Как git cherry-pick вычисляет исправление?

#git #cherry-pick #git-cherry-pick

#git #выбор вишни #git-cherry-pick

Вопрос:

Я понимаю, как git cherry-pick работает на высоком уровне: он принимает изменения, внесенные в один коммит, и применяет их к другому.

Тем не менее, я пытаюсь лучше понять, как git на самом деле достигает этого под капотом.

Предположим, вы запускаете следующее:

 $ git checkout main
$ git cherry-pick source-commit
  

Я понимаю, что, поскольку фиксация является моментальным снимком, а не набором изменений, этот cherry-pick должен сначала вычислять какой-то diff, а затем применять этот patch / diff к текущей ветке ( main ). Является ли этот патч просто отличием source-commit от своего родителя? Задействована ли вообще база слияния source-commit и main ?

Ответ №1:

Действительно, выполнение git cherry-pick HASH с помощью одной фиксации более или менее эквивалентно:

  1. git show --patch HASH > temp.diff
  2. git apply temp.diff

В свою очередь, шаг 1 выше вычисляет разницу между данным коммитом и его единственным родителем.

(Вы можете выбрать слияние, но вы должны указать, с каким родителем сравнивать, с опцией -m parent-number .)

О базе слияния, AFAIK база слияния ХЭША и main вообще не задействована. Обратите внимание, что в случае конфликтов, если вы настроили diff3 стиль конфликта, средний фрагмент (который для слияний является базой слияния) является просто родительским элементом вишни.

Комментарии:

1. Точнее, это похоже на использование git am --3way в исправлении, поскольку cherry-pick при необходимости выполнит слияние и сделает новую фиксацию. Внутри, git cherry-pick использует механизм слияния (используя git merge-recursive по умолчанию) с базой слияния, просто вынужденной быть родительской, или с -m выбранным родительским элементом, для выбранного коммита.