我有一个相当大的git存储库,它有一个我维护库代码的目录。该目录包含许多子目录。
repo
+--- lib
| +--- A
| +--- B
...
| +--- Z
现在让我们假设我想开源子目录A,...,M
并保持子目录N,...,Z
close sourced。我们还假设我想:
A,...,M
保存在一个开源存储库中。原因是目录A,...,M
具有相互依赖性,将它们分成单独的存储库会很困惑。lib/pub
和lib/pvt
,但这会产生级联效果,需要在其他地方更改引用,或者需要大量的符号链接(lib/A -> lib/pub/A
)。git subtree
的解决方案,我可以在我的封闭源代码库或开源代码库中修改代码,我可以轻松地同步两个存储库之间的更改。我已经在stackoverflow和google中搜索了一个解决方案,但似乎没有明显的解决方案。从概念上讲,这是git subtree
应该能够做到的事情,但它只适用于单个子目录。
我已经查看了git-subtree
脚本,目的是修改它。
https://github.com/git/git/blob/master/contrib/subtree/git-subtree.sh
在我看来,如果我要修改subtree_for_commit()
,我应该能够说服git subtree split
考虑不止一个目录进行拆分。但是我对git的了解还不足以理解脚本正在做什么并在不破坏事情的情况下修改它。
如果您对上述问题有任何解决方案或修改git-subtree
的任何其他指示,请告诉我。
这似乎是一个常见的请求,但是当文件夹混合在一起时,我不认为有一个简单的答案。
我建议拆分与其他文件夹混合的库的一般方法是:
git subtree split -P lib/ -b temp-br
git checkout temp-br
git filter-branch --tag-name-filter cat --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch N O P Q R S T U V W X Y Z' HEAD
注意:如果您执行连续命令,则可能需要删除filter-branch所做的备份。
git update-ref -d refs/original/refs/heads/temp-br
cd <new-lib-repo>
git init
git pull <original-repo> temp-br
这是一个基于git subtree
的shell脚本,它比基于git filter-branch --tree-filter
的解决方案快得多;它的副作用是几个额外的git mv
和git merge
提交将生成并添加到最终的HEAD
。如果您对这些额外的空提交感觉不错,可以尝试:
ids=0
lists=(\
"a/b" \
"c/d/e" \
)
# subtree each path
for dir in ${lists[@]}
do
echo git subtree split -P $dir -b split_dir_$ids
git subtree split -P $dir -b split_dir_$ids
((ids++))
done
# restore folder structure
for (( idx=0; idx < ${#lists[@]}; idx++ ))
do
git checkout split_dir_$idx
dir=${lists[$idx]}
mkdir -p $dir
dirPrefix=${$dir%%/*}
find . -maxdepth 1 ! -name $dirPrefix -and ! -name '\.*' \
-exec git mv {} $dir \;
done
# merge
git checkout split_dir_0
for (( idx=1; idx < ${#lists[@]}; idx++ ))
do
git merge -q split_dir_$idx
done
git push -u `target remote` `target branch`
当你在目录src中同时拥有子目录和文件时,你想要拆分成一个单独的存储库,后来成为一个子模块,答案就不多了。假设您希望dir2和file2移动到新的repo srcpublic然后在原始仓库中,
git mv src / file2 src / dir2; git subtree split -P dir2 -b branch_dir2
在新的repo中,子树pull / dir2 branch_dir2; git mv dir2 / file2 ../
新的回购:srcpublic - file2,dir2
原始仓库:src - file1,file2,dir1,dir2
当有许多文件夹和文件时,将命令放在脚本中会很有帮助。