Кладовочка

О разном, чтобы было под рукой онлайн

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

Полезные ресурсы


Что дальше

Связанные шпаргалки: Git Basics, Docker, Linux Commands, Kubernetes