Я сделал некоторые изменения в своей основной ветке и хочу внести их в апстрим. когда я выбираю следующие коммиты, я застреваю на fd9f578, где git говорит:
$ git cherry-pick fd9f578
fatal: Commit fd9f57850f6b94b7906e5bbe51a0d75bf638c74d is a merge but no -m option was given.
Что мерзавец пытается сказать мне, и является ли вишня подобрать правильную вещь для использования здесь? Основная ветвь включает в себя изменения в файлах, которые были изменены в восходящей ветке, поэтому я уверен, что будут некоторые конфликты слияния, но они не так уж и плохи, чтобы их исправить. Я знаю, какие изменения нужны где.
Это коммиты, которые я хочу представить.
e7d4cff added some comments...
23e6d2a moved static strings...
44cc65a incorporated test ...
40b83d5 whoops delete whitspace...
24f8a50 implemented global.c...
43651c3 cleaned up ...
068b2fe cleaned up version.c ...
fd9f578 Merge branch 'master' of ssh://extgit/git/sessions_common
4172caa cleaned up comments in sessions.c ...
источник
git rebase
- это как слияние, но вместо объединения двух ветвей он пересаживает одну, чтобы сидеть над другой.git show
и тому подобное).git reset --hard HEAD@{1}
чтобы вернуть свой недостающий коммит.git reset
не ограничивается движением «назад» в истории.git checkout -b mybranch HEAD@{1}
также будет работать.git merge
может иметь непредвиденные последствия. Эта команда добавит все другие (более старые) коммиты, которые существуют в родительской ветви. Обычно люди выбирают вишню, потому что они не хотят других коммитов. Убедитесь, что вы дважды проверили, что вносите только те изменения, которые хотите!-m
означает родительский номер.Из Git Doc:
Например, если ваше дерево коммитов выглядит так:
затем
git cherry-pick E
создаст проблему, с которой вы столкнулись.git cherry-pick E -m 1
означает использованиеD-E
, в то время какgit cherry-pick E -m 2
означает использованиеB-C-E
.источник
Ответ @ Бореалида верный, но предположим, что вы не заботитесь о сохранении точной истории слияния ветки и просто хотите выбрать ее линеаризованную версию. Вот простой и безопасный способ сделать это:
Начальное состояние: вы находитесь на ветке
X
, и вы хотите выбрать коммитыY..Z
.git checkout -b tempZ Z
git rebase Y
git checkout -b newX X
git cherry-pick Y..tempZ
git branch -D tempZ
Для этого нужно создать ветку,
tempZ
основанную наZ
истории, но сY
линеаризованной историей , а затем выбрать ее на копиюX
коллаnewX
. (Безопаснее делать это в новой ветви, а не мутироватьX
.) Конечно, на шаге 4 могут возникнуть конфликты, которые вам придется разрешать обычным способом (cherry-pick
работает очень похожеrebase
на это). Наконец, он удаляет временнуюtempZ
ветку.Если на шаге 2 выдается сообщение «Текущая ветвь tempZ актуальна», то
Y..Z
она уже была линейной, поэтому просто проигнорируйте это сообщение и продолжайте с шага 3 и далее.Затем просмотрите
newX
и посмотрите, сделал ли это то, что вы хотели.(Примечание: это не то же самое, что и в простом
git rebase X
ветвленииZ
, потому что это никак не зависит от отношений междуX
иY
; могут быть коммиты между общим предком и тем,Y
что вы не хотели.)источник
git rebase Y
говоритCurrent branch tempZ is up to date
Y..Z
было уже линейно. Таким образом, вы можете проигнорировать это сообщение и перейти к шагам 3 и 4.Упростить. Вишневый пик коммитов. Не выбирай слияния.
Вот переписанный принятый ответ, который идеально проясняет преимущества / риски возможных подходов:
Вы пытаетесь выбрать вишню fd9f578, которая была слиянием с двумя родителями.
Вместо выбора вишни слияния, самая простая вещь - вишня выбрать коммит (ы), который вы на самом деле хотите из каждой ветви в слиянии.
Поскольку вы уже слились, вероятно, все ваши желаемые коммиты есть в вашем списке. Выбирайте их напрямую, и вам не нужно связываться с коммитом слияния.
объяснение
Метод вишневого выбора работает, используя diff, который представляет набор изменений (разница между рабочим деревом в этой точке и рабочим деревом его родителя), и применяя набор изменений к вашей текущей ветви.
Если коммит имеет двух или более родителей, как в случае слияния, этот коммит также представляет два или более различий. Ошибка возникает из-за неопределенности, в отношении которой должен применяться diff.
альтернативы
Если вы решите, что вам нужно включить слияние против выбора вишни связанных коммитов, у вас есть два варианта:
(Более сложный и неясный; также отбрасывает историю) вы можете указать, к какому из родителей следует обратиться.
Используйте
-m
опцию, чтобы сделать это. Например,git cherry-pick -m 1 fd9f578
будет использоваться первый родитель в списке в качестве слияния.Также учтите, что когда вы выбираете коммит слияния, он объединяет все изменения, сделанные в родительском элементе, для которого вы не указали,
-m
в этот коммит . Вы теряете всю их историю и собираете вместе все их различия. Ваш звонок.(Проще и знакомее; сохраняет историю) вы можете использовать
git merge
вместоgit cherry-pick
.git merge
, он попытается применить все коммиты, существующие в ветке, которую вы объединяете, и перечислить их по отдельности в ваш журнал git.источник
Упрощение метода @Daira Hopwood для выбора одного коммита. Не нужно никаких временных веток.
В случае с автором:
затем сделайте:
источник