Git Cherry-pick vs Merge Workflow

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

  • я cherry-pick каждый фиксация с пульта (по порядку). В этом случае git записывает фиксацию как не связанную с удаленной ветвью.
  • я merge ветвь, потянув все изменения и добавив новую "конфликтную" фиксацию (при необходимости).
  • я merge каждый фиксирует от удаленной ветки индивидуально (опять по порядку), позволяя записывать конфликты для каждой фиксации, а не группировать все вместе как один.
  • Для полноты вы можете сделать rebase (то же, что и cherry-pick опция?), однако я понимаю, что это может вызвать путаницу для вкладчика. Возможно, это исключает вариант 1.

В обоих случаях 2 и 3, git записывает историю ветвей коммитов, в отличие от 1.

Что такое pro и con между использованием методов cherry-pick или merge?. Я понимаю, что метод 2 является нормой, но я чувствую, что решение большого коммита с одним "конфликт" сливается, не является самым чистым решением.

Ответ 1

Оба rebasecherry-pick) и merge имеют свои преимущества и недостатки. Я утверждаю, что здесь merge, но стоит понять и то, и другое. (Посмотрите здесь альтернативный, хорошо аргументированный ответ , перечисляющий случаи, когда rebase является предпочтительным.)

merge предпочтительнее cherry-pick и rebase по нескольким причинам.

  • грубости. Идентификатор SHA1 фиксации идентифицирует его не только сам по себе, но и по отношению ко всем другим коммитам, которые предшествуют ему. Это дает вам гарантию того, что состояние репозитория в данном SHA1 идентично для всех клонов. Существует (теоретически) отсутствие шансов, что кто-то сделал то, что похоже на одно и то же изменение, но на самом деле искажает или захватывает ваш репозиторий. Вы можете вишнево выбирать в индивидуальных изменениях, и они, вероятно, одинаковы, но у вас нет никакой гарантии. (В качестве второстепенной вторичной проблемы новые захваченные вишни коммиты будут занимать дополнительное место, если кто-то еще вишневый выбирает в том же комманде снова, поскольку они оба будут присутствовать в истории, даже если ваши рабочие копии в итоге совпадают.)
  • Простота использования. Люди склонны легко понимать рабочий процесс merge. rebase имеет тенденцию считаться более продвинутым. Лучше всего понять и то, и другое, но люди, которые не хотят быть экспертами в области контроля версий (которые по моему опыту включали многих коллег, которые чертовски хороши в том, что они делают, но не хотят тратить дополнительное время), легче время просто сливается.

Даже в случае слияния с тяжелыми рабочими потоками rebase и cherry-pick все еще полезны для конкретных случаев:

  • Один недостаток merge - загроможденная история. rebase предотвращает разброс длинной серии коммитов в вашей истории, как если бы вы периодически сливались в другие изменения. Это и есть его основная цель, поскольку я использую ее. То, что вы хотите быть очень осторожным, никогда не относится к коду rebase, который вы поделили с другими репозиториями. После фиксации push ed кто-то еще мог бы сделать это поверх нее, а перезагрузка в лучшем случае приведет к описанному выше дублированию. В худшем случае у вас может быть очень запутанный репозиторий и тонкие ошибки, на которые уходит много времени, чтобы выведать.
  • cherry-pick полезен для отбора небольшого подмножества изменений из ветки темы, которую вы в основном решили отбросить, но понял, что есть несколько полезных фрагментов.

Что касается предположения о слиянии многих изменений над одним: это намного проще. Может быть очень утомительно делать слияния отдельных наборов изменений после того, как вы начнете их много. Разрешение слияния в git (и в Mercurial, и на Bazaar) очень хорошее. Вы не столкнетесь с серьезными проблемами слияния даже длинных ветвей большую часть времени. Я вообще объединяю все все сразу, и только если я получаю большое количество конфликтов, я возвращаюсь и повторно запускаю слияние по частям. Даже тогда я делаю это в больших кусках. В качестве очень реального примера у меня был коллега, у которого было 3 месяца изменений, чтобы объединиться, и получил около 9000 конфликтов в 250000 строк кода. То, что мы сделали, чтобы исправить, заключается в том, чтобы объединить один месяц за раз: конфликты не растут линейно, а в результате получается намного меньше, чем 9000 конфликтов. Это была еще большая работа, но не так много, как попытка сделать это за один раз.

Ответ 2

По-моему, сборка вишни должна быть зарезервирована для редких ситуаций, когда это требуется, например, если вы сделали некоторые исправления непосредственно на ветке "мастер" (магистраль, основная ветка развития), а затем поняли, что ее следует применять также на "maint". Вы должны основывать рабочий процесс либо на слиянии, либо на rebase (или "git pull --rebase" ).

Помните, что выбранная вишня или rebased commit отличается с точки зрения Git (имеет другой идентификатор SHA-1), чем оригинал, поэтому он отличается от фиксации в удаленный репозиторий. (Rebase обычно может справиться с этим, поскольку он проверяет идентификатор патча, т.е. Изменения, а не идентификатор фиксации).

Также в Git вы можете объединить сразу несколько ветвей: так называемое octopus merge. Обратите внимание, что слияние осьминога должно преуспеть без конфликтов. Тем не менее это может быть полезно.

НТН.