Один із способів зробити це зворотним - видаліть усе, крім файлу, який ви хочете зберегти.
В основному, зробіть копію сховища, потім використовуйте 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-здійснює , виправляє це ..
git filter-branch --commit-filter 'if [ z$1 = z`git rev-parse $3^{tree}` ]; then skip_commit "$@"; else git commit-tree "$@"; 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 "$@"; else git commit-tree "$@"; fi'