Как применить патч git из одного репозитория в другой?
у меня есть два репозитория, один из которых является основным РЕПО для библиотеки, а другой-проект, использующий эту библиотеку.
если я сделаю исправление в проекте subservient, я хотел бы простой способ применить этот патч обратно вверх по течению.
расположение файла отличается в каждом репозитории.
- Главная РЕПО:
www.playdar.org/static/playdar.js
:
playlick.com/lib/playdar.js
Я попытался с помощью git format-patch -- lib/playdar.js
в проекте playlick, а затем git am
на основном РЕПО playdar, но различные местоположения файлов в файле патча вызвали ошибку.
есть ли простой способ применить патч из данной фиксации в данном файле к другому произвольному файлу в другом месте?
для бонусных очков, что делать, если файл, к которому вы хотите применить патч, не находится в репозитории git?
8 ответов
если ручное редактирование файла исправления невозможно или невозможно, это можно сделать со стандартными параметрами (доступно в git apply
, git format-patch
и GNU patch
).
-p<n>
выводитn
ведущие каталоги из путей в патче.после обработки
-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, чтобы он изменял другой путь.
так, например, он выдавал что-то вроде этого:
diff --git a/lib/playdar.js b/lib/playdar.js
index 1234567..89abcde
-- a/lib/playdar.js
++ b/lib/playdar.js
все, что вам нужно сделать, это изменить lib/playdar.js
to static/playdar.js
а затем запустите патч через git am"
патч должен читаться стандартной утилитой GNU patch для людей, у которых нет git
--- но не работать format-patch
С -M
, -C
так далее. опции для создания патчей переименования в этом случае, потому что поддержка для них не является универсальной.
предполагая, что оба проекта являются проектами git, это звучит так подмодулей будет идеально подходит для вас. Это позволяет проекту git динамически связываться с другим проектом git, по сути, выпекая git-РЕПО прямо внутри другого git-РЕПО, оба имеют свою собственную жизнь.
другими словами, добавьте " main repo "в качестве подмодуля в"project". Всякий раз, когда вы совершаете/нажимаете новые вещи в "главном РЕПО", вы просто git pull
их обратно в "проект".
завершить ответ Хенрика, и пойти на бонусный балл
что делать, если файл, к которому вы хотите применить патч, не находится в репозитории git?
Если у вас есть доступ к каталогам кандидата в файл для патча идет из репозитория Git, вы можете сначала преобразовать это дерево каталогов/файлов в Git-репозиторий! ('git init
': репозиторий git-это просто a .git в корневом каталоге все-таки).
Затем вы бы установили это РЕПО в качестве подмодуля для своего основного проекта.
вы можете добавить новый пульт и вытащить из него. статья с подробностями.
$ cd <path-to-repoB>
$ git remote add repoA <git-URL-for-repoA>
$ git pull repoA
вы можете просто временно удалить (переименовать) основной репозиторий.
cd to/main/project
mv .git .git_
cd to/sub/project
git apply patchname
cd -
mv .git_ .git
С помощью до 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".документация Кажется в некоторых случаях, но он все равно работает (начиная с версии 2.7.4).