Как применить патч Git к файлу с другим именем и путем?

У меня есть два репозитория. В одном я вношу изменения в файл ./hello.test. Я фиксирую изменения и создаю патч из этой фиксации с помощью git format-patch -1 HEAD. Теперь у меня есть второй репозиторий, содержащий файл, который имеет то же содержимое, что и hello.test, но помещается в другой каталог под другим именем: ./blue/red/hi.test. Как я могу применить вышеупомянутый патч к файлу hi.test? Я пробовал git am --directory='blue/red' < patch_file, но, конечно же, жалуется, что файлы не называются одинаковыми (что я думал, что Git не заботился?). Я знаю, что я, вероятно, мог бы отредактировать diff для применения к этому конкретному файлу, но я ищу командное решение.

Ответ 1

Вы можете создать патч, используя git diff, а затем применить его с помощью patch, которая позволяет вам указать файл, к которому вы хотите применить diff.

Например:

cd first-repo
git diff HEAD^ -- hello.test > ~/patch_file

cd ../second-repo
patch -p1 blue/red/hi.test ~/patch_file

Ответ 2

Существует простое решение, которое не требует ручного редактирования патчей и внешнего script.

В первом репозитории (это может также экспортировать диапазон фиксации, используйте -1, если вы хотите выбрать только одно коммит):

git format-patch --relative <committish> --stdout > ~/patch

Во втором репозитории:

git am --directory blue/red/ ~/patch

Вместо использования --relative в git format-patch другое решение состоит в использовании опции -p<n> в git am для удаления каталогов n с пути патчей, как указано в ответить на аналогичный вопрос.

Можно также запустить git format-patch --relative <committish> без --stdout, и он сгенерирует набор файлов .patch. Затем эти файлы можно напрямую передать на git am с помощью git am --directory blue/red/ path/to/*.patch.

Ответ 3

Отвечая на мой вопрос с помощью script, который делает только это: https://github.com/mprpic/apply-patch-to-file

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