Easy Way™
事实证明,这是一种通用且有用的做法,Git的霸主确实使这变得非常容易,但是您必须拥有更新版本的Git(> = 2012年5月1.7.11)。有关如何安装最新版本的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
MUST 的文件夹必须以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>
。
这是我要在node中实现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
...
附录
macOS上的最新Git
要使用Homebrew获得最新版本的Git :
brew install git
Ubuntu上的最新Git
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
小
前面提到的delete history命令仍然留下了许多备份文件-因为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
请参阅下面的答案。