git-subtree: 从克隆的仓库推送更改

16
我正在使用git-subtree(来自Avery Pennarun)。在我的当前git repo中,我当然有所有的项目文件/文件夹和一个名为“lib”的子树。如果我现在使用git clone克隆这个git repo,我会得到所有的项目文件和子树“lib”(一切正常)。
现在我尝试了这样一件事:在克隆的repo中更改了子树“lib”中的内容,然后尝试使用git subtree push将更改推送回子树“lib”的远程repo,但它不起作用。问题出在哪里?我需要首先使用git subtree add将其添加为子树吗?
提前感谢。

你是如何将子树添加到顶级项目中的?你只是创建了一个目录并克隆到其中吗? - Rog
你好!我使用 "git subtree add" 将子树添加到我的顶级项目中。也许我的问题不够清晰:如果我在另一台机器上克隆仓库,那么我就拥有了所有项目文件以及子树 "lib"。现在,在克隆的仓库中更改子树 "lib" 中的某些内容后,我无法使用 "git subtree push" 将更改推送回远程服务器,这是我的问题。 - arge
嗨,罗杰!抱歉我回复晚了,我休息了几天。你的答案解决了我的问题,非常感谢你。正如你在答案中提到的,我刚开始学习如何使用git子树。 - arge
2个回答

23

免责声明,我怀疑我比你早学习subtree几天 :-)

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

如果你正确地克隆了仓库,则subtree已经在其中。Subtree需要告诉你想要从哪个子树推送(即使你只有一个子树),它还需要知道要推送到哪里 - 具体而言,你不想推送到顶级仓库。因此,你需要像这样做:

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

显然,仓库和refspec应该被更改以匹配您的仓库。

如果您想了解正在发生的事情(这确实有帮助),subtree实际上将影响子树内文件的更改拆分到不同的分支中,然后将其推送到子树仓库。 要查看此过程,请使用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

1
我已经执行了“add”步骤,但没有找到任何文档表明需要随后进行“pull”。如果在“add”之后未执行初始的第一个“pull”,会发生什么?我面临的问题是,即使使用--squash进行“add”后,当我尝试进行“subtree push”时,它仍然开始检查该子树上自时间开始以来的所有提交,尽管我只想将那些在将子树“添加”回容器存储库之后的提交推送进去。 - Nishith

1
我曾经遇到了你遇到的问题,最终采用了Roger Nolan建议的方法来解决。但是,如果你和我一样不幸地使用了大小写不敏感的文件系统,你还需要确保每次进行拉取和推送时,前缀的大小写保持一致。
如果你不小心混淆了大小写,git会认为你有两个子树,而实际上只有一个存在于文件系统中。
因此,我最终采用的解决方案(希望能对其他人有所帮助)是:
  1. 创建一个脚本来推送你的子树。将其命名为publish_<your-subtree-name>
  2. 创建另一个脚本来拉取你的子树。将其命名为update_<your-subtree-name>
  3. 在你的HEAD处创建一个临时分支,并测试更新。如果你的脚本正确,你的临时分支不会移动。
  4. 在别处克隆子树仓库,添加一个测试提交,将其推送并尝试使用刚刚编写的更新脚本将其拉入你的仓库。
  5. 如果一切正常,删除临时分支,现在将两个脚本都提交到超级项目仓库中。
  6. 然后每当你需要推送或拉取子树时,使用这些脚本。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接