Как 'git cherry-pick' находит файлы, к которым применяются изменения?

У меня есть два репозитория с похожей структурой, но нет общих коммитов. Я добавил их как удаленные друг от друга, чтобы иметь возможность cherry-pick совершает между ними.

Недавно я заметил, что git правильно применяет изменения коммита, даже если пути к файлам в репозиториях различаются (и сами файлы различаются). Как git найти файл (ы), чтобы применить изменения к? Просматривает ли он все файлы в текущем снимке?

2 ответа

Решение

Посмотрите предложенный дубликат Phd, Как работает выбор и возврат вишни? как черри действительно используют git merge,

Обратите внимание, что git merge работает git diff --find-renames (ну, во всяком случае, внутренний эквивалент этого). Это шаг, который определяет, какие файлы переименованы, из каких других файлов. Чтобы увидеть, как это работает, смотрите мои ответы на Попытки понять механизм обнаружения переименования `git diff` и`git mv` и Git Diff одинаковых файлов в двух каталогах всегда приводят к "переименованному". Детектор переименования запускается на обоих diff:

  • git diff parent child где child - это коммит, который выбирается вишней, а parent - его родитель; а также
  • git diff parent HEAD, который находит изменения на "нашей" стороне операции слияния. Обратите внимание, что parent здесь родительский коммит коммитов, а не родительский коммит HEAD сам.

Как правило, у parent-vs-child есть несколько переименований (большинство людей не выбирают операцию массового переименования), но parent-vs- HEAD может иметь большое количество переименований для обнаружения.

git cherry-pick eacf32b возьму патч, который описывает коммит eacf32bи попробуйте применить его поверх вашего текущего коммита.

Так что да: если просматривает все файлы в "снимке", описанном вишней выбранной фиксации.


Более полный ответ: git cherry-pick выполняет операцию слияния, чтобы применить исправление.

Начиная с:

--*--*--A--B--C--D
         \
          \
           D--E--F <- HEAD

Если вы бежите git cherry-pick D, он будет применять операцию, подобную слиянию, используя C в качестве "базового контента", D как "их" и F как "наши", как будто вы объединяете что-то со следующей историей для создания D':

..*..*..A..B   C--D
         .      \  .
          .      \  .
           D..E   F..D'

Так git также смотрит на разницу между C а также Fи может обнаружить переименование файла или вызвать конфликты при применении исправления C..D на вершине C..F

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