Как '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