Могу ли я переместить push-коммиты из одной ветви в другую существующую ветку? - PullRequest
0 голосов
/ 17 мая 2018

У меня есть 3 филиала: develop, feature-1 и feature-2. Я работал на feature-1, затем переключился на работу на feature-2. Затем я закончил работу над feature-2, зафиксировал и отправил в репозиторий, а затем создал запрос на слияние для этой функции. Затем я увидел, что feature-2 содержит некоторые коммиты, которые должны были быть в feature-1. Могу ли я переместить их с feature-2 на feature-1 локально, а затем отразить те же ходы в репо?

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Ваш вопрос говорит о том, что данные коммиты принадлежат в 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 в разделе «восстановление после восходящей версии» для получения дополнительной информации об этом.

0 голосов
/ 17 мая 2018

git cherry-pick <commit-id> твой друг дорогой.

  1. Перейти на ветку Feature-2
  2. Копировать commit-id(s) вы хотите перейти с feature-2 на feature-1
  3. Переключиться на ветку Feature-1
  4. Теперь Черри выберет все коммиты, которые вы скопировали на шаге 2 выше.

    git cherry-pick <commit-id>

    Если у вас есть более одного коммита, который нужно переместить на feature-1, поместите все идентификаторы коммитов в последовательности их даты / времени фиксации.

    Например:

    git cherry-pick <commit-id-1> <commit-id-2> . . <commit-id-n>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...