Как черри выбрать диапазон коммитов и слить в другую ветку?

function btnClick() {
    return validData();
}
572
задан Ciro Santilli 新疆改造中心996ICU六四事件 26 June 2018 в 14:10
поделиться

3 ответа

Когда дело доходит до диапазона коммитов, выбор вишни был непрактичным.

Как упоминается ниже Кит Ким , в Git 1.7.2+ появилась возможность выбирать диапазон коммитов (но вам все равно нужно знать о ] последствие выбора вишни для будущего слияния )

git cherry-pick "научился выбирать диапазон коммитов
(например, « выбор вишни A..B » и « выбор вишни --stdin »), так же как и « git revert »; однако они не поддерживают более удобный контроль секвенирования " rebase [-i] ".

Дамиан комментирует и предупреждает нас:

В форме « cherry-pick A..B », A должен быть старше ] B .
Если они в неправильном порядке, команда автоматически завершится ошибкой .

Если вы хотите выбрать диапазон от B до D (включительно) , это будет B ^ .. D .
См. Иллюстрацию « Git создать ветку из диапазона предыдущих коммитов? ».

Как Джубобс упоминает в комментариях :

Предполагается, что B не является корневым коммитом; в противном случае вы получите ошибку « неизвестная версия ».

Примечание: начиная с Git 2.9.x / 2.10 (3 квартал 2016 г.), вы можете выбрать диапазон фиксации прямо в ветке-сироте (пустая голова): см. " Как сделать существующую ветку сиротой в git ".


Исходный ответ (январь 2010 г.)

rebase --onto было бы лучше, когда вы воспроизводите заданный диапазон фиксации поверх своей ветки интеграции, как Чарльз Бейли описал здесь .
(также ищите «Вот как можно трансплантировать тематическую ветку, основанную на одной ветке, в другую» на странице руководства git rebase , чтобы увидеть практический пример git rebase --onto )

Если ваша текущая ветка - интеграция:

# Checkout a new temporary branch at the current location
git checkout -b tmp

# Move the integration branch to the head of the new patchset
git branch -f integration last_SHA-1_of_working_branch_range

# Rebase the patchset onto tmp, the old location of integration
git rebase --onto tmp first_SHA-1_of_working_branch_range~1 integration

Это будет воспроизводить все, что находится между:

  • после родительского элемента first_SHA-1_of_working_branch_range (отсюда ~ 1 ) : первая фиксация, которую вы хотите воспроизвести с
  • до « интеграция » (которая указывает на последнюю фиксацию, которую вы хотите воспроизвести, от рабочей ветки)

до « tmp "(который указывает на то, где раньше указывала интеграция )

Если возникает конфликт при воспроизведении одного из этих коммитов:

  • либо разрешите его, либо запустите" git rebase --continue ".
  • или пропустите этот патч и вместо этого запустите « git rebase --skip »
  • или отмените все с помощью « git rebase --abort » (и поместите вернуться в ветку интеграции в ветке tmp )

После этого rebase --onto , интеграция вернется в последнюю очередь фиксация ветки интеграции (то есть ветка « tmp » + все воспроизведенные коммиты)

При выборе вишни или rebase --onto не забывайте, что это имеет последствия для последующие слияния, как описано здесь .


Чистое решение типа « cherry-pick » обсуждается здесь и включает что-то вроде:

Если вы хотите использовать патч, тогда «git format-patch | git am "и" git cherry "- ваши варианты.
В настоящее время git cherry-pick принимает только одну фиксацию, но если вы хотите выбрать диапазон от B до D , это будет B ^. .D на git lingo, поэтому

git rev-list --reverse --topo-order B^..D | while read rev 
do 
  git cherry-pick $rev || break 
done 

Но в любом случае, когда вам нужно «воспроизвести» диапазон коммитов,слово «воспроизведение» должно подтолкнуть вас к использованию функции Git « rebase ».

764
ответ дан 22 November 2019 в 22:01
поделиться

Ты уверен, что не хочешь на самом деле сливать ветки? Если в рабочей ветке есть несколько недавних коммитов, которые вам не нужны, вы можете просто создать новую ветку с HEAD в нужный момент.

Теперь, если по какой-то причине вы действительно хотите видоизменить набор коммитов, элегантный способ сделать это - просто вытащить патчсет и применить его к вашей новой ветке интеграции:

git format-patch A..B
git checkout integration
git am *.patch

В сущности, это то, что делает git-rebase в любом случае, но без необходимости играть в игры. Вы можете добавить --3way в git-am, если вам нужно слияние. Убедитесь, что в каталоге, где вы это делаете, нет других *.patch-файлов, если вы следуете инструкциям дословно...

.
26
ответ дан 22 November 2019 в 22:01
поделиться

Я обернул код VonC в короткий сценарий bash, git-multi-cherry-pick , для удобства running:

#!/bin/bash

if [ -z $1 ]; then
    echo "Equivalent to running git-cherry-pick on each of the commits in the range specified.";
    echo "";
    echo "Usage:  $0 start^..end";
    echo "";
    exit 1;
fi

git rev-list --reverse --topo-order $1 | while read rev 
do 
  git cherry-pick $rev || break 
done 

В настоящее время я использую это, поскольку я перестраиваю историю проекта, в котором в одном стволе svn были смешаны сторонний код и настройки. Теперь я разделяю основной сторонний код, сторонние модули и настройки на их собственные ветки git для лучшего понимания будущих настроек. git-cherry-pick полезен в этой ситуации, поскольку у меня есть два дерева в одном репозитории, но без общего предка.

9
ответ дан 22 November 2019 в 22:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: