Git Advanced: cherry-pick, rebase, bisect

Продвинутые техники работы с Git для профессионалов

Git — не только commit и push. Cherry-pick, interactive rebase, bisect, reflog — инструменты которые отличают junior от senior. Разберем продвинутые техники работы с Git. Git Rebase: переписываем историю Merge vs Rebase: # Merge создает merge commit git checkout feature git merge main # Rebase переносит commits поверх main git checkout feature git rebase main Когда использовать: Rebase — для локальных веток, чистая история Merge — для публичных веток, сохраняет контекст Interactive Rebase git rebase -i HEAD~5 # Последние 5 commits # Откроется редактор: pick 1a2b3c4 Add feature A pick 5d6e7f8 Fix typo pick 9g0h1i2 Add feature B pick 3j4k5l6 WIP pick 7m8n9o0 Complete feature B Команды в interactive rebase: pick — использовать commit reword — изменить commit message edit — остановиться для правки squash — объединить с предыдущим fixup — как squash, но без message drop — удалить commit Squashing commits: pick 1a2b3c4 Add feature A fixup 5d6e7f8 Fix typo pick 9g0h1i2 Add feature B squash 3j4k5l6 WIP squash 7m8n9o0 Complete feature B # Результат: 2 чистых commits вместо 5 Git Cherry-pick Применить конкретный commit из одной ветки в другую: # Применить один commit git cherry-pick abc123 # Применить несколько git cherry-pick abc123 def456 ghi789 # Применить диапазон git cherry-pick abc123..def456 # Cherry-pick без commit git cherry-pick --no-commit abc123 Use case: # Hotfix из develop в main git checkout main git cherry-pick hotfix-commit-hash git push Git Bisect: поиск проблемного commit # Начать bisect git bisect start # Указать плохую версию (current) git bisect bad # Указать хорошую версию git bisect good abc123 # Git переключится на средний commit # Тестируем... # Если баг есть git bisect bad # Если бага нет git bisect good # Повторяем пока не найдем виновника # Завершить bisect git bisect reset Автоматический bisect: git bisect start HEAD abc123 git bisect run npm test # Git автоматически найдет проблемный commit Git Reflog: спасение от ошибок Reflog — журнал всех изменений HEAD: git reflog # Вывод: abc123 HEAD@{0}: commit: Add feature def456 HEAD@{1}: rebase: checkout main ghi789 HEAD@{2}: commit: WIP jkl012 HEAD@{3}: commit: Initial Восстановление после reset: # Случайно сделали hard reset git reset --hard HEAD~3 # О нет! Потеряли commits! # Смотрим reflog git reflog # Находим нужный commit git reset --hard HEAD@{1} # Все вернулось! Восстановление удаленной ветки: git branch -D feature-branch # Упс! git reflog git checkout -b feature-branch abc123 Git Stash: временное сохранение # Сохранить изменения git stash # Сохранить с сообщением git stash save "WIP: feature in progress" # Сохранить включая untracked files git stash -u # Список stash git stash list # Применить последний stash git stash apply # Применить и удалить git stash pop # Применить конкретный stash git stash apply stash@{2} # Создать ветку из stash git stash branch feature-branch # Удалить stash git stash drop stash@{0} # Очистить все git stash clear Git Worktree: несколько рабочих копий # Создать новый worktree git worktree add ../feature-branch feature-branch # Теперь можно работать в двух ветках одновременно: cd ../feature-branch # Работа в feature cd ../main-repo # Работа в main # Список worktrees git worktree list # Удалить worktree git worktree remove ../feature-branch Git Hooks: автоматизация Pre-commit hook: # .git/hooks/pre-commit #!/bin/sh # Запустить линтер npm run lint if [ $? -ne 0 ]; then echo "Lint failed. Commit rejected." exit 1 fi # Запустить тесты npm test if [ $? -ne 0 ]; then echo "Tests failed. Commit rejected." exit 1 fi Commit-msg hook (валидация сообщений): # .git/hooks/commit-msg #!/bin/sh commit_msg=$(cat "$1") # Требуем формат: "type: message" if ! echo "$commit_msg" | grep -qE "^(feat|fix|docs|style|refactor|test|chore): "; then echo "Error: Commit message must start with type: feat, fix, docs, etc." echo "Example: feat: add user authentication" exit 1 fi Husky для управления hooks: npm install --save-dev husky npx husky init # .husky/pre-commit npm run lint npm test # .husky/commit-msg npx commitlint --edit "$1" Git Submodules vs Subtrees Submodules: # Добавить submodule git submodule add https://github.com/user/repo libs/repo # Клонировать с submodules git clone --recursive https://github.com/user/main-repo # Обновить submodules git submodule update --remote # Удалить submodule git submodule deinit libs/repo git rm libs/repo rm -rf .git/modules/libs/repo Subtrees (альтернатива): # Добавить subtree git subtree add --prefix=libs/repo https://github.com/user/repo main --squash # Обновить subtree git subtree pull --prefix=libs/repo https://github.com/user/repo main --squash # Push изменений обратно git subtree push --prefix=libs/repo https://github.com/user/repo main Git Blame и Log: анализ истории # Кто изменил каждую строку git blame file.js # Blame с игнорированием whitespace git blame -w file.js # Blame для диапазона строк git blame -L 10,20 file.js # История конкретного файла git log --follow file.js # История с изменениями git log -p file.js # Кто изменил функцию git log -L :functionName:file.js # Найти кто удалил строку git log -S "deleted text" --source --all Git Clean: очистка рабочей директории # Показать что будет удалено git clean -n # Удалить untracked files git clean -f # Удалить untracked files и директории git clean -fd # Включая ignored files git clean -fdx Git Filter-branch: масштабные изменения # Удалить файл из всей истории git filter-branch --tree-filter "rm -f passwords.txt" HEAD # Изменить автора всех commits git filter-branch --env-filter ' if [ "$GIT_COMMITTER_EMAIL" = "old@email.com" ]; then export GIT_COMMITTER_EMAIL="new@email.com" export GIT_AUTHOR_EMAIL="new@email.com" fi ' HEAD BFG Repo-Cleaner (быстрее): # Удалить большие файлы bfg --strip-blobs-bigger-than 100M # Удалить конкретный файл bfg --delete-files passwords.txt git reflog expire --expire=now --all git gc --prune=now --aggressive Git Strategies Git Flow: # Feature branches git checkout -b feature/new-feature develop # Work... git checkout develop git merge --no-ff feature/new-feature # Release branches git checkout -b release/1.0 develop # Fixes... git checkout main git merge --no-ff release/1.0 git tag -a v1.0 # Hotfix git checkout -b hotfix/critical-bug main # Fix... git checkout main git merge --no-ff hotfix/critical-bug git checkout develop git merge --no-ff hotfix/critical-bug Trunk-based Development: # Короткоживущие ветки git checkout -b feature # Work 1-2 days max git checkout main git merge feature git push Advanced Git Config # Aliases git config --global alias.co checkout git config --global alias.br branch git config --global alias.ci commit git config --global alias.st status git config --global alias.lg "log --graph --oneline --all" # Автоматический rebase при pull git config --global pull.rebase true # Default branch name git config --global init.defaultBranch main # Цветной вывод git config --global color.ui auto # Автоматическое исправление опечаток git config --global help.autocorrect 1 Git Performance Tips # Shallow clone (быстрее для CI) git clone --depth 1 https://github.com/user/repo # Partial clone (меньше размер) git clone --filter=blob:none https://github.com/user/repo # Sparse checkout (только нужные папки) git sparse-checkout init git sparse-checkout set src/ # GC для оптимизации git gc --aggressive --prune=now Troubleshooting Отменить последний commit: # Сохранить изменения git reset --soft HEAD~1 # Удалить изменения git reset --hard HEAD~1 Отменить merge: git merge --abort # Во время конфликта git reset --hard HEAD~1 # После merge Изменить последний commit: git commit --amend git commit --amend --no-edit # Без изменения message Security: подписывание commits # Настроить GPG key gpg --gen-key gpg --list-secret-keys --keyid-format LONG git config --global user.signingkey YOUR_KEY_ID git config --global commit.gpgsign true # Подписать commit git commit -S -m "Signed commit" # Проверить подписи git log --show-signature Заключение: Продвинутые техники Git — инструменты профессионала. Rebase для чистой истории, cherry-pick для выборочного применения изменений, bisect для debugging, reflog для спасения от ошибок. Используйте hooks для автоматизации, worktree для параллельной работы. Помните: с большой силой приходит большая ответственность — будьте осторожны с переписыванием публичной истории.