Извлечение нескольких каталогов с помощью 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