Легкий путь ™
Оказывается, это настолько распространенная и полезная практика, что повелители Git сделали это действительно легко, но вам нужно иметь более новую версию Git (> = 1.7.11, май 2012). Смотрите приложение о том, как установить последнюю версию Git. Кроме того, есть реальный пример в пошаговом руководстве ниже.
Подготовьте старый репо
cd <big-repo>
git subtree split -P <name-of-folder> -b <name-of-new-branch>
Примечание: <name-of-folder>
НЕ должно содержать начальных или конечных символов. Например, папка с именем subproject
ДОЛЖНА быть передана как subproject
, НЕ./subproject/
Примечание для пользователей Windows: если глубина вашей папки> 1, <name-of-folder>
должен иметь разделитель папок в стиле * nix (/). Например, папка с именем path1\path2\subproject
ДОЛЖНА быть передана какpath1/path2/subproject
Создать новый репо
mkdir ~/<new-repo> && cd ~/<new-repo>
git init
git pull </path/to/big-repo> <name-of-new-branch>
Свяжите новый репо с GitHub или где угодно
git remote add origin <git@github.com:user/new-repo.git>
git push -u origin master
Очистка внутри <big-repo>
, при желании
git rm -rf <name-of-folder>
Примечание . Это оставляет все исторические ссылки в хранилище. См. Приложение ниже, если вы действительно обеспокоены тем, что зафиксировали пароль, или вам необходимо уменьшить размер файла вашей .git
папки.
...
Прохождение
Это те же шаги, что и выше , но следуйте моим точным шагам для моего репозитория вместо использования <meta-named-things>
.
Вот мой проект по реализации модулей браузера JavaScript в узле:
tree ~/node-browser-compat
node-browser-compat
├── ArrayBuffer
├── Audio
├── Blob
├── FormData
├── atob
├── btoa
├── location
└── navigator
Я хочу разделить одну папку btoa
, в отдельный репозиторий Git
cd ~/node-browser-compat/
git subtree split -P btoa -b btoa-only
Теперь у меня есть новая ветка, для btoa-only
которой есть только коммиты, btoa
и я хочу создать новый репозиторий.
mkdir ~/btoa/ && cd ~/btoa/
git init
git pull ~/node-browser-compat btoa-only
Затем я создаю новый репозиторий на GitHub или Bitbucket, или как угодно, и добавляю его как origin
git remote add origin git@github.com:node-browser-compat/btoa.git
git push -u origin master
Счастливый день!
Примечание: Если вы создали репо с микросхемой README.md
, .gitignore
и LICENSE
, вам нужно будет тянуть первым:
git pull origin master
git push origin master
Наконец, я хочу удалить папку из большего репо
git rm -rf btoa
...
аппендикс
Последний Git на macOS
Чтобы получить последнюю версию Git с помощью Homebrew :
brew install git
Последний Git на Ubuntu
sudo apt-get update
sudo apt-get install git
git --version
Если это не работает (у вас очень старая версия Ubuntu), попробуйте
sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git
Если это все еще не работает, попробуйте
sudo chmod +x /usr/share/doc/git/contrib/subtree/git-subtree.sh
sudo ln -s \
/usr/share/doc/git/contrib/subtree/git-subtree.sh \
/usr/lib/git-core/git-subtree
Спасибо rui.araujo из комментариев.
Очистка вашей истории
По умолчанию удаление файлов из Git фактически не удаляет их, а просто подтверждает, что их больше нет. Если вы хотите на самом деле удалить исторические ссылки (т.е. у вас есть подтвержденный пароль), вам нужно сделать это:
git filter-branch --prune-empty --tree-filter 'rm -rf <name-of-folder>' HEAD
После этого вы можете проверить, что ваш файл или папка больше не отображаются в истории Git
git log -- <name-of-folder> # should show nothing
Тем не менее, вы не можете «нажать» удаления на GitHub и тому подобное. Если вы попытаетесь, вы получите ошибку, и вам придется, git pull
прежде чем вы сможетеgit push
- и тогда вы вернетесь к тому, чтобы иметь все в своей истории.
Поэтому, если вы хотите удалить историю из «источника» - то есть удалить ее из GitHub, Bitbucket и т. Д. - вам необходимо удалить репо и повторно нажать на сокращенную копию репо. Но подождите - это еще не все ! - Если вы действительно хотите избавиться от пароля или чего-то в этом роде, вам потребуется удалить резервную копию (см. Ниже).
Делая .git
меньше
Вышеупомянутая команда удаления истории все еще оставляет кучу файлов резервных копий - потому что Git слишком любезен, чтобы помочь вам не испортить репо случайно. В конечном итоге он удалит потерянные файлы в течение нескольких дней и месяцев, но на некоторое время оставит их там, если вы поймете, что случайно удалили то, что не хотели.
Поэтому, если вы действительно хотите очистить корзину, чтобы сразу же уменьшить размер клона репо, вы должны сделать все эти действительно странные вещи:
rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune=now
git reflog expire --all --expire-unreachable=0
git repack -A -d
git prune
Тем не менее, я бы порекомендовал не выполнять эти шаги, если вы не знаете, что вам нужно - просто на тот случай, если вы удалили неправильный подкаталог, понимаете? Файлы резервных копий не должны быть клонированы, когда вы нажимаете репо, они просто будут в вашей локальной копии.
кредит
git filter-branch
см. Мой ответ ниже.