Как я могу переместить набор коммитов из мастера в отдельную ветвь?
У меня есть ряд коммитов (20+), которые относятся к определенной функции, которую я пытаюсь удалить из нашей главной ветки и в отдельную ветвь.
У меня есть тег (rel_2009_07_18
) в коммите, который представляет нашу последнюю стабильную версию, поэтому когда на master, git log rel_2009_07_18
.. HEAD получает мне набор коммитов, которые я хочу переместить на отдельный ветка. Есть также некоторые коммиты в этом наборе, которые должны остаться, но я мог бы просто вишнево-подобранных, поскольку их немного.
Я просмотрел ветвь git filter-branch, но опция commit упоминает о внесении изменений, но удаление commit - определенно не хочет этого. Я также посмотрел на git rebase, но это также упоминает повторное применение коммитов к восходящей ветке.
Есть ли хороший способ перемещения этих коммитов в отдельную ветвь?
Я не уверен, что это жизнеспособный вариант и последствия в распределенной, хотя и небольшой (3 разработчиках) среде. Но могу ли я выполнить следующий небольшой сдвиг...
- Локально переименуйте главную ветвь в master_plus_feature (или аналогичную...)
- Оформить заказ из тега `rel_2009_07_18`
- Создайте новый мастер ветвей с этой точки.
- Удалить удаленные ветки и повторно нажать из локального
Мысли и предложения? Спасибо!
Ответы
Ответ 1
Вы пишете, что хотите удалить. Это может вызвать проблемы, если была опубликована ветвь "master" (ну, фиксируется после публикации rel_2009_07_18
), а кто-то основывает свою работу на вашем "хозяине". Но, возможно, это не проблема в вашем случае.
Оба решения ниже предполагают, что у вас нет несанкционированных изменений
Если вы можете перемотать ветку "master" :
$ git checkout master
$ git branch separate_branch
$ git reset --hard rel_2009_07_18
Теперь "master" находится в теге rel_2009_07_18
, а "separate_branch" находится там, где был "master" . Конечный результат точно такой же, как в наборе шагов, которые вы предложили (переименуйте "master" в "separate_branch", воссоздайте 'master' в rel_2009_07_18
), единственное различие в reflogs.
Если вы не можете перемотать ветвь "master"
$ git checkout master
$ git branch separate_branch
$ git checkout rel_2009_07_18 -- .
$ git clean -df
$ git commit -m 'Reverted to state at rel_2009_07_18'
Обратите внимание, что это решение не проверено! YMMV.
Ответ 2
Для меня самый простой вариант - использовать git-cherry-pick
.
В основном вам нужно переключиться на ветку, на которую вы хотите совершить фиксацию, а затем, используя журнал исходной ветки (git log master
), вы найдете SHA-1 каждой фиксации, которую хотите, и вишни - выберите ее в текущую ветку.
Как только это будет сделано, вы сможете вернуться к мастеру и отменить все эти нежелательные коммиты, используя git-reset
и hey presto, теперь у вас есть ветка с вашими новыми коммитами и чистая ветвь.
Ответ 3
В случае непрерывности истории создайте новую ветку, затем найдите ветку, в которой вы хотите включить оригинал, и обновите HEAD:
git checkout -b new_branch
git log
Журнал git предназначен для определения места, где должен был быть первоначальный раскол.
echo {commit id} >.git/refs/heads/original_branch
Если вы проверите оригинал_branch в этот момент, он укажет на фиксацию, где новая ветка должна быть разделена.
Я лично использую это для старых репозиториев, что я не использовал рабочий процесс git -flow, чтобы разделить ветки разработки и мастера, и до сих пор у меня не было никаких проблем.
Если история не соприкасается, то тот же самый метод работает, за исключением того, что нужно найти последнее коммит до того, как ветка должна была произойти, а затем использовать вишневый выбор для применения коммитов, которые нужны в исходной ветке.