git cherry-pick говорит: "... 38c74d-это слияние, но опция no-m была предоставлена"

Я сделал некоторые изменения в моей главной ветви и хочу принести их вверх по течению. когда я выбираю следующие коммиты, однако я застреваю на fd9f578, где git говорит:

$ git cherry-pick fd9f578
fatal: Commit fd9f57850f6b94b7906e5bbe51a0d75bf638c74d is a merge but no -m option was given.

что git пытается сказать мне, и черри-выбрать правильную вещь, чтобы использовать здесь? Главная ветвь включает изменения в файлы, которые были изменены в восходящей ветви, поэтому я уверен, что будут некоторые конфликты слияния, но это не так уж плохо, чтобы исправить. Я знаю, какие изменения нужно где.

эти коммиты я хочу продвинуть.

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 ...

4 ответов


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

Итак, если фиксация имеет двух или более родителей, она также представляет два или более различий - какой из них следует применять?

вы пытаетесь выбрать вишню fd9f578, Что было слиянием с двумя родителями. Поэтому вам нужно сказать команде cherry-pick, которая против который diff должен быть рассчитан, используя . Например, git cherry-pick -m 1 fd9f578 использовать родитель 1 в качестве основы.

Я не могу точно сказать по вашей конкретной ситуации, но с помощью git merge вместо git cherry-pick обычно рекомендуется. Когда вы выбираете фиксацию слияния, она рушится все изменения, внесенные в родителя, который вы не указали в -m на один commit. Вы теряете всю их историю, и глом вместе все их различия. Ваш вызов.


@Borealid ответ правильный, но предположим, что вы не заботитесь о сохранении точной истории слияния ветви и просто хотите выбрать линеаризованную версию. Вот простой и безопасный способ сделать это:

начальное состояние: вы находитесь на филиал X, и вы хотите вишневый выбрать коммиты Y..Z.

  1. git checkout -b tempZ Z
  2. git rebase Y
  3. git checkout -b newX X
  4. git cherry-pick Y..tempZ
  5. (опционально) 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 что вы не хотите.)


вот переписывание принятого ответа, который идеально разъясняет преимущества / риски возможных подходов:

вы пытаетесь выбрать вишню fd9f578, которая была слиянием с двумя родителями.

вместо вишневого выбора слияния, самая простая вещь-вишневый выбор фиксации(ов), которые вы действительно хотите от каждой ветви в слиянии.

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

объяснение

как работает вишневый выбор, принимая diff, который представляет набор изменений (разница между рабочим деревом в этой точке и рабочим деревом его родителя), и применяя набор изменений к вашей текущей ветви.

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

варианты

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

  1. (более сложный и неясный; также отбрасывает историю) вы можете указать, какой родитель должен применяться.

    • использовать -m возможность сделать это. Например, git cherry-pick -m 1 fd9f578 будет использовать первый родитель, указанный в слиянии в качестве основа.

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

  2. (проще и более знакомо; сохраняет историю) вы можете использовать git merge вместо git cherry-pick.

    • как обычно с git merge, он попытается применить все коммиты, которые существуют в ветви, которую вы объединяете, и перечислить их отдельно в своем журнале git.

упрощение метода @Daira Hopwood хорошо подходит для выбора одного коммита. Не нужны временные ветви.

в случае автора:

  • Z требуется совершить (fd9f578)
  • Y совершает перед ним
  • X текущая рабочая ветвь

затем выполните:

git checkout Z   # move HEAD to wanted commit
git reset Y      # have Z as changes in working tree
git stash        # save Z in stash
git checkout X   # return to working branch
git stash pop    # apply Z to current branch
git commit -a    # do commit