Git: продвинутая шпаргалка — rebase, stash, bisect, cherry-pick, hooks, reflog, скорая помощь
Git — не просто commit/push/pull. Продвинутые команды экономят часы при расследовании багов и восстановлении потерянной работы.
Rebase: переписывание истории
# Интерактивный rebase (последние 3 коммита)
git rebase -i HEAD~3
# pick → оставить, reword → сменить сообщение, edit → правка
# squash → склеить с предыдущим, fixup → склеить без сообщения, drop → удалить
# Склеить все коммиты ветки в один
git rebase -i main # первый оставить pick, остальные → fixup
# Autosquash — коммиты "fixup! ..." склеиваются автоматически
git rebase -i --autosquash origin/main
# Rebase ветки на main
git fetch origin && git rebase origin/main
# Перенести ветку на другую основу
git rebase --onto main dev feature # feature коммиты поверх main, исключая dev
Конфликты при rebase
git status # на каком коммите остановились
# ... разрешить конфликты ...
git add . && git rebase --continue
git rebase --skip # пропустить проблемный коммит
git rebase --abort # откатить всё
# 🔥 rerere — запоминает разрешения и применяет автоматически
git config --global rerere.enabled true
Cherry-pick / Bisect / Stash
# Cherry-pick
git cherry-pick a1b2c3d # конкретный коммит
git cherry-pick start..end # диапазон
git cherry-pick --no-commit a1b2c3d # без авто-коммита
git cherry-pick --abort # откатить
# Bisect — бинарный поиск бага
git bisect start && git bisect bad && git bisect good v1.0
git bisect run npm test # автоматический!
git bisect reset # завершить
# Stash
git stash push -m "WIP" # сохранить с сообщением
git stash push -u # + untracked
git stash list # список
git stash apply stash@{0} # применить, stash остаётся
git stash branch rescued stash@{0} # создать ветку из stash (безопасно!)
# ⚠️ stash pop удаляет stash даже при конфликте! Всегда: apply → проверить → drop
Reflog: восстановление потерянного
git reflog # все перемещения HEAD за ~90 дней
# a1b2c3d HEAD@{0}: commit: feat
# e4f5g6h HEAD@{1}: reset: moving to HEAD~1
# Восстановить «потерянный» коммит
git checkout -b recovered a1b2c3d
# Восстановить удалённую ветку
git branch rescued a1b2c3d
# Восстановить коммит ПОСЛЕ amend
git reflog → найти SHA до amend → git checkout -b original SHA
# Если reflog не помог
git fsck --lost-found
Reset: три режима
git reset --soft HEAD~1 # отменить commit, staged сохранён
git reset --mixed HEAD~1 # отменить commit, unstaged (по умолчанию)
git reset --hard HEAD~1 # ⚠️ ПОЛНОСТЬЮ удалить изменения!
git restore file.txt # откатить незакоммиченные изменения
git restore --staged file.txt # убрать из staged
git revert a1b2c3d # безопасный откат — новый коммит
Force-push и алиасы
# ⚠️ --force только на своих ветках!
git push --force-with-lease # отклонит, если remote ушёл вперёд
git push --force-with-lease --force-if-includes
# .gitconfig — полезные алиасы
git config --global alias.st "status -sb"
git config --global alias.lg "log --oneline --graph --all --decorate"
git config --global alias.unstage "restore --staged"
git config --global alias.undo "reset --soft HEAD~1"
git config --global alias.amend "commit --amend --no-edit"
git config --global alias.last "log -1 HEAD"
git config --global alias.rh "reset --hard"
git config --global alias.cleanup "!git fetch origin && git checkout main && git reset --hard origin/main"
Конвенции коммитов (Conventional Commits)
Коммиты этого проекта используют type(scope): message:
feat(txtly): add 5 standalone text tools
fix(txtly): add L10N keys for new text tools
docs(kb-txtly): update articles
seo(psychology): optimize 4 articles for LF queries
chore: add TASK.md for cheat sheets improvement
| Type | Назначение | Пример |
|---|---|---|
feat |
Новая фича | feat(auth): add JWT authentication |
fix |
Исправление бага | fix(api): handle null user in profile |
docs |
Документация | docs(readme): update install steps |
chore |
Обслуживание | chore: update dependencies |
refactor |
Рефакторинг | refactor(db): extract query builder |
style |
Форматирование | style: apply prettier |
test |
Тесты | test(auth): add login edge cases |
perf |
Производительность | perf(list): add virtual scrolling |
ci |
CI/CD | ci: add GitHub Actions deploy |
Split commit: разбить коммит на части
git rebase -i HEAD~3 # пометить целевой коммит как edit
# Git остановится на нём
git reset HEAD~1 # откатить commit, файлы останутся
git add first-part.js && git commit -m "part 1"
git add second-part.js && git commit -m "part 2"
git rebase --continue
Hooks
# .git/hooks/pre-commit — линтеры
#!/bin/sh
files=$(git diff --cached --name-only --diff-filter=ACM | grep '\.js$')
if [ -n "$files" ]; then
npx eslint $files || exit 1
fi
# .git/hooks/commit-msg — проверка Conventional Commits
#!/bin/sh
msg=$(cat $1)
echo "$msg" | grep -qE '^(feat|fix|docs|chore|refactor|style|test|perf|ci)(\(.+\))?: .+' || {
echo "Формат: type(scope): message"; exit 1
}
.gitignore: реальные паттерны
node_modules/
dist/
.turbo/
.archlet/
.cache/
*.log
# Секреты — исключаем всё, разрешаем example
.env
.env.*
!.env.example
# IDE
.DS_Store
Thumbs.db
*.swp
*.swo
*~
# Артефакты
coverage/
*.tsbuildinfo
.vite/
*.db
Worktree / Submodules / Log
# Worktree — несколько веток одновременно
git worktree add ../hotfix hotfix
git worktree add -b feature ../feature main
git worktree list && git worktree remove ../hotfix
# Submodules
git clone --recurse-submodules url
git submodule update --init --recursive
git submodule update --remote libs/mylib
git submodule deinit libs/mylib && git rm libs/mylib
# Продвинутый log
git log --oneline --graph --all --decorate # граф
git log --author="Иван" --since="2026-07-01" # фильтр
git log -S "TODO" # поиск по содержимому
git log -G "pattern" # поиск изменений
git blame -L 10,20 file.ts # кто менял строки
git log main..feature # что в feature, чего нет в main
git shortlog -sn # кто сколько коммитов
# Diff tricks
git diff --word-diff # пословное сравнение
git diff --name-only HEAD~1 # только имена файлов
git diff --diff-filter=D --summary # удалённые файлы
Скорая помощь: 20 аварийных ситуаций
| # | Ситуация | Решение |
|---|---|---|
| 1 | Закоммитил НЕ в ту ветку | git reset --soft HEAD~1 && git stash && git checkout feature && git stash pop && git commit |
| 2 | Забыл добавить файл в последний коммит | git add forgotten.js && git commit --amend --no-edit |
| 3 | Опечатка в сообщении коммита | git commit --amend -m "Правильное сообщение" |
| 4 | Хочу отменить amend (вернуть старый коммит) | git reflog → найти SHA → git reset --soft SHA |
| 5 | Закоммитил в main вместо feature | git branch feature && git reset --hard HEAD~1 && git checkout feature |
| 6 | Push с amend уже сделан | git push --force-with-lease (только свои ветки!) |
| 7 | Rebase завис, конфликт, не знаю что делать | git rebase --abort — вернёт всё как было |
| 8 | Случайный git reset --hard, потерял работу |
git reflog → найти SHA до reset → git checkout -b rescued SHA |
| 9 | Stash pop с конфликтом, stash удалён | git fsck --lost-found | grep commit — искать висячие коммиты |
| 10 | Нужный коммит из чужой ветки | git cherry-pick SHA |
| 11 | Merge не туда, надо откатить | git reset --hard HEAD~1 (если merge последний) или git revert -m 1 SHA |
| 12 | Хочу убрать файл из коммита, оставить на диске | git reset --soft HEAD~1 && git restore --staged file.txt && git commit |
| 13 | Кто и когда сломал тест? | git bisect start && git bisect bad && git bisect good v1.0 && git bisect run npm test |
| 14 | Конфликт при merge/rebase повторяется | git config --global rerere.enabled true |
| 15 | Push отклонён — remote ушёл вперёд | git fetch && git rebase origin/main && git push |
| 16 | Удалил ветку на GitHub, хочу восстановить | git reflog → найти SHA → git branch rescued SHA |
| 17 | Хочу откатить один файл к версии из другого коммита | git checkout SHA -- path/to/file |
| 18 | Хочу отменить последний push (никто не пуллил) | git reset HEAD~1 && git push --force-with-lease |
| 19 | Нужен пустой коммит (триггер CI) | git commit --allow-empty -m "chore: trigger CI rebuild" |
| 20 | Не могу вспомнить что делал вчера | git reflog --since=yesterday |
Частые проблемы и их решения
| Проблема | ❌ Неправильно | ✅ Правильно |
|---|---|---|
| Rebase завис в detached HEAD | git checkout main |
git rebase --continue / --abort |
| Потерял коммиты после reset --hard | Паника | git reflog → git checkout -b recovered SHA |
| Stash pop удалил stash при конфликте | Потерял работу | Всегда git stash apply, потом drop |
| Force-push перезаписал чужие коммиты | git push --force |
git push --force-with-lease |
| Конфликт повторяется при rebase | Ручное разрешение каждый раз | git config --global rerere.enabled true |
| Push отклонён после amend | git push --force |
git push --force-with-lease |
| Удалил ветку, коммиты пропали | Считать потерянным | git reflog → SHA → git branch recovered SHA |
Полезные ресурсы
- Pro Git Book — полная книга на русском
- Oh Shit, Git!?! — аварийные ситуации (EN)
- Git Flight Rules — что делать если...
- Learn Git Branching — интерактивный тренажёр
Что дальше
- Базовая шпаргалка по Git — commit, branch, merge
- Шпаргалка по Docker — контейнеризация
- Шпаргалка по Linux — командная строка
- Шпаргалка по Kubernetes — оркестрация
Связанные шпаргалки: Git Basics, Docker, Linux Commands, Kubernetes