Как применить патч git из одного репозитория в другой?

StackOverflow https://stackoverflow.com/questions/931882

Вопрос

У меня есть два репозитория: один — основной репозиторий библиотеки, а другой — проект, использующий эту библиотеку.

Если я внесу исправление в подчиненный проект, мне нужен простой способ применить этот патч обратно в исходную версию.

Местоположение файла в каждом репозитории разное.

  • Основное репо: www.playdar.org/static/playdar.js
  • Проект: playlick.com/lib/playdar.js

Я попробовал использовать git format-patch -- lib/playdar.js в проекте playlick, а затем git am в основном репозитории Playdar, но разные местоположения файлов в файле патча вызывали ошибку.

Есть ли простой способ применить патч из данного коммита к данному файлу к другому произвольному файлу в другом месте?

В качестве бонуса: что, если файла, к которому вы хотите применить патч, нет в репозитории git?

Это было полезно?

Решение

Если редактирование файла патча вручную исключено или невозможно, это можно сделать стандартными опциями (доступны в git apply, git format-patch и ГНУ patch).

  1. -p<n> удаляет n ведущие каталоги из путей в патче.

  2. После обработки -p, --directory=<root> добавляет root к каждому пути в патче перед применением.

Пример

Итак, для вашего примера взять патч, который изначально стоял на static/playdar.js и применить его к lib/playdar.js, вы бы запустили:

$ cat patch_file | git am     \ 
          -p1                 \ # remove 1 leading directory ('static/')
         --directory='lib/'     # prepend 'lib/'

Другие советы

Патч, созданный git format-patch это просто текстовый файл. Вы можете редактировать заголовки различий, чтобы изменить другой путь.

Например, это привело бы к чему-то вроде этого:

diff --git a/lib/playdar.js b/lib/playdar.js
index 1234567..89abcde
-- a/lib/playdar.js
++ b/lib/playdar.js

Все, что вам нужно сделать, это изменить lib/playdar.js к static/playdar.js а затем запустите патч через git am"

Патч должен быть доступен для чтения стандартной утилитой GNU patch для людей, у которых нет git--- но не беги format-patch с -M, -C и т. д.в этом случае можно создавать патчи переименования, поскольку их поддержка не является универсальной.

Если предположить, что оба проекта являются git-проектами, это звучит так: субмодули идеально подойдет вам.Это позволяет проекту git динамически связываться с другим проектом git, по сути, создавая репозиторий git прямо внутри другого репозитория git, причем оба имеют свою собственную жизнь.

Другими словами, добавьте «основное репо» в качестве подмодуля в «проект».Всякий раз, когда вы фиксируете/отправляете новый материал в «основной репозиторий», вы просто git pull их обратно в «проект».

Завершить Ответ Хенрика, и пойти за бонусным баллом

что, если файла, к которому вы хотите применить патч, нет в репозитории git?

Если у вас есть доступ к каталогам файла-кандидата для патча, поступающего из репозитория git, вы можете сначала преобразовать это дерево каталогов/файлов в сам репозиторий git!('git init':в конце концов, репозиторий git — это всего лишь .git в корневом каталоге).
Затем вы установите этот репозиторий в качестве подмодуля вашего основного проекта.

Вы можете добавить новый пульт и пользоваться им. Статья с подробностями.

$ cd <path-to-repoB>
$ git remote add repoA <git-URL-for-repoA>
$ git pull repoA

Я думаю, что поддерево - лучшее решение вашей проблемы

Урок 1

Туориал 2

Вы можете просто временно удалить (переименовать) основной репозиторий.

cd to/main/project
mv .git .git_
cd to/sub/project
git apply patchname
cd -
mv .git_ .git

Используя --relative возможность format-patch может улучшить абстракцию (скрыть ненужные сведения о репозитории, из которого был создан патч).

[repository-with-changes]
git format-patch --relative=(path-to-library) (base-commit-for-patch) ## 'HEAD~1'

Я нашел --3way опция, которая потребуется при применении патча (во избежание does not exist in index ошибка) – ваш пробег может отличаться.С использованием --directory=(...) вероятно, необходим только в том случае, если ваш целевой путь не является корнем репозитория.

[repository-to-update]
git am --3way --directory=(path-to-library) (patch-file)

  • format-patch создаст один файл патча для каждой фиксации в текущей ветке, начиная с «base».

  • Документация для --relative вариант кажется отсутствует в некоторых случаях, но, похоже, он все равно работает (начиная с версии 2.7.4).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top