简单的方法™
事实证明,这是一种常见且有用的做法,Git 的统治者使它变得非常简单(在版本 1.7.11 - 2012 年 5 月中添加)。另外,还有一个现实世界的例子 in the 演练 below.
-
准备旧仓库
cd <big-repo>
git subtree split -P <name-of-folder> -b <name-of-new-branch>
Note: <name-of-folder>
不得包含前导或尾随字符。例如,名为的文件夹subproject
必须传递为subproject
, NOT ./subproject/
Note: <name-of-new-branch>
是您将在现有/旧存储库中创建的分支,NOT新的[稍后出现]。
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 <[email protected] /cdn-cgi/l/email-protection:user/new-repo.git>
git push -u origin master
-
内部清理<big-repo>
, 如果需要的话
git rm -rf <name-of-folder>
Note:这会将所有历史参考文献保留在存储库中。请参阅Appendix如果您确实担心提交密码或者需要减小您的文件大小,请按以下步骤操作:.git
folder.
演练
这些是与上面相同的步骤,但是按照我的存储库的确切步骤而不是使用<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 [email protected] /cdn-cgi/l/email-protection:node-browser-compat/btoa.git
git push -u origin master
快乐的一天!
Note:如果您创建了一个带有README.md
, .gitignore
and LICENSE
,你需要先拉:
git pull origin master
git push origin master
最后,我想从更大的存储库中删除该文件夹
git rm -rf btoa
清除您的历史记录
默认情况下,从 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 等删除历史记录),您需要删除存储库并重新推送存储库的修剪副本。可是等等 -还有更多! - 如果您真的担心删除密码或类似的东西,您需要修剪备份(见下文)。
Making .git
smaller
前面提到的删除历史命令仍然会留下一堆备份文件 - 因为 Git 非常友善地帮助您避免意外破坏您的存储库。它最终会在数天和数月内删除孤立的文件,但会将它们保留一段时间,以防您意识到不小心删除了您不想删除的内容。
所以如果你真的想清空垃圾 to 减小克隆大小立即创建一个仓库,你必须做所有这些非常奇怪的事情:
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
也就是说,我建议不要执行这些步骤,除非您知道需要这样做 - 以防万一您确实修剪了错误的子目录,您知道吗?当您推送存储库时,备份文件不应被克隆,它们只会位于您的本地副本中。
Credit
- http://psionides.eu/2010/02/04/sharing-code- Between-projects-with-git-subtree/ http://psionides.eu/2010/02/04/sharing-code-between-projects-with-git-subtree/
- 从 git 中永久删除目录 https://stackoverflow.com/questions/1216733/remove-a-directory-permanently-from-git
- http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/ http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/
- 如何从我的 Git 存储库中删除未引用的 blob https://stackoverflow.com/questions/1904860/how-to-remove-unreferenced-blobs-from-my-git-repo