Ваш вопрос говорит о том, что данные коммиты принадлежат в feature-1
, а не в feature-2
ветке . Принятый ответ этого не делает.
cherry-pick
- это хороший способ создать новый коммит в одной ветви, который дублирует изменения, сделанные коммитом в другой ветви; но это не меняет другую ветвь.
Так, например, если вы начали с
x <--(master)
|\
| A1 -- A2 <--(feature_1)
\
B1 -- A3 -- B2 <--(feature_2)
, где A3
предназначено для feature_1
, после выполнения процедуры cherry-pick
у вас будет
x <--(master)
|\
| A1 -- A2 -- A3' <--(feature_1)
\
B1 -- A3 -- B2 <--(feature_2)
Так что feature_1
может выглядеть так, как вы хотите сейчас, но feature_2
все еще имеет некоторые изменения, которых, вероятно, не должно было быть. Возможно, это вызовет некоторые проблемы при объединении обеих функций в master
. (Я имею в виду, что могут быть конфликты слияний, которые не имеют особого смысла. git
пытается здесь помочь, но это не может быть идеальным.)
В своем вопросе вы отмечаете, что коммиты уже были переданы, и в ответ на ответ cherry-pick
вы спрашиваете, будут ли изменения push
корректно; поэтому я предполагаю, что вы столкнулись (хотя бы с некоторыми) проблемами с переписыванием истории в ветке, которую вы нажали.
Несмотря на то, что результаты cherry-pick
будут push
чистыми, это связано с тем, что cherry-pick
не сделал все запрошенные изменения (как отмечено выше). Это исправление feature-2
, которое действительно вызывает проблему с push
.
Одним из решений является использование cherry-pick
для исправления feature-1
, а затем revert
для исправления feature-2
. В нашем примере, используя feature-2~1
в качестве выражения, которое идентифицирует фиксацию, которую нужно «переместить» (обычно вы можете использовать идентификатор фиксации или выражение, соответствующее вашей реальной ситуации):
git checkout feature-1
git cherry-pick feature-2~1
git checkout feautre-2
git revert feature-2~1
дает вам
x <--(master)
|\
| A1 -- A2 -- A3' <--(feature_1)
\
B1 -- A3 -- B2 -- !A3 <--(feature_2)
Это все равно будет push
чисто (потому что ни один коммит не был удален из истории какой-либо ветви), и обе ветви теперь будут иметь правильные изменения. С другой стороны, это снижает вероятность возникновения проблем слияния; с другой стороны, некоторые операции rebase
теперь могут быть проблематичными. Существуют шаги, которые вы можете предпринять, чтобы смягчить это, но если вы беспокоитесь только о внесении изменений, которые push
аккуратно, то вы все равно не будете делать такого рода rebase
.
Если существует много коммитов, которые вы хотите «переместить», то вы можете заменить cherry-pick
на интерактивный rebase
, например:
git checkout feature-2
git branch temp
git rebase -i feature-1 temp
Откроется редактор, показывающий список «задач» для rebase
. Каждая запись в списке - это инструкция для обработки коммита. Удалите строки для коммитов, которые вы хотите «оставить позади». (Есть и другие настройки, которые вы можете сделать, чтобы коммиты были представлены на feature-1
; но это длинная кроличья нора, так как все, что вы до сих пор спрашивали, это как «переместить» коммиты, так что только эти шаги сохранят их "как есть".)
Когда вы сохраните и выйдите из редактора, rebase
начнется, переписав все выбранные коммиты. Завершите обновление до feature-1
на
git checkout feature-1
git merge temp
git branch -d temp
Вам все равно нужно будет перейти к feature-2
, чтобы отменить коммиты, которых там быть не должно; Возможно, вы захотите сделать это с помощью одной команды с флагом -n
, чтобы вы могли создать только один возвратный коммит. (Это будет иметь побочный эффект снижения риска, о котором я говорил выше, некоторых rebase
операций, выполняющихся после того, как вы выполните revert
; но, опять же, я ожидаю, что вы все равно не будете выполнять эти типы rebase
учитывая ограничения, вытекающие из этого вопроса.)
Теперь некоторые люди не любят использовать revert
для такого рода вещей, потому что история показывает, что произошло - в том числе внесение изменений и последующее удаление изменений, что может показаться раздражающим, поскольку изменения никогда не должны были быть сделаны.
Единственный способ избежать этого - «переписать историю» feature-2
, и, независимо от того, как вы это сделаете, это не будет push
чисто. Вы можете получить до push
, но при этом вы создадите работу для всех других разработчиков, у которых есть копия feature-2
- и если они поступят неправильно, это отменит вашу Работа. Таким образом, вы должны координировать свои действия со всеми, кто использует репо, если вы хотите переписать историю. См. Документацию git rebase
в разделе «восстановление после восходящей версии» для получения дополнительной информации об этом.