как использовать git cherry pick для обработки изменений папок между различными ветками для вновь созданного файла - PullRequest
0 голосов
/ 14 января 2019

У нас недавно произошли изменения структуры кода между двумя ветвями, а именно, A и B. Поэтому, когда я пытаюсь выбрать вариант перехода от B к A,

git cherry-pick commit-hash

если файлы ранее существовали, изменения объединяются корректно (кажется, git может отследить предыдущий существующий файл для изменения их папки). Тем не менее, я заметил, что два новых файла в B были объединены в A с новым путем (создается автоматически), а не со старым путем. Есть ли какой-нибудь элегантный способ справиться с этим?

1 Ответ

0 голосов
/ 15 января 2019

Внутренне, git cherry-pick <em>commit</em> реализовано как трехстороннее слияние с:

  • база слияния, установленная в качестве родителя коммита, обозначенного commit;
  • текущий коммит установлен на текущий коммит, как всегда;
  • другой коммит установлен на commit.

Это объединяющее действие, или, как я люблю его называть, «объединить как глагол», происходит как обычно:

  • запустить git diff --find-renames <em>base</em> HEAD, чтобы узнать, что мы изменили
  • запустить git diff --find-renames <em>base</em> <em>other</em>, чтобы узнать, что они изменили
  • объединить два набора изменений, применяя объединенные изменения к base

Если это удается, Git делает новый обычный (без слияния) коммит как обычно. Если это не удается, Git останавливается с конфликтом слияния, оставляя коммит other, идентифицируемый CHERRY_PICK_HEAD вместо MERGE_HEAD, так что ваш окончательный коммит - при условии, что вы выбрали коммит - делает обычный (без слияния) commit.

Это --find-renames шаг, который находит или не может найти, переименовывает. Это делается обычным способом. Например, при сравнении base с HEAD, если в base существуют файлы, которые не существуют в HEAD в то же самое Имена, Git будет сравнивать все несопоставленные base файлы со всеми несопоставленными HEAD файлами, чтобы увидеть, какие из этих файлов имеют похожее содержимое. Два файла с большинством аналогичным содержимым будут объединены в пару при условии, что вычисленный индекс подобия соответствует или превышает минимальный требуемый индекс сходства, выбранный -X find-renames=<em>value</em>. Если такого аргумента -X нет, по умолчанию используется значение 50 (то есть 50% аналогичное).

Поэтому, когда я пытаюсь выбрать вишню, переход от B к A,

git cherry-pick commit-hash

Давайте закончим эту мысль. Когда вы пытаетесь выбрать этот конкретный коммит, Git находит родителя этого коммита, выбирает его в качестве базы слияния и запускает указанную выше команду git diff. HEAD имеет значение name A, так что текущий коммит является коммитом tip для ветви A, каким бы ни был этот хэш-идентификатор. Git поэтому запускает эквивалент git diff --find-renames hash A. Сделайте это самостоятельно, если хотите, с помощью --name-status (чтобы получить только имена и статусы файлов, включая переименования), и вы увидите, какие файлы Git были в паре между hash и HEAD. Если вы прочитали предыдущий абзац, вы уже знаете, какой алгоритм Git использует для этого спаривания: он ищет достаточно похожих файлов, которые иначе не были бы спарены.

Если таких файлов не может быть никогда, Git не найдет таких файлов. В этом случае вам необходимо изменить любые имена файлов, если / как необходимо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...