Подтвердить что ты не робот

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

У меня есть два репозитория, один из них является основным репо для библиотеки, а другой - проектом с использованием этой библиотеки.

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

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

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

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

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

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

4b9b3361

Ответ 1

Если ручное редактирование файла исправления не может быть и речи, это может быть сделано со стандартными опциями (доступно в 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/'

Ответ 2

Патч, созданный 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 на static/playdar.js, а затем запустить патч через git am"

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

Ответ 3

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

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

Ответ 4

Чтобы завершить ответ Хенрика, и перейти к бонусной точке

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

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

Ответ 5

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

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

Ответ 7

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

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

Ответ 8

Использование опции --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).