Довольно часто бывает, что вы пишете какой-то проект, и через некоторое время становится ясно, что какой-то компонент проекта действительно полезен как отдельный компонент (например, библиотека). Если у вас с самого начала возникла эта идея, то есть большая вероятность, что большая часть этого кода находится в отдельной папке.
Есть ли способ преобразовать один из подкаталогов в проекте Git в подмодуль?
В идеале это должно происходить так, чтобы весь код в этом каталоге был удален из родительского проекта, а проект подмодуля был добавлен на его место со всей соответствующей историей, и так, чтобы все фиксации родительского проекта указывали на правильные фиксации подмодуля. ,
git
git-submodules
naught101
источник
источник
Ответы:
Чтобы изолировать подкаталог в его собственном репозитории, используйте
filter-branch
клон исходного репозитория:Это не что иное, как удаление исходного каталога и добавление подмодуля в родительский проект.
источник
git remote rm <name>
после ветки фильтра, а затем, возможно, добавить новый пульт. Также, если есть игнорируемые файлы,git clean -xd -f
может быть полезен-- --all
можно заменить на имя ветки, если подмодуль должен быть извлечен только из этой ветки.git clone <your_project> <your_submodule>
только скачивать файлы для your_submodule?git clone source destination
просто сообщает Git расположение, куда поместить ваши клонированные файлы. На этомfilter-branch
шаге происходит настоящая магия фильтрации файлов вашего подмодуля .filter-branch
в настоящее время устарела . Вы можете использоватьgit clone --filter
, но ваш сервер Git должен быть настроен на фильтрацию, иначе вы получитеwarning: filtering not recognized by server, ignoring
.Сначала измените каталог на папку, которая будет подмодулем. Затем:
источник
Я знаю, что это старый поток, но ответы здесь сводят на нет любые связанные коммиты в других ветках.
Простой способ клонировать и сохранить все эти дополнительные ветки и коммиты:
1 - Убедитесь, что у вас есть этот псевдоним git
2 - Клонируйте пульт, вытяните все ветки, смените пульт, отфильтруйте каталог, нажмите
источник
Это можно сделать, но это непросто. Если вы ищете
git filter-branch
,subdirectory
иsubmodule
есть несколько достойных рецензий на этот процесс. По сути, это влечет за собой создание двух клонов вашего проекта с использованиемgit filter-branch
для удаления всего, кроме одного подкаталога, в одном и удаления только этого подкаталога в другом. Затем вы можете установить второй репозиторий как подмодуль первого.источник
Статус кво
Давайте предположим , что у нас есть хранилище под названием ,
repo-old
который содержит вспомогательный каталогsub
, который мы хотели бы преобразовать в суб модуль со своим собственным репоrepo-sub
.Кроме того, предполагается, что исходное репо
repo-old
должно быть преобразовано в модифицированное репо,repo-new
где все коммиты, касающиеся ранее существовавшего подкаталогаsub
, теперь будут указывать на соответствующие коммиты нашего извлеченного репо подмодуляrepo-sub
.Давай меняться
Этого можно добиться с помощью
git filter-branch
двухэтапного процесса:repo-old
вrepo-sub
(уже упоминалось в принятом ответе )repo-old
наrepo-new
(с правильным сопоставлением фиксации)Замечание : я знаю, что этот вопрос старый, и уже упоминалось, что
git filter-branch
он устарел и может быть опасен. Но, с другой стороны, это может помочь другим с личными репозиториями, которые легко проверить после преобразования. Так что будьте осторожны ! И, пожалуйста, дайте мне знать, есть ли другой инструмент, который делает то же самое, но не является устаревшим и безопасен в использовании!Я объясню, как я реализовал оба шага в linux с git версии 2.26.2 ниже. Старые версии могут работать в некоторой степени, но это необходимо протестировать.
Для простоты я ограничусь случаем, когда в исходном репо есть только
master
ветка иorigin
пультrepo-old
. Также имейте в виду, что я полагаюсь на временные теги git с префиксом,temp_
которые будут удалены в процессе. Итак, если уже есть теги с одинаковыми именами, вы можете изменить префикс ниже. И, наконец, имейте в виду, что я тщательно не тестировал это, и могут быть крайние случаи, когда рецепт не работает. Поэтому, пожалуйста, сделайте резервную копию всего, прежде чем продолжить !Следующие ниже фрагменты bash можно объединить в один большой скрипт, который затем должен быть выполнен в той же папке, где находится репо
repo-org
. Не рекомендуется копировать и вставлять все прямо в командное окно (хотя я успешно это протестировал)!0. Подготовка
переменные
Скрипт фильтра
1. Извлечение подкаталога
2. Замена подкаталога
Примечание: если вновь созданное репо
repo-new
зависает во время,git submodule update --init
попробуйте вместо этого рекурсивно повторно клонировать репозиторий:источник
Это выполняет преобразование на месте, вы можете вернуть его, как и любую ветвь фильтра (я использую
git fetch . +refs/original/*:*
).У меня есть проект с
utils
библиотекой, которая начала быть полезной в других проектах, и я хотел разделить ее историю на подмодули. Не подумал сначала взглянуть на SO, поэтому я написал свой собственный, он создает историю локально, так что это намного быстрее, после чего, если вы хотите, вы можете настроить.gitmodules
файл вспомогательной команды и тому подобное, и протолкнуть сами истории подмодулей куда угодно вы хотите.Сама команда с разделением находится здесь, документ в комментариях, в следующем разделе без разделов. Запустите его как отдельную команду с
subdir
set, какsubdir=utils git split-submodule
если бы вы разделялиutils
каталог. Это хакерский метод, потому что он разовый, но я тестировал его в подкаталоге Documentation в истории Git.источник