Извлечение нескольких каталогов с помощью git -filter-branch

У меня есть большой репозиторий, который в настоящее время содержит несколько проектов в подпапках верхнего уровня, например /a, /b, /c и /d.

Теперь я хочу разбить этот репозиторий на два разных репозитория: один, содержащий /a и /b, а другой - /c и /d.

Я знаю git filter-branch --subdirectory-filter, который идеально подходит для извлечения одного каталога, но, похоже, он не может сразу извлекать несколько каталогов.

Я также знаю, что git filter-branch --prune-empty --tree-filter, который позволит мне удалить все, но два требуемых каталога. Это не совсем правильно, так как я должен вручную указывать все файлы верхнего уровня, которые могут существовать.

Есть ли лучший способ извлечь два каталога из большого репозитория?

PS: Конечно, любое хорошее решение, использующее что-то отличное от git filter-branch, прекрасно.;)

Ответы

Ответ 1

Использование

git filter-branch -f --prune-empty --tree-filter 'bash preserve-only.sh a b' -- --all

где preserve-only.sh:

IFS=':'
GLOBIGNORE="$*"
rm -rf *

Это должно удалить все, кроме a и b, из всех коммитов всех ветвей, что должно быть таким же, как извлечение именно указанных каталогов.

Чтобы завершить фактическое разделение, вы можете использовать фильтр типа rm -rf a b, чтобы получить все изменения, не извлеченные в первом прогоне.


Обновление: при попытке ускорить работу с помощью --index-filter я пришел к еще более простому решению:

git filter-branch -f --prune-empty --index-filter \
  'git rm --cached -r -q -- . ; git reset -q $GIT_COMMIT -- a b' -- --all

Это просто удаляет все и впоследствии восстанавливает данные каталоги.

Ответ 2

Я не знаю лучшего способа, чем tree-filter для этого. Таким образом, у вас уже есть вся необходимая информация. Теперь просто сделай это!

Начните с создания двух ветвей:

git branch br1
git branch br2

Теперь для каждой ветки проверьте его, затем отфильтруйте его с помощью tree-filter.

Затем вы можете разделить их на отдельные каталоги либо путем их выталкивания, либо путем клонирования или потянув их.

Ответ 3

Я предпочитаю это

git filter-branch -f --prune-empty --tree-filter "ls -I a -I b | xargs rm -rf"  -- --all