Синтаксис git cherry-pick и ветви слияния

Итак, я сделал бесчисленные вишневые кирки раньше, и кажется, что я должен потерпеть неудачу в жизни с этим прямо сейчас, я пытаюсь вишневый выбор с одной ветви на другую, что должно быть легко, как я могу получить ошибку о том, что это слияние, но не-m было дано?

$ git cherry-pick a8c5ad438f6173dc34f6ec45bddcef2ab23285e0
error: Commit a8c5ad438f6173dc34f6ec45bddcef2ab23285e0 is a merge but no -m option was given.
fatal: cherry-pick failed

это выглядит неправильно.......должно быть:

$ git cherry-pick a8c5ad438f6173dc34f6ec45bddcef2ab23285e0

С каких пор я должен поставлять функцию a-m?

5 ответов


вы должны поставить -m Если фиксация является объединить commit, т. е. фиксация с более чем одним родителем.

нормально, что git cherry-pick REV does можно описать как:

  1. принять изменения между rev и его родителя.

  2. примените эти изменения к текущей головке и зафиксируйте результат с помощью rev'ы сообщение.

фиксация слияния соединяет два линия развития. Например, одна строка реализует виджет, а другая строка удаляет беспорядок. Слияние дает вам код с виджетом, без помех.

теперь рассмотрим Шаг №1 процесса cherry-pick: git не может догадаться, хотите ли вы удалить беспорядок или реализовать виджет. И вы не можете сделать оба, потому что информация о том, как сделать оба, не содержится внутри одной фиксации слияния, только содержимое результирующего объединенного дерева.

в -m опция позволяет сказать git, как действовать. Например, если удаление беспорядка произошло на master и фиксация слияния была создана с помощью git merge WIDGET, потом git cherry-pick -m 1 merged-commit будет вишневый выбор нового виджета, потому что разница между объединенным деревом и родителем 1 (последний из коммитов по удалению беспорядка) будет именно добавлением виджета. С другой стороны,--6--> будет удалить беспорядок, потому что разница между родителем 2 (Последний из виджетов-добавление коммитов) и merge-commit именно беспорядок-удаление отсутствует из виджет филиала.


git просит вас указать Родительский номер (-m), поскольку у вашего слияния есть два родителя и git не знают, какую сторону слияния следует считать основной линией. Таким образом, используя эту опцию, вы можете указать Родительский номер (начиная с 1) основной линии и cherry-pick, чтобы воспроизвести изменение относительно указанного родителя.

чтобы узнать своих родителей, попробуйте либо:

git show --pretty=raw <merge_commit>

или:

git cat-file -p <merge_commit>

или даже для лучшей видимости GUI, попробуйте:

gitk <merge_commit>

в результате, вы должны получить что-то вроде:

commit fc70b1e9f940a6b511cbf86fe20293b181fb7821
tree 8d2ed6b21f074725db4f90e6aca1ebda6bc5d050 
parent 54d59bedb9228fbbb9d645b977173009647a08a9 = <parent1_commit>
parent 80f1016b327cd8482a3855ade89a41ffab64a792 = <parent2_commit>

затем проверьте свои данные каждого родителя по:

git show <parent1_or_2_commit>

добавить --stat посмотреть список измененных файлов.

или используйте следующую команду для сравнения изменений (на основе вышеприведенного родителя):

git diff <parent1_or_2_commit>..<commit>

добавить --stat посмотреть список измененных файлов.

или используйте комбинированный diff для сравнения двух родителей по:

git diff --cc <parent1_commit>
git diff --cc <parent2_commit>

затем укажите Родительский номер, начиная с 1 для вашего вишневого выбора, например

git cherry-pick -m 1 <merge_commit>

затем запустите git status чтобы увидеть, что происходит. Если вы еще не хотите фиксировать изменения, добавьте -n возможность увидеть, что происходит. Затем, когда вы не счастливы, сбросить в голову (git reset HEAD --hard). Если вы получите конфликты git, вам, вероятно, придется решать их вручную или укажите стратегию слияния (-X), см.: как разрешить конфликты слияния в Git?


лично, что я обычно делаю в том, что после слияния совместная 2 совершает, например, если у меня фиксация слияния C, которая состоит из 2 родителей е.г совершить в Мастер и совершить в другой ветке становится слился, если мне нужно, чтобы вишня выбрать "слияние" я бы не стал заморачиваться с толку команду, чтобы вишня выбрать фиксацию себе, но вместо этого я бы просто вишня каждый из родителей A и B по отдельности, это также полезно в ситуации, когда вы только хотите, чтобы вишня выбрать совершают Б только в случае, если фиксация от мастера уже была Вишневой на ветке, это вишневый сбор до того, как произошло слияние.


синтаксис man-страниц выглядит следующим образом:

git cherry-pick [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...

Родительский номер относится к:

- M parent-number, --mainline parent-number, обычно вы не можете выбрать слияние, потому что вы не знаете, какая сторона слияния должна считаться основной линией. Эта опция задает Родительский номер (начиная с 1) основной линии и позволяет cherry-pick воспроизвести изменение относительно указанного родителя.

поэтому я бы дважды проверьте, чтобы убедиться, что у вас есть правильный хэш фиксации. Возможно, Вам нужен тот, который не от слияния, а скорее от фиксации перед ним. В противном случае вам нужно использовать этот флаг и указать правильную сторону слияния, чтобы устранить двусмысленность вашего запроса.


попробуйте объединить результат:

git cherry-pick ....
git mergetool
git cherry-pick --continue