Краткий ответ
Вы можете применить уже существующий коммит к другой ветви, используя команду cherry-pick
, а затем протолкнуть обе ветви, используя git push origin branchA branchB
.
Почему использование фиксации в двух ветвях может быть полезным
Предположим, у вас есть хранилище с такой структурой:
A--B--C--D ← master ← HEAD
\--E ← v1-release
После некоторой разработки (коммитов A
, B
, C
) проект был выпущен и была создана ветка v1-release
(так что v1 можно поддерживать с исправлениями ошибок, а следующую версию можно разработать в master
) , Коммит E
использовался для указания информации о версии (добавленные заметки о выпуске и т. Д.). В коммите D
появилась новая функция, которая запланирована на следующую версию и не должна появляться в v1-release
.
Теперь, если ошибка обнаружена в v1-release
, она должна быть исправлена в обеих ветках, чтобы пользователи могли продолжать использовать v1, и она не появится в следующей версии.
После исправления ошибки в master
хранилище должно выглядеть так:
A--B--C--D--F ← master ← HEAD
\--E ← v1-release
Теперь коммит F
с исправлением должен применяться к v1-release
ветке.
Как на самом деле это сделать
Коммиты не могут быть точно скопированы (так как фиксация - это сохраненное состояние каталога), но вы можете применить изменения, сделанные в фиксации, к другой фиксации.
Команда
cherry-pick
делает именно это. Он применяет изменения, сделанные указанным коммитом к текущей ветви, создавая новый коммит:
git checkout v1-release
git cherry-pick F
После этого хранилище должно выглядеть так:
A--B--C--D--F ← master
\--E--G ← v1-release ← HEAD
Commit G
вносит те же изменения, что и F
.
Возможно, вам придется разрешать конфликты (точно так же, как после слияния).
Сообщение об ошибке
Предыдущая вишня была пуста ...
означает, что изменения, сделанные вишневым коммитом, уже присутствуют в текущей ветке. Вы, вероятно, забыли оформить правильную ветку.
В случае ошибок или конфликтов cherry-pick можно отменить с помощью git cherry-pick --abort
.
Наконец, вы можете вернуться к ветке master
и отправить обе ветки в удаленный репозиторий:
git checkout master
git push origin master v1-release
Окончательная структура хранилища:
A--B--C--D--F ← master ← HEAD
\--E--G ← v1-release