在Stack Overflow上搜索了这个问题。发现了这个较旧的帖子,似乎没有给出任何答案。重新启动该帖子,希望有人知道!
有人可以告诉我git subtree和git filter-branch之间的区别吗? 我将为此使用原始问题中的相同示例:
git subtree split --prefix=some_subdir -b some_branch
git filter-branch --subdirectory-filter some_subdir some_branch
在Stack Overflow上搜索了这个问题。发现了这个较旧的帖子,似乎没有给出任何答案。重新启动该帖子,希望有人知道!
有人可以告诉我git subtree和git filter-branch之间的区别吗? 我将为此使用原始问题中的相同示例:
git subtree split --prefix=some_subdir -b some_branch
git filter-branch --subdirectory-filter some_subdir some_branch
2016年:是的,git subtree
(一个contrib/
shell)可以用于拆分存储库,如Stu Campbell所描述的“使用Git subtrees进行存储库分离”。
不过,您需要删除在拆分文件夹中重复的代码(另请参见theamk的答案):
git subtree split --prefix=path/to/code -b split
git push ~/shared/ split:master
git rm -r path/to/code
git commit -am "Remove split code."
与原生 Git 命令 git filter-branch
不同,它会重写存储库历史记录,仅选择实际影响特定子目录内容的提交。
意思是一旦运行了 filter-branch
,就没有代码可以使用 git rm
。
git filter-branch
不像 git subtree split
一样复制提交记录:它删除(“过滤掉”)所有不符合某个条件的内容(这里是子文件夹路径)。
同样,有关更新,请参见 theamk 的 answer:在使用新分支时不会出现重复: git subtree split --prefix=some_subdir -b some_branch
。
2021年更新:
使用 git switch some_branch
或 git switch -c some_branch
,而不是 旧的且令人困惑的 git checkout
命令。
考虑使用 新的和改进的 git filter-repo
, 因为 git filter-branch
和 BFG
已正式过时。
(参见 git filter-branch
手册页面)
git filter-repo
可以 提取所需路径及其历史记录(剥离其他所有内容)。
git switch -c some_branch
git filter-repo --path some_subdir/ --refs some_branch
当按照原样执行时,差异非常小:
HEAD
开始,并将结果放入some_branch
中,该分支以前不能存在some_branch
开始,并将结果放回some_branch
,用新内容覆盖some_branch
换句话说,只要没有找到特殊的subtree rejoin
提交,下面的两个代码片段完全相等。
git subtree split --prefix=some_subdir -b some_branch
git checkout some_branch
并且
git checkout -b some_branch
git filter-branch --subdirectory-filter some_subdir some_branch
--rejoin
和--onto
选项。
git filter-branch
的注意事项不适用于此用例,因为我们不提供任何shell命令,也不会触及标签。 - theamk