извлечение нескольких каталогов с помощью 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 - это хорошо. ;)

3 ответов


использовать

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 чтобы получить все изменения не добыто в первом запуске.


Update: при попытке ускорить работу с помощью --index-filter Я пришел к еще легче решение:

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

это просто удаляет все, а затем восстанавливает заданные каталоги после этого.


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

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

git branch br1
git branch br2

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

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


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

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