Как применить патч 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, чтобы применить к этому конкретному файлу, но я ищу решение для команды.
5 ответов
Вы можете создать патч используя 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
Существует простое решение, которое не включает ни ручное редактирование патча, ни внешний скрипт.
В первом хранилище (это также может экспортировать диапазон фиксации, используйте -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
,
Отвечая на мой собственный вопрос с помощью скрипта, который делает это: https://github.com/mprpic/apply-patch-to-file
Вместо того, чтобы изменять файл патча вручную, он запрашивает у пользователя целевой файл, модифицирует патч и применяет его к репо, в котором вы сейчас находитесь.
Основываясь на ответе @georgebrock, вот решение, которое я использовал:
Сначала создайте файлы исправлений как обычно (например, git format-patch commitA..commitB
).
Затем убедитесь, что ваш целевой репозиторий является чистым (не должно быть измененных или неотслеживаемых файлов) и примените патчи следующим образом:
cd second-repo
git am ~/00*.patch
Для каждого файла патча вы получите ошибку типа "ошибка: XYZ не существует в индексе". Теперь вы можете применить этот файл патча вручную:
patch --directory blue/red < ~/0001-*.patch
git add -a
git am --continue
Вы должны сделать эти три шага для каждого файла патча.
Это сохранит исходное сообщение о коммите и т. Д., Не требуя каких-либо специальных git format-patch
команда или редактирование файлов патчей.
Я понимаю, что в вашей ситуации два файла абсолютно одинаковы, поэтому, скорее всего, исправление пройдет успешно.
Однако, если вы хотите применить исправление к похожему, но не точно тому же файлу, или хотите сделать интерактивное исправление, вы будете использовать трехстороннее объединение.
Скажем, вы изменили файл A
давайте обозначим A~1
как и в предыдущей версии, и вы хотите применить разницу между A~1
в A
в файл B
,
Откройте трехсторонний инструмент слияния, например Beyond Compare, путь к левой панели A
средняя панель является общим предком, поэтому путь A~1
путь правой панели B
, Затем нижняя панель показывает результат применения различий между A~1
в A
в файл B
,
Следующий рисунок иллюстрирует идею.
К вашему сведению: недавно у меня были проблемы с попыткой загрузить патч с Github и применить его к локальному файлу (что было "переопределением" в новом месте).
git am
не применил бы исправление либо потому, что файл был "не в индексе", либо "грязный". Но я обнаружил, что простойpatch
команда могла применить патч. Мне было предложено указать имя файла, который нужно исправить.
В любом случае, работа сделана...