21

我正在使用Git 子树将几个子项目“链接”到主项目中(我来自“svn:externals”)。我已经使用了几个星期,但是将更改推送到远程子树的时间会增加每次提交。

$ git subtree push -P platform/rtos rtos master

git push using:  rtos master

1/    215 (0)2/    215 (1)3/    215 (2)4/    215 (3)5/    215 (4)6/    215 (5)7/    215 (6)8/    215 (7)9/    215 (8)10/    215 (9)11/    215 (9)12/    215 (10)13/    215 (11)14/    
...
20 more lines
...
(204)209/    215 (205)210/    215 (206)211/    215 (207)212/    215 (208)213/    215 (209)214/    215 (210)215/    215 (211)To https://github.com/rtos/rtos.git
   64546f..9454ce  9a9d34c5656655656565676768887899898767667348590 -> master

有没有办法“清理”子树,从而减少推送更改的时间?

4

5 回答 5

18

尝试使用该--rejoin标志,以便在拆分后子树正确合并回您的主存储库。这样,每次拆分都不需要遍历所有历史记录。

git subtree split --rejoin --prefix=<prefix> <commit...>

原始子树文档

拆分后,将新创建的合成历史合并回您的主项目。这样,未来的拆分只能搜索自最近一次 --rejoin 以来添加的历史记录部分。

于 2013-04-22T04:16:39.837 回答
7

不,很遗憾没有。当您运行git subtree push时,它将重新创建此子树的所有提交。它必须这样做,因为他们的 SHA 依赖于先前的提交,并且需要这些 SHA 能够将新提交链接到旧提交。它可以缓存它,但它没有。

我想这是您使用子树与子模块所付出的代价。子树在您的存储库中是非常无状态的,一方面这很好,但另一方面会导致这些长时间的计算。子模块存储所有需要您管理的信息,但也使这样的事情变得更快。

于 2013-04-21T23:17:31.457 回答
0

@LopSae 的答案有效,但是如果您使用 squash 合并/拉取,它将使您的仓库充满大量提交

这是避免这种情况的方法

git subtree split --rejoin --prefix=<subtree/path> --ignore-joins

当你这样做时,你想推回你从中拉出的分支。否则您无法创建拉取请求。

至少有两个选项可以处理这个问题。

  1. 变基

  2. 在远程项目上创建一个新分支并将其拉回并推回该分支。

于 2020-02-21T03:16:10.023 回答
-2

也许这会有所帮助:我认为您可以git subtree split通过这样做来告诉您只返回 n 次提交

git subtree split --prefix XXX HEAD~n..

或通过指定您要开始的提交,例如

git subtree split --prefix XXX 0a8f4f0^..

这有助于减少时间,尽管它很不方便。

于 2015-11-02T11:27:33.107 回答
-6

请注意,如果您决定切换到git submodule,现在可以,因为 git1.8.2 (2013-03-08)跟踪子模块 repo 的最新提交

请参阅git externals

“git submodule”开始学习一种与远程分支的尖端集成的新模式(而不是与超级项目的 gitlink 中记录的提交集成)。

这可以加快推送速度,同时受益于子模块在子树上的附加信息(即子模块特定提交的轻量级记录)

您可以使用以下命令将该子模块更新为给定分支的最新版本:

git submodule update --remote

此选项仅对update命令有效。
不要使用超级项目记录的 SHA-1 来更新子模块,而是使用子模块的远程跟踪分支的状态。

于 2013-04-22T05:47:49.607 回答