Как переместить последние коммиты из ветки master в новую ветку и сбросить master в предыдущее состояние? Например, преобразовать следующую историю Git:
master A - B - C - D - E
В такую:
newbranch C - D - E
/
master A - B
Какие Git-команды нужны для выполнения этого рабочего процесса?
Чтобы переместить последние коммиты из ветки master в новую ветку и сбросить master в предыдущее состояние, вам нужно создать новую ветку в текущем HEAD, а затем сбросить ветку master до нужного коммита. Базовый рабочий процесс включает использование git branch для создания новой ветки и git reset --hard или git reset --keep для сброса master.
Содержание
- Понимание рабочего процесса
- Метод 1: Использование Git Branch и Reset
- Метод 2: Использование Git Cherry-Pick
- Метод 3: Использование Git Rebase
- Пошаговый пример
- Важные замечания
- Работа с удаленными репозиториями
- Заключение
Понимание рабочего процесса
Рабочий процесс Git, который вы хотите выполнить, включает две основные операции:
- Создание новой ветки, которая будет содержать последние коммиты, которые вы хотите переместить
- Сброс ветки master в предыдущее состояние перед этими коммитами
Как объясняется в руководстве 30 seconds of code, этот процесс особенно полезен, когда вы понимаете, что определенные коммиты должны были быть сделаны на отдельной ветке, а не на текущей.
Основные команды, которые вам понадобятся:
git branch <имя-ветки>- создает новую ветку в текущем HEADgit reset --hard HEAD~<n>- перемещает указатель ветки назад на n коммитов и отбрасывает измененияgit reset --keep HEAD~<n>- перемещает указатель ветки назад, но сохраняет изменения в рабочем каталоге
Метод 1: Использование Git Branch и Reset
Это наиболее прямой подход, рекомендуемый для большинства сценариев.
Пошаговый процесс:
-
Создайте новую ветку в текущем HEAD:
bashgit checkout master git branch feature-branch
-
Сбросьте master в предыдущее состояние. Если вы хотите оставить последние 3 коммита (C, D, E) на новой ветке и сбросить master до B:
bashgit checkout master git reset --hard HEAD~2 # Это перемещает master назад на 2 коммита (до коммита B)
Как объясняется в руководстве GeeksforGeeks, вы можете использовать команду git reset для перемещения коммитов в новую ветку. Опция --hard сбросит как указатель ветки, так и рабочий каталог.
Альтернатива с --keep:
Если вы хотите сбросить указатель ветки, но сохранить изменения в рабочем каталоге:
git reset --keep HEAD~2
Метод 2: Использование Git Cherry-Pick
Этот метод полезен, когда вы хотите получить больше контроля над тем, какие коммиты перемещать.
Пошаговый процесс:
-
Создайте и переключитесь на новую ветку:
bashgit checkout -b feature-branch
-
Выберите конкретные коммиты, которые вы хотите переместить:
bashgit cherry-pick C..E # Перемещает коммиты C, D и E в новую ветку -
Сбросьте master в предыдущее состояние:
bashgit checkout master git reset --hard C~1 # Сбрасывает master до коммита B
Как упоминается в руководстве Graphite, cherry-pick может быть полезен, когда вам нужен более детальный контроль над перемещением коммитов между ветками.
Метод 3: Использование Git Rebase
Этот подход полезен для перемещения серии коммитов в более автоматизированном режиме.
Пошаговый процесс:
-
Создайте новую ветку:
bashgit checkout -b feature-branch
-
Перебазируйте на целевой коммит:
bashgit rebase --onto B C..E
-
Сбросьте master:
bashgit checkout master git reset --hard C~1 # Сбрасывает master до коммита B
В руководстве Graphite отмечается, что rebase может быть полезен, если вы хотите переместить серию коммитов из одной ветки в другую в более автоматизированном режиме.
Пошаговый пример
Рассмотрим полный рабочий процесс на примере из вашего вопроса:
Начальное состояние:
master A - B - C - D - E
Конечное желаемое состояние:
newbranch C - D - E
/
master A - B
Полные команды:
-
Создайте новую ветку в текущем HEAD (E):
bashgit checkout master git branch feature-branch
-
Сбросьте master до коммита B (на 2 коммита назад):
bashgit checkout master git reset --hard HEAD~2
-
Переключитесь на новую ветку, чтобы продолжить работу:
bashgit checkout feature-branch
Как объясняется в ответе на Stack Overflow, если вы хотите переместить коммиты в существующую ветку, вам нужно слить изменения в существующую ветку перед выполнением git reset --hard HEAD~3. Однако в нашем случае мы сначала создаем новую ветку.
Важные замечания
Безопасность прежде всего:
- Сделайте резервную копию работы: Перед выполнением любых операций сброса убедитесь, что у вас нет неотправленных изменений, которые могут понадобиться
- Проверьте историю коммитов: Используйте
git log, чтобы убедиться, что вы сбрасываете до правильного коммита - Рассмотрите использование --keep: Если вы не уверены в потере изменений, используйте
git reset --keepвместо--hard
Распространенные ошибки:
- Не сбрасывайте общие ветки: Никогда не сбрасывайте ветку, над которой работают другие члены команды
- Осторожно используйте принудительную отправку: После сброса удаленной ветки вам понадобится принудительная отправка
- Проверяйте перед отправкой: Дважды проверьте, что вы на правильной ветке, прежде чем делать новые коммиты
Как предупреждает руководство Sarunw, чтобы удалить неправильные коммиты из ветки develop, мы используем git reset, поэтому будьте очень осторожны с тем, что вы сбрасываете.
Работа с удаленными репозиториями
Если вы работаете с удаленным репозиторием, вам нужно будет обновить удаленную ветку после сброса:
# После сброса master локально
git push --force origin master
Как упоминается в руководстве Graphite, если вы работаете с удаленным репозиторием и нужно обновить ветки, вам может понадобиться принудительно отправить изменения.
Предупреждение: Принудительная отправка перезапишет удаленную историю, поэтому убедитесь, что все члены команды осведомлены об этом изменении и получили последние изменения перед тем, как вы будете принудительно отправлять.
Заключение
Перемещение последних коммитов из master в новую ветку и сброс master - это распространенный рабочий процесс Git, который можно выполнить несколькими способами:
- Базовый подход: Используйте
git branchдля создания новой ветки иgit reset --hard HEAD~nдля сброса master назад - Метод cherry-pick: Используйте
git cherry-pickдля более детального контроля над тем, какие коммиты перемещать - Метод rebase: Используйте
git rebase --ontoдля автоматизированного перемещения серии коммитов
Основные команды:
git branch <имя-ветки>- создает новую веткуgit reset --hard HEAD~<n>- сбрасывает ветку назад на n коммитовgit checkout <имя-ветки>- переключается на новую ветку
Всегда помните:
- Проверяйте историю коммитов перед сбросом
- Будьте осторожны с сбросами
--hard, так как они отбрасывают изменения - Учитывайте командную работу при работе с общими репозиториями
- Осторожно используйте принудительную отправку при обновлении удаленных веток
Этот рабочий процесс особенно полезен, когда вы понимаете, что определенные коммиты должны были быть сделаны на отдельной ветке, а не на текущей, что помогает поддерживать чистую и организованную историю Git.
Источники
- Move the most recent commit(s) to a new branch with Git - Stack Overflow
- Move Git commits from master to a new branch - 30 seconds of code
- How to Move the Most Recent Commit(s) to a New Branch With Git? - GeeksforGeeks
- Moving commits between branches · GitHub
- Move the most recent commits to a new branch with git | Sarunw
- How to move a commit to another branch in Git - Graphite
- Git - git-reset Documentation
- How to Make the Development Branch Identical to the Master Branch | Delft Stack