Как использовать продвинутые команды Git для сложных рабочих процессов

Bbot_tutorials25.05.2026
gitпродвинутые командырабочие процессыrebasecherry-pickstash

Зачем: реальная задача, которую мы решим

Представьте: вы работаете в команде над крупным проектом. Ветка main - стабильный релиз. Вы начали фичу, но в процессе поняли, что часть работы нужно откатить, а часть - перенести в другую ветку. Или вы случайно закоммитили в main черновой код. Или нужно объединить несколько коммитов в один, чтобы история была чистой. Стандартные add, commit, push здесь не помогут. Нужны продвинутые команды Git.

В этом туториале мы разберём 4 реальных сценария и покажем, как их решить с помощью git rebase, git cherry-pick, git stash и git reset. Каждый пример - рабочий код с пошаговым объяснением.

1. Как отменить коммит, но сохранить изменения: git reset

Зачем: Вы сделали коммит, но поняли, что код сырой. Удалять его совсем не нужно - просто уберите из истории, оставив изменения в рабочей директории.

Как: Используйте git reset --soft HEAD~1.


# Исходная ситуация: последний коммит "WIP: черновик"
git log --oneline
# abc1234 (HEAD -> main) WIP: черновик
# def5678 Фича: авторизация

# Отменяем последний коммит, но оставляем изменения в staging
git reset --soft HEAD~1

# Проверяем: коммита нет, но файлы в индексе
git status
# Changes to be committed:
#   modified:   app.js

# Теперь вы можете доработать код и сделать новый коммит
git commit -m "Фича: авторизация v2"

Пример: Вы случайно закоммитили console.log в продакшн-ветку. Вместо git revert (который создаёт новый коммит отмены), используйте git reset --soft - история останется чистой.

Итог: git reset --soft - ваш друг, когда нужно "переделать" последний коммит без потери данных. Для полного удаления изменений используйте --hard, но осторожно: это безвозвратно.

2. Как перенести один коммит из другой ветки: git cherry-pick

Зачем: В ветке develop уже есть исправление бага, но оно нужно и в hotfix. Сливать всю ветку - слишком жирно. Нужен только один коммит.

Как: git cherry-pick <хэш_коммита>.


# Находим хэш нужного коммита в ветке develop
git checkout develop
git log --oneline
# a1b2c3d Исправление: баг с таймером
# e4f5g6h Рефакторинг компонента

# Переключаемся в hotfix
git checkout hotfix

# Переносим только коммит с исправлением
git cherry-pick a1b2c3d

# Если возник конфликт - Git приостановит операцию
# Разрешаем конфликт вручную, затем:
git add .
git cherry-pick --continue

# Проверяем историю
git log --oneline -3
# a1b2c3d (HEAD -> hotfix) Исправление: баг с таймером
# (остальные коммиты hotfix)

Пример: В main нашли критический баг. Вы уже исправили его в develop, но мержить develop в main не хотите - там много незаконченных фич. cherry-pick решает проблему за секунду.

Итог: git cherry-pick - точечное копирование коммита. Идеально для hotfix-ов и переноса отдельных изменений между ветками.

3. Как спрятать незавершённые изменения: git stash

Зачем: Вы работаете над фичей, но срочно нужно переключиться на другую задачу. Коммитить незаконченный код нельзя - он сломает сборку. Просто оставить изменения в рабочей директории - они "прилипнут" к другой ветке.

Как: git stash сохраняет изменения в стек и очищает рабочую директорию.


# Вы начали фичу, но нужно срочно переключиться
git status
# Changes not staged for commit:
#   modified:   app.js

# Прячем изменения
git stash push -m "WIP: фича логирования"

# Рабочая директория чиста - можно переключать ветки
git checkout main
# делаем срочный фикс
git commit -m "Hotfix: исправление цены"
git push

# Возвращаемся к фиче
git checkout feature/logging
git stash pop  # достаёт последний stash и удаляет его из стека

# Или можно применить без удаления
git stash apply stash@{0}

Пример: Вы правите баг, а коллега просит срочно проверить его код в другой ветке. git stash сохранит ваши наработки, не требуя коммита. Можно даже сделать несколько stash - они хранятся в стеке.

Итог: git stash - временное хранилище для незавершённой работы. Не забывайте git stash list для просмотра стека и git stash drop для удаления конкретного элемента.

4. Как переписать историю ветки: git rebase - интерактивный режим

Зачем: У вас 10 мелких коммитов в ветке feature. Вмержить их в main - значит захламить историю. Лучше объединить их в 2-3 осмысленных коммита.

Как: git rebase -i HEAD~N, где N - количество последних коммитов для переписывания.


# Исходная история (ветка feature)
git log --oneline
# 1a2b3c4 fix: опечатка
# 5d6e7f8 fix: ещё одна опечатка
# 9g0h1i2 feat: добавлена кнопка
# 3j4k5l6 feat: базовая верстка

# Запускаем интерактивный rebase для последних 4 коммитов
git rebase -i HEAD~4

# Откроется редактор, где нужно изменить порядок и команды:
# pick 3j4k5l6 feat: базовая верстка
# pick 9g0h1i2 feat: добавлена кнопка
# fixup 5d6e7f8 fix: ещё одна опечатка    # объединить с предыдущим, отбросив сообщение
# fixup 1a2b3c4 fix: опечатка             # объединить с предыдущим

# Сохраняем и выходим - Git перепишет историю
# Результат:
git log --oneline
# aaa1111 feat: базовая верстка (объединил 4 коммита в 1)

Пример: Перед мержем feature-ветки в main вы делаете git rebase -i, чтобы превратить кучу "WIP" и "fix typo" в один чистый коммит. Это стандарт в командах, где ценят историю.

Важно: Никогда не делайте rebase для коммитов, которые уже отправлены в общий репозиторий (например, в main). Это сломает историю у коллег. Rebuse только для локальных веток.

Итог: git rebase -i - мощный инструмент для причёсывания истории. Используйте pick, fixup, squash для объединения коммитов и reword для переименования.

5. Как безопасно объединить ветки: разница merge и rebase

Зачем: Вы работаете в feature-ветке, а main ушёл вперёд. Нужно обновить свою ветку, чтобы избежать конфликтов при мерже. Два подхода: merge и rebase.

Как: Выберите в зависимости от команды.


# Подход 1: Merge (сохраняет историю ветвлений)
git checkout feature
git merge main
# Git создаёт merge-commit, история показывает, что feature ответвилась от старого main
# Минус: много merge-коммитов захламляют историю

# Подход 2: Rebase (линейная история)
git checkout feature
git rebase main
# Git переписывает коммиты feature так, будто они сделаны на основе нового main
# Плюс: чистая линейная история
# Минус: если конфликты - придётся разрешать их для каждого коммита по-отдельности

Пример: В команде с code review чаще используют rebase - история читается как книга. В больших open-source проектах предпочитают merge, потому что он не переписывает историю.

Итог: Для личных веток - rebase. Для общих - merge (или rebase, но только если никто кроме вас не работает в этой ветке).

Итог: когда что использовать

Эти команды решают 90% проблем, которые возникают при работе с Git в команде. Практикуйтесь на тестовых репозиториях - и вы перестанете бояться конфликтов и "испорченной" истории.

0
Просмотры: 8Комментарии: 0

Комментарии (0)

Комментариев пока нет