博客使用简单的Django框架,一直使用git管理整个项目的开发。 基于这个前提,如何保留尽量多的信息,将博客部分开源独立出去,独占一个仓库?
我验证了几种容易找到的方案,最终还是选择使用subtree
管理博客部分。
以下实验均在同一目录下进行,使用拉丁字母命名实验用的新仓库,每个仓库均 直接 clone自原仓库(c除外)。
最好使用clone来的新仓库,防止因原仓库有未追踪的文件而出现冲突,意外中止某些关键操作
“最好”的语气需要强烈,既然有着重提示,那么背后一定有部血泪史。
以下实验验证用subtree
分割出新的分支,并将分支提交到远程仓库,最后将远程仓库作为submodule
添加回本仓库。
# 初始化远程仓库
git init --bare /tmp/blog_a.git
git remote add blog_a /tmp/blog_a.git
# 分割出子目录blog并创建为blog分支
git subtree split -P blog -b blog
git push blog_a blog:master
# 先删除目录才能添加submodule
git rm -r blog
git submodule add /tmp/blog_a.git blog
git commit
以下实验验证可以在直接clone自原仓库的实验仓库b中添加实验仓库a分离出来的部分作为submodule
。
git rm -r blog
git submodule add /tmp/blog_a.git blog
以下实验练习clone和使用带有submodule
的仓库。
git clone b c
git submodule init
git submodule update
以下实验验证直接使用subtree
的功能,不使用submodule
。
git init --bare /tmp/blog_d.git
git remote add blog_d /tmp/blog_d.git
# 以下有两种方案
# 创建blog分支并合并入当前分支(--rejoin选项)
git subtree split -P blog --rejoin -b blog
git push blog_d blog:master
# 基本同样的操作,但是不会创建blog分支
git subtree push -P blog blog_d master
--rejoin
可以自己通过在master等原仓库分支使用git merge blog --allow-unrelated-histories
实现。
以下参考github上一篇帮助,使用重量级武器filter-branch
分割仓库。
https://help.github.com/en/articles/splitting-a-subfolder-out-into-a-new-repository
git checkout -b blog
git filter-branch --prune-empty --subdirectory-filter blog blog
# 查看git log,会有一个如下的残留引用
# refs/original/refs/heads/blog
# 这个好像无法避免
git init --bare /tmp/blog_e.git
git remote add blog_e /tmp/blog_e.git
git push -u blog_e master
此方法和使用subtree
(不带--rejoin
)一样的效果,一样的日志,可以直接使用subtree
分离出来的仓库作为远程仓库同步。
从以上参考的方法来看,分割方法主要为两种,使用subtree
的split
或者使用filter-branch
,两种方法无效果上的差别
(我猜subtree
的split
就是用filter-branch
实现的,以后验证)。
使用subtree
或者submodule
管理分割出来的分支就是比较灵活的事,二者使用上就见仁见智吧。