如何在每次推送时将回购的一部分移动到另一个回购

How to move a part of repo to another repo on each push

我有一个庞大的应用程序,我想在每次推送时将我的应用程序的一部分移动到另一个存储库。 例如当我按下

-assets
-themes
--theme-1
--theme-2
-pages

到存储库 maintheme-1 被推送到存储库 main-theme-1 等等 theme-2 。最好不要将主题推送到 main 回购。 反正有办法吗?? (自动首选 :D )

你得不到你想要的。您可以 得到一些近似值。

Git 存储库由 提交 组成。他们不保存文件——至少不直接保存。 commits 保存文件,但提交本身是存储单元。这就是 git log 向您显示提交哈希 ID 的原因:每个都是一个可用的东西,都是独立的。

每个提交都会存储一个每个文件的完整快照。您可能认为这会占用很多 space。除了聪明之外,它会:Git 压缩和删除重复项 每次提交中的文件。它们不像普通文件那样存储在您的计算机上。它们采用特殊形式,只有 Git 可以读取,而且几乎没有任何东西——甚至 Git 本身——都不能覆盖。

这个只读 属性 实际上是每个内部 Git 对象的 属性。因此,不仅提交中包含的文件是只读的,提交本身也是如此。 Git 以多种方式使用它。特别是,标识每个提交的哈希 ID 对于 那个特定的提交 是唯一的,并且由提交内容的加密校验和组成。这意味着实现 Git 传输协议的任何两个软件块都可以相互连接,然后一个实际上可以对另一个说:我已提交 _____ (用hash ID填空),would you like it? 另一个Git 可以通过检查hash来判断是否有that commit ID。如果它确实有那个提交,它有每个文件

不仅如此,在除shallow存储库之外的所有存储库中,如果潜在接收者有那个提交,它也有每个较早的提交 并且发送者现在已经完成:没有什么可以发送的了。如果接收方没有该提交,则发送方有义务提供该提交的父提交。这一直持续到发送方提供了所有提交,或者发送方和接收方已达到共享提交的点。这就是 如何 发送方和接收方可以协商最小的文件集并提交发送,只需交换几个哈希 ID。

无论如何,所有这一切的重点是发送者发送——接收者接收——整个提交。文件去重技巧意味着发送方知道接收方是否已经有一些文件,因为发送方知道接收方有哪些 commits,以及那些提交(发送方也有)有其中的文件哈希 ID。所以发送方只需要发送任何 new 提交和 new 文件,接收方自动使用重复文件来填写新收到的提交如所须。这都是一个非常聪明的系统,但它从根本上取决于这个哈希系统和提交永远不会改变并且存储库只交换整个提交的想法。1

这对您意味着git push发送了一些提交,仅此而已。您不能将提交的 部分 发送到其他地方。每个提交都包含每个文件的完整快照。发送文件较少的提交的唯一方法是......提交文件较少的提交。

有一些工具可以做到这一点,例如 git-subtree。当前未维护子树代码。参见 如果我考虑使用它,缺乏维护会让我担心。

维护的另一个执行此操作的工具是 Git 的子模块。这些在同一个链接的 SO 问题中有轻微描述,但基本上子模块是一种方式,在一个 Git 存储库中:Clone this other Git repository, into a sub-directory在我将使用的工作树中。 一旦您的 Git 将另一个 Git 存储库克隆到该位置,您的 Git 使用 分离的子模块中的 HEAD 模式,以将该子模块保留在另一个 Git 存储库中的一个特定提交

此设置有点僵化和脆弱,并不能取悦它的许多用户。2不过它确实 有效,并且它可以解决实际问题。考虑一下吧。


1最近有意削弱这个系统,Git 称之为部分克隆,但它们仍然还没有真正准备好日常使用。把弱化想象成一种叠叠乐游戏,我们抽出一些坚固的结构来让一切变得更轻。如果我们拔出错误的位,整个事情就会崩溃:糟糕!

2我个人得出的结论是子模块是错误的,我对如何“正确”地做它们有一些想法,但这些想法还有很长的路要走在它们可能以任何可用代码的形式实现之前进行。