Как сделать часть существующего репозитория GIT подмодулем

У меня есть этот репозиторий git, который содержит две папки: binary-search и poker. Например, http://github.com/soulnafein/code-katas

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

Как я могу это сделать?

Ответ 1

Общая идея состоит в том, чтобы использовать git filter-branch ' и следующие шаги:

1) Создайте подмодуль с использованием --subdirectory-фильтра filter-branch (после клонирования вашего репо).

$ git filter-branch --subdirectory-filter ABC HEAD -- --all

См. этот вопрос SO для получения дополнительной информации об этом шаге.

2) Создайте суперпроект, используя индексный фильтр filter-branch, чтобы удалить подмодуль.

$ git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch ABC" --prune-empty HEAD

3) Соедините субмодуль с последней версией суперпроекта.

См. Отсоединить подкаталог в отдельный репозиторий git для практического примера.

Каждый подмодуль сохранит свою историю. Но, как сказано в этом патчевом предложении, оно:

теряют все исторические связи между суперпроектом и подмодулем, вызывая такие инструменты, как "git bisect" и затрудняет восстановление старых версий.

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

Если вам не нужно иметь предыдущую историю, связанную с новыми подмодулями, вы можете выполнить описанные выше действия.
Но если вам нужно перейти от более старой точки, имея ссылки на ваши подмодули (которые в настоящее время являются простыми подкаталогами), вы можете рассмотреть возможность использования script, упомянутого в патче, к которому я обращаюсь. Обсуждается в этот поток, но интегрирован в git, но, как говорит Юнио С Хамано:

К сожалению, я не думаю, что мы полностью разработали (или внедрили) поведение, чтобы проверить разные точки истории, которые имеют тот же подмодуль, перемещенный в дереве суперпроектов.

Ответ 2

Сегодня есть лучший способ сделать это: git subtree

См. этот ответ.