В чем разница между git merge --squash A SINGLE COMMIT и git cherry-pick той же самой фиксации?

Я пытаюсь понять практическое различие между сбором вишни и слиянием одной фиксации, если таковая имеется. Чтобы быть более точным, приведите следующую простую ситуацию:

-O <- master
  \
   A <- develop

Есть ли практическая разница между сбором вишни и слиянием единственного коммита A в master?

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

Что я пытаюсь понять, так это то, есть ли какая-либо причина предпочесть сквош-фиксацию в этой конкретной ситуации, а не более простую IMO-выборку вишни?

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

-O <- master
  \
   A-B-C <- develop

Есть ли разница между сбором вишен A, B и C (в таком порядке) и последующим раздавливанием их на мастере и последовательностью git merge --squash -> разрешить конфликты -> git commit?

Мое наблюдение до сих пор состоит в том, что сквош-слияние часто сообщает о конфликтах слияния для простейшего изменения, чего не происходит при выборе вишни. Например, это тривиальное изменение в A (от O) сообщается как конфликт слияния при слиянии сквоша, но не при выборе вишни:

<<<<<<< HEAD
        allow(subject).to receive(:some_method).and_return(some_result)
=======
        allow(controller).to receive(:some_method).and_return(some_result)
>>>>>>> 3s/checkout-page/develop

После разрешения конфликтов состояние рабочего директора, конечно же, остается прежним.

Кажется, что сбор вишен легче и менее проблематичен в краткосрочной перспективе, но мне интересно, есть ли последствия в будущем.

Если вы сделаете и то, и другое, какие различия вы заметите?

Ulrich Eckhardt 12.12.2020 12:22

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

zor-el 12.12.2020 12:30

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

Ulrich Eckhardt 12.12.2020 12:32

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

torek 12.12.2020 12:46

Глупая заметка: если у вас включен rerere, конфликты, разрешенные в первый раз, будут автоматически разрешены во второй раз. Проверьте свою конфигурацию git.

LeGEC 12.12.2020 14:39
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
75
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Сообщения фиксации по умолчанию будут отличаться.

Кроме этого, если граф фиксации - это то, что вы нарисовали здесь:

...--H--I--J   <-- master (HEAD)
            \
             K   <-- develop

эффект слияния или выбора вишни будет таким же, потому что фактическая база слияния master и develop — это фиксация J. Чтобы увидеть это в действии, используйте git rev-parse и git merge-base:

$ git rev-parse master
<some hash ID appears>
$ git rev-parse develop
<another hash ID appears>
$ git merge-base --all master develop
<the hash ID from the rev-parse master command appears again>

Это слияние или вишневый выбор никогда не будет иметь конфликтов. Причина в том, что родителем K является J, а текущим коммитом является J, поэтому база слияния / Cherry-Pick-Parent является текущим коммитом, а один из двух diff пуст.

Теперь предположим, что график выглядит так:

...--H--I--J   <-- master (HEAD)
      \
       K   <-- develop

На этот раз база слияния будет зафиксирована H. Результат снова должен быть одинаковым для обеих операций, как база слияния master (текущая фиксация J) и develop, но на этот раз могут возникнуть конфликты слияния, поскольку две стороны различия будут сравнивать H-vs-J для «наши» изменения и H-vs-K для «их» изменений. Если мы и они коснемся одних и тех же строк одного и того же файла или коснутся строк, которые примыкают к какому-то одному файлу, мы получим конфликт слияния.

Многие ответы здесь сосредоточены на общей разнице, когда разработка на несколько коммитов опережает мастер...

Правильно: в этом случае у нас есть что-то вроде, скажем:

...--H--I--J   <-- master (HEAD)
      \
       K--L   <-- develop

Здесь коммит выбора вишни L заставляет Git выполнить трехстороннее слияние между содержимым K (в качестве базы слияния), содержимым J (в качестве «нашего» коммита) и содержимым L (в качестве «их» коммита). " совершить). Поэтому мы различаем K и master (т. е. J), чтобы увидеть, что мы изменили, и K и L, чтобы увидеть, что они изменили. Затем Git объединяет эти различия и применяет объединенные изменения к содержимому K, чтобы получить выборку L'.

Напротив, git merge --squash находит фиксацию H в качестве базы слияния, сравнивая H и J, чтобы найти наши изменения, и H и L, чтобы найти их. Затем Git объединяет эти изменения — которые, вероятно, представляют собой два разных набора изменений, отличных от наборов вишни, — и применяет объединенные изменения к снимку в H, а не к снимку в K.

«эффект слияния или выбора вишни будет одинаковым, потому что фактическая база слияния мастера и разработки — это фиксация J». Но почему git merge --squash иногда сообщает о конфликтах, а выбор вишни — нет? (Спасибо, кстати, за быстрый и подробный ответ.)

zor-el 12.12.2020 12:54

Создайте повторяемый пример, например, небольшой сценарий оболочки, который создает репозиторий, делает несколько коммитов и настраивает все так, чтобы это произошло. Тогда мы сможем повторить это и посмотреть, произойдет ли это в наших собственных версиях Git, потому что этого точно не должно быть. :-)

torek 12.12.2020 13:17

torek, с вашим комментарием к моему вопросу выше («В этом случае это может показать вам, что фиксация, которую вы считали базой слияния, на самом деле не является базой слияния» - и, конечно же, это было так), я считаю, что мой вопрос ответил. Спасибо за отличную разработку!

zor-el 12.12.2020 15:16

Другие вопросы по теме