Можно ли синхронизировать 2 похожих репозитория git с разными именами файлов? - PullRequest
1 голос
/ 02 февраля 2012

У нас есть 2 репозитория git, одно из которых мы предоставляем сторонней библиотеке, где мы хотим поделиться своими наборами изменений как частью истории git, но их имена файлов немного отличаются.

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

Примером того, что мы делаем, может быть: Скажем, в репо А (наш источник, с которым мы работаем изо дня в день) у нас есть такая структура:

module-x/
    module-x.js

В репо B (куда мы хотим скопировать наши коммиты) структура выглядит следующим образом:

gallery-module-x/
    gallery-module-x.js

(кроме того, в содержимом файлов есть и другие изменения в сценариях).

Есть ли способ скопировать историю и запустить сценарий для файлов, чтобы синхронизировать их (но сохранить изменения содержимого и сообщение о коммите, чтобы создать новый коммит в репо стороннего производителя)?

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

Любой совет? Заранее спасибо,

Ответы [ 2 ]

1 голос
/ 02 февраля 2012

Все, что вы делаете, будет довольно уродливым, так как Git на фундаментальном уровне знает, какими должны быть имена файлов. Дерево с разными именами файлов имеет другой SHA1, так что коммиты тоже делают, и ничто не будет совпадать. Это означает, что на GitHub на самом деле нет ничего разумного, так как необходимо много переписывать историю.

Есть две основные вещи, которые вы можете попробовать сделать.

One: используйте git filter-branch с древовидным или индексным фильтром, чтобы переписать всю историю в одном репо, переименовав файлы. Вы можете прочитать документацию или выполнить поиск в Интернете или здесь, чтобы найти примеры этого. В man-странице есть пример, который довольно близок к вашему варианту использования, последний в разделе примеров, который перемещает все файлы в подкаталог, делая это таким образом, который в основном эквивалентен удалению или добавлению префикса. Ваша версия может быть что-то вроде:

git filter-branch --index-filter \
               'git ls-files -s | sed "s/module-x/gallery-module-x/" |
                       GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
                               git update-index --index-info &&
                mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD

(Шаблон замены sed - это то место, где вам нужно быть осторожным.) Вы бы хотели запустить его в новом клоне, чтобы не переписывать ветви в исходном репо.

Если вы работаете в обоих репозиториях, для синхронизации потребуется много тщательной работы, чтобы избежать несоответствия между двумя репозиториями, и вам придется выполнить обратное преобразование, чтобы вернуть вещи в другую сторону. Но если открытый / общедоступный только для чтения, то эта опция замечательна; думайте о ветке фильтра как о предвестнике экспорта. Сохраните сценарий, чтобы сделать это, и все, что вам нужно сделать, это клонировать, разветвить фильтр и нажать.

Два: перенос патчей вручную. Вы можете использовать git format-patch <revision-range> для создания исправлений, затем выполнить автоматическую замену имен файлов в этих исправлениях, а затем применить их в другом хранилище. Это некрасиво, но работает.

Я полагаю, что вы могли бы запускать любую из этих вещей с помощью ловушки после фиксации локально, но они могут занимать больше времени, чем вы хотите, так как вы, вероятно, будете часто фиксировать и захотите двигаться немедленно. Еще один вариант, который, я полагаю, вы уже рассмотрели и отклонили по какой-то причине, заключается в том, чтобы использовать существующий сценарий, запущенный из ловушки после фиксации, для копирования / переименования файлов в другое хранилище и немедленной фиксации там. (Один коммит на коммит, а не один большой коммит на несколько коммитов.)

0 голосов
/ 02 февраля 2012

Если только git-репозиторий (каталог) имеет другое имя, вы можете упростить себе задачу, установив другой git remote: git remote add <their-remote> <git-remote-url>.Я надеюсь, что это так, потому что это гораздо более простой метод.

Однако, если имена файлов также различаются, но код в этих файлах одинаков, вы можете создать git patch и запуститьsed или другая команда find-replace, чтобы изменить имена файлов в этом одном файле исправления, а затем git apply исправление в другом хранилище.Это действительно может быть сделано с использованием хука post commit и скриптов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...