12

我正在使用 git-subtree(来自 Avery Pennarun)。在我当前的 git repo 中,我当然有我所有的项目文件/文件夹和一个名为“lib”的子树。如果我现在使用克隆这个 git存储库,git clone我会得到所有项目文件和子树“lib”(应该是一切)。我现在尝试的是:我在克隆的仓库中更改了子树“lib”中的某些内容,并尝试使用 将更改推送回子树“lib”的远程仓库 git subtree push,但它没有用。问题是什么?我是否必须先使用 git subtree add 将其添加为子树?

提前谢谢

4

2 回答 2

21

免责声明,我怀疑我只比你早几天了解子树:-)

如果您只是在使用git subtree push,那么您没有提供足够的信息来提取和推送您的更改。

如果您正确克隆了 repo,则子树将已经存在。子树需要被告知你想从哪个子树推送(即使你只有一个),它还需要知道推送到哪里——具体来说,你不想推送到顶级仓库。因此,你想要这样的东西:

git subtree push --prefix=lib git@github.com:arges-github/lib.git master

显然,应该更改 repo 和 refspec 以匹配您的 repo。

如果您想查看这里发生的事情(它确实有帮助),子树实际上会将影响子树内文件的更改拆分到不同的分支,然后将其推送到子树存储库。要看到这种情况发生,请使用subtree split

git subtree split --rejoin --branch=shared-changes --prefix=lib

然后看看你所做的分支:

git checkout lib-changes

并且,手动推动它们

git push git@github.com:arges-github/lib.git master

如果这不起作用,则可能是您尚未将子树合并到您的存储库中。添加子树时:

 git subtree add --squash --prefix lib git@github.com:arges-github/lib.git master

您还需要合并子树并将其推回您的顶级仓库。

 git subtree pull --squash --prefix lib git@github.com:arges-github/lib.git master
 git push
于 2012-10-10T12:56:42.533 回答
1

我遇到了与您完全相同的问题,我基本上使用 Roger Nolan 建议的方法解决了它。但是,如果您不幸像我一样使用不区分大小写的文件系统,您还必须确保每次执行拉取和推送时,前缀的大小写保持不变。

当您最终错误地混淆了大小写时,git 会认为您有两个子树,而文件系统上只存在一个。

所以我最终得到的解决方案(以防它帮助任何人)是:

  1. 创建一个将推送您的子树的脚本。调用它publish_<your-subtree-name>
  2. 创建另一个脚本来拉取您的子树。调用它update_<your-subtree-name>
  3. 在您的 HEAD 创建一个临时分支并测试更新。如果您的脚本是正确的,您的临时分支将不会移动。
  4. 在别处克隆子树存储库,添加测试提交,推送它并尝试使用您刚刚编写的更新脚本将其拉入您的存储库。
  5. 如果一切正常,请删除您的临时分支,然后将两个脚本签入超级项目存储库。
  6. 然后,每当您需要推送或拉取子树时,请使用脚本。

PS> --squash 参数很重要,特别是如果您的存储库的不同分支正在拉取子树的不同分支,并且如果您的项目中有多个子树。

于 2014-12-03T00:33:55.110 回答