【问题标题】:Difference between git filter branch and git subtree?git过滤器分支和git子树之间的区别?
【发布时间】:2016-12-08 16:19:13
【问题描述】:

正在寻找 throw SO 来寻找答案。遇到了这个似乎没有给出任何答案的旧线程。重新触发此线程希望有人可能知道!

有人能告诉我 git subtree 和 git filter-branch 的区别吗? 为此,我将在原始问题中使用相同的示例:

git subtree split --prefix=some_subdir -b some_branch

git filter-branch --subdirectory-filter some_subdir some_branch

【问题讨论】:

    标签: git git-subtree git-filter-branch


    【解决方案1】:

    2016:是的,git subtreecontrib/ shell)可用于拆分存储库,如 Stu Campbell 的“Using Git subtrees for repository separation”中所述。

    您需要删除在拆分文件夹中复制的代码,(另请参阅theamkanswer):

    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 filter-branch(一个原生 Git 命令)不同,后者会重写 repo 历史记录,只选择那些实际影响特定子目录内容的提交。

    含义:一旦filter-branch 运行,git rm 就没有代码了。
    git filter-branch 不会重复提交git subtree split 那样:它删除(“过滤器out") 不符合特定标准的所有内容(此处为子文件夹路径)。
    同样,请参阅 theamkanswer 以获取更新:使用新分支时没有重复:git subtree split --prefix=some_subdir -b some_branch


    2021 年更新:

    git filter-repo 可以extract wanted paths and their history(剥离其他所有内容)

     git switch -c some_branch
     git filter-repo --path some_subdir/ --refs some_branch
    

    【讨论】:

    • 这是不准确的,因为 git subtree 现在是 git 的官方部分
    • 不同之处还意味着如果你有几个(n)个子文件夹,你想让它们各自成为他自己的仓库,使用 git filter-branch 你需要先克隆 n 次,使用子树你需要git rm n 次。
    • 那个答案不正确!如果您使用“git branch”或“git checkout -b”复制分支,那么您不需要“克隆n次”并且您有一个可以“git rm”进入的分支。只需执行“ git checkout”推送到原来的分支。
    • @theamk 感谢您的更新。请注意,在 2021 年:git checkout 已过时并替换为 git switchgit filter-branch 已过时并替换为git filter-repo(我已经编辑了自己的答案以使其更清楚)。您的回答非常好,并且得到了支持。
    • 如果有可用的第三方工具(“git filter-repo”),我会犹豫不决。特别是因为git filter-branch 的大多数警告不适用对于这个用例,因为我们不提供任何 shell 命令,也不接触标签。
    【解决方案2】:

    按书面执行时,差异很小:

    • 您的“子树拆分”命令将从HEAD 开始,并将结果放入some_branch,之前不得存在
    • 您的“filter-branch”命令将以some_branch 开头,并将结果放回some_branch,用新内容覆盖some_branch
    • 在我的测试中,“git filter-branch”的速度提高了约 50 倍(在一个非常旧的 repo 上,只有几个提交触及所选路径)

    换句话说,只要没有找到特殊的subtree rejoin 提交,下面的两个sn-ps 是完全等价的。

    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
    

    你可能会问,为什么还要使用“git subtree”呢?对于--rejoin--onto 选项——它们支持原始作者使用的非常具体的工作流程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-19
      • 2012-04-18
      • 1970-01-01
      • 2017-12-23
      • 2015-10-24
      • 1970-01-01
      • 2011-09-18
      • 2010-10-09
      相关资源
      最近更新 更多