【问题标题】:How can I reduce the ever-increasing time to push a subtree?如何减少推送子树的不断增加的时间?
【发布时间】:2013-04-14 15:19:40
【问题描述】:

我正在使用Git subtree 将几个子项目“链接”到主项目中(我来自“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

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

【问题讨论】:

  • 子模块并不适合所有人,问题是关于子树的。
  • @ferraith 切换到子模块没问题,但是使用子树的社区需要答案!您可以选择其他答案吗?
  • @JorgeOrpinel 你似乎想要一个更好的答案,就像我一样......如果你能发布一个好的答案,甚至只是总结其他答案/文档,并解释来龙去脉,我相信你会得到一些选票:)
  • 抱歉 Anthony 我现在已经放弃了 Git 子树。很久以前!连他们都不熟悉了哈哈。我的建议:不要使用它们。
  • @ferraith,你找到解决这个问题的方法了吗?

标签: git github git-subtree


【解决方案1】:

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

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

来自original subtree documentation

拆分后,合并新创建的synthetic 历史回到你的主要项目。这样,未来 splits 只能搜索具有 自最近一次 --rejoin 后添加。

【讨论】:

  • 并使用哪个 ?我尝试使用该子树的尖端,虽然它进行了拆分/重新加入(甚至不确定这意味着什么),但我的下一个子树推送同样冗长:(
  • 为什么会这样(你能解释一下当你使用 split/rejoin 时发生了什么)?以及我需要多久运行一次(一次?每次未指定事件一次?每次推送之前?)
【解决方案2】:

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

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

【讨论】:

  • 令人惊讶的是git subtree 不能(不是吗?)只缓存这些信息,所以在第一个git subtree push 之后,一切都变得相对活泼。
  • @davidg 当然可以。
  • 尤其是在 Windows 上,这速度慢得离谱。在我的情况下,当您达到 600 个断言计数时,每次推送都需要一分钟以上,从而使 git 在那时无用。
【解决方案3】:

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

这是避免这种情况的方法

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

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

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

  1. 变基

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

【讨论】:

  • 问题是关于git subtree push 而不是split,我认为rejoin 选项不适用。
  • @AnthonyMastrean 啊....git subtree push 首先进行拆分。请检查原始文件。如果你真的尝试过,你会看到它是如何工作的。
  • 我查看了git-subtree.sh 的来源,是的,那里有一个subtree split。不过,我仍然没有遵循您回答的机制...如果我们手动设置拆分/重新加入...这将使后续推送工作得更好?
  • 它创建一个分割点并从那里计算,而不是从头开始计算。你试过吗?
  • @maxisam 我刚才试了一下,还是不行。 -1
【解决方案4】:

也许这有帮助:我想你可以告诉 git subtree split 只返回 n 次提交。

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

或者通过指定你想要开始的提交,例如

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

这有助于减少时间,但不方便。

【讨论】:

  • git subtree split 只接受一个提交作为参数。
【解决方案5】:

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

git externals

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

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

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

git submodule update --remote

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

【讨论】:

  • 不错的选择,但这个问题是关于子树的。很高兴找到答案。
猜你喜欢
  • 2019-10-29
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 2021-11-10
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多