Один из способов сделать это - инвертировать - удалить все, кроме файла, который вы хотите сохранить.
В основном, сделайте копию репозитория, затем используйте git filter-branch
, чтобы удалить все, кроме файла/папок, которые вы хотите сохранить.
К примеру, у меня есть проект, из которого я желаю, чтобы извлечь файл tvnamer.py
в новое хранилище:
git filter-branch --tree-filter 'for f in *; do if [ $f != "tvnamer.py" ]; then rm -rf $f; fi; done' HEAD
, который использует git filter-branch --tree-filter
пройти каждый коммит, выполнить команду и вновь полученное содержимое каталогов , Это крайне разрушительно (так что вы должны делать это только на копии вашего репозитория!), И может занять некоторое время (около 1 минуты в репозитории с 300 коммитов и около 20 файлов)
Вышеупомянутая команда запускает следующая оболочка-скрипт на каждой версии, которую вы должны были бы изменить, конечно (чтобы исключить ваш подкаталог вместо tvnamer.py
):
for f in *; do
if [ $f != "tvnamer.py" ]; then
rm -rf $f;
fi;
done
Самый большой очевидной проблемой является то, что оставляет все сообщения фиксации, даже если они не связаны с остальным файлом. Сценарий git-remove-empty-commits, фиксирует это ..
git filter-branch --commit-filter 'if [ z$1 = z`git rev-parse $3^{tree}` ]; then skip_commit "[email protected]"; else git commit-tree "[email protected]"; fi'
Вы должны использовать -f
силы аргумент запустить filter-branch
снова что-нибудь в refs/original/
(который в основном резервное копирование)
Конечно, это никогда не будет совершенным, например, если в ваших сообщениях фиксации упоминаются другие файлы, но это примерно так, как это делает git current (насколько мне известно в любом случае).
Опять же, только запустите это на копии вашего хранилища! - но в целом, чтобы удалить все файлы, но «thisismyfilename.txt»:
git filter-branch --tree-filter 'for f in *; do if [ $f != "thisismyfilename.txt" ]; then rm -rf $f; fi; done' HEAD
git filter-branch -f --commit-filter 'if [ z$1 = z`git rev-parse $3^{tree}` ]; then skip_commit "[email protected]"; else git commit-tree "[email protected]"; fi'
Также очень хороший ответ: http://stackoverflow.com/questions/359424/detach-subdirectory-into-separate-git-repository –