当前位置: 首页 > 科技观察

如何使用子模块和子树来管理Git项目

时间:2023-03-17 13:35:51 科技观察

使用子模块和子树来帮助您管理跨多个存储库通用的子项目。如果您参与过开源项目的开发,那么您很可能已经使用Git来管理您的源代码。您可能遇到过具有许多依赖项和/或子项目的项目。你如何管理它们?对于一个开源组织来说,实现社区和产品的单一来源文档和依赖管理是很棘手的。文档和项目往往变得支离破碎和冗余,使它们难以维护。必要性假设您希望将单个项目作为存储库中的子项目,传统的方法是将该项目复制到父存储库中,但是如果您想在多个父项目中使用同一个子项目怎么办?如果把子工程复制到所有的父工程中,当有更新的时候,还得在每个父工程中都做改动,不太可行。这会导致父项目中的冗余和数据不一致,导致难以更新和维护子项目。Git子模块和子树如果您可以使用一条命令将一个项目放入另一个项目会怎样?如果您可以随时将一个项目作为子项目添加到任意数量的项目中,并同步更新和修改它会怎样?Git为此类问题提供了解决方案:Gitsubmodulesubmodule和Gitsubtree子树。创建这些工具的目的是在更模块化的层面上支持通用代码的开发工作流程,旨在在Git存储库的源代码管理(SCM)和它下面的子树之间架起一座桥梁。在长在桑树上的樱桃树下面,是本文详述的概念在现实世界中的应用。如果您已经熟悉树结构,模型如下所示:带有子树的树什么是Git子模块?Git在其默认包中提供了子模块,子模块可以将Git存储库嵌入到其他存储库中。具体来说,一个Git子模块指向子树中的一个提交。下面是我的Docs-testGitHub仓库中的一个Git子模块的样子:Gitsubmodulesscreenshot文件夹@commitId格式表明这个仓库是一个子模块,你可以直接点击文件夹进入那个子树。名为.gitmodules的配置文件包含所有子模块存储库的详细信息。我的存储库的.gitmodules文件如下:.gitmodules文件的屏幕截图您可以使用以下命令在存储库中使用Git子模块:ClonearepositoryandloadsubmodulesClonearepositorywithsubmodules:$gitclone--recursive如果你之前已经克隆了存储库,现在想加载它的子模块:$gitsubmoduleupdate--init如果你有嵌套的子模块:$gitsubmoduleupdate--init--recursivedownloadsubmodule连续下载多个子模块很无聊job,所以clone和submoduleupdate将支持--jobs(或-j)参数:例如,如果你想一次下载8个子模块,使用:$gitsubmoduleupdate--init--recursive-j8$gitclone--recursive--jobs8拉取子模块在运行或构建父项目之前,需要确保依赖的子项目都是最新的。拉取子模块中的所有更改:$gitsubmoduleupdate--remote使用子模块创建存储库:将子树添加到父存储库:$gitsubmoduleadd初始化现有的Git子模块:$gitsubmoduleinit你可以还可以通过向子模块更新命令添加--update参数来创建分支并跟踪子模块中的提交:$gitsubmoduleupdate--remoteUpdatesubmodulecommits如上所述,子模块是一个指向子树中提交的链接。如果你想更新子模块的提交,不用担心。您不需要明确指定最新的提交。您只需使用通用子模块更新命令:$gitsubmoduleupdate添加并提交,就像您通常创建父存储库并将父存储库推送到GitHub一样。从父存储库中删除子模块仅手动删除子项目文件夹不会从父项目中删除子项目。要删除名为childmodule的子模块,请使用:$gitrm-fchildmoduleGit子模块虽然看起来简单易用,但对于初学者来说还是有一定门槛的。什么是Git子树?Git子树在Git1.7.11中引入,让您可以将任何存储库的副本作为子目录嵌入到另一个存储库中。它是Git项目可以注入和管理项目依赖项的几种方式之一。它在常规提交中保存外部依赖信息。Git子树提供简洁的集成点,因此很容易恢复它们。如果按照GitHub提供的子树教程使用子树,那么每次添加子树时,本地都看不到.gittrees配置文件。这使得很难分辨哪个是子树,因为它们看起来像普通文件夹,但它们是子树的副本。默认的Git包中并没有提供带.gittrees配置文件的Git子树版本,所以如果你想要带.gittrees配置文件的git-subtree命令,你必须从/contrib/subtree文件夹中下载git-subtreeGit源代码库。子树。您可以像任何其他常规存储库一样克隆任何带有子树的存储库,但由于父存储库中有整个子树的副本,因此克隆过程可能需要很长时间。您可以使用以下命令在存储库中使用Git子树。向父仓库添加子树要向父仓库添加子树,首先需要执行remoteadd,然后执行子树添加命令:$gitremoteaddremote-name$gitsubtreeadd--prefix=folder/remote-namesubtree-branchname上面的命令会将整个子项目的提交历史合并到父存储库中。将更改推送到子树并从子树中拉取更改$gitsubtreepush-all或$gitsubtreepull-all你应该使用哪个?任何工具都有优点和缺点。以下是一些可以帮助您决定最适合您的功能:Git子模块存储库占用空间较小,因为它们只是指向子项目的单个提交的链接,而Git子树包含整个子项目及其提交历史记录。Git子模块需要在服务器中可访问,但子树是分散的。Git子模块大量用于基于组件的开发,而Git子树主要用于基于系统的开发。Git子树不是Git子模块的直接替代品。有明确的说明指导我们使用哪一个。如果你有一个属于你的外部存储库,并且用例是将代码推送回它,那么使用Git子模块,因为推送代码更容易。如果你有第三方代码,并且你不会向它推送代码,那么使用Git子树,因为它更容易拉取代码。