【问题标题】:Submodules, subtrees or something else for dependencies in Git?Git 中依赖的子模块、子树或其他东西?
【发布时间】:2014-06-26 14:35:20
【问题描述】:

我有一个大型项目的情况,该项目有很多模块/库及其各自的存储库。这些模块中的大多数是其他模块的依赖项,而不是项目的依赖项。现在已经到了主项目有几个子项目和许多模块共享的地步。一些依赖关系的深度超过 3-4 级。

我已经读到可以在项目中更新/拉取子模块,但这仅适用于第一级子模块。假设这些子模块有自己的子模块(第 2 级),并且一些第 1 级子模块共享相同的第 2 级子模块。此外,第二个 lvl 子模块有它们的子模块(lvl3)等。现在我应该做的是首先推送第三级所做的更改,而不是更新第二级模块中的子模块并推送这些,现在我可以进入第一级,更新和推送,最后更新我的项目子模块并推送它们。

这现在不仅是更多的工作,但它仍然没有解决我的问题,为什么我需要这样的东西,那就是能够在对依赖于每个的存储库进行更改时轻松推送和拉取多个存储库其他。很容易发生团队中的某个人在 5 个 repo 中的 4 个中推送更改,而当其他成员拉除此之外的所有内容时,生产线会停止,直到发现错误。

对此我能做些什么?也许一些关于工作流程的建议,有没有其他人遇到过这个问题,或者 Git 中是否有一些功能可以解决这个问题。

【问题讨论】:

  • 您的解决方案是否也需要在 Windows 上运行?
  • 暂时没有,您有什么建议吗?

标签: git dependencies workflow


【解决方案1】:

我会推荐 android 使用的 repo 工具。它足够通用,可以与任何 git 托管环境一起使用,并且不需要像子模块那样需要超级项目提交来更新子项目。

首先,按照此处所述安装客户端:https://source.android.com/source/downloading.html#installing-repo

然后创建一个清单存储库。清单是一个 xml 文件,它描述了 git 存储库位置和它们应该被签出的路径。像这样:

mkdir manifests
cd manifests
git init

创建清单文件default.xml

<?xml version="1.0" encoding="UTF-8"?>
<manifest>
  <remote name="github" fetch="ssh://git@github.com" />
  <default remote="github" revision="master" />
  <project name="git/git.git" path="git" />
  <project name="libgit2/libgit2.git" path="vendor/libgit2" />
</manifest>

然后添加、提交清单,然后推送到某处:

git add default.xml
git commit -m "My first try at a manifest file"
git push git@github.com:myusername/manifests.git master

现在您可以使用repo 命令了。

mkdir myproject
cd myproject
repo init -u git@github.com:myusername/manifests.git
repo sync -j2

您的 git 存储库将被克隆。您现在可以像往常一样在每一个中工作。在您推送到任何项目后,其他人只需发送repo sync,它们就会更新到最新版本(另请参阅repo start)。

注意事项

您可能需要重新组织您的项目。通常,您可能会将其他模块作为子目录 (myproject/vendor/dependency)。虽然您仍然可以使用 repo 维护此布局,但它会导致 git 存储库与另一个 repo 签出。使用 .gitignore 诡计它可能是可行的,但我建议重新组织您的项目,这样存储库就不需要相互签出。

清单文件的简短说明

有关 xml 文件中每个项目的完整说明,请参阅https://gerrit.googlesource.com/git-repo/+/master/docs/manifest-format.txt

查看https://source.android.com/source/using-repo.html 以获得简单的命令参考。 repo help 也很有用。注意:除非您使用 Gerrit,否则您应该忽略 repo upload

&lt;remote name="github" fetch="ssh://git@github.com" /&gt;

这就像在git 中添加一个遥控器。这意味着我们可以使用给定名称引用 url。

&lt;default remote="github" revision="master" /&gt;

默认元素指定项目的默认选项。这相当于在每个项目上添加 remoterevision 项目。这只是节省了一些输入。

&lt;project name="git/git.git" path="git" /&gt;

这是真正的工作发生的地方。 repo sync 将获取名称并使用斜杠将其附加到远程。在这种情况下,遥控器是默认的github,所以它会得到 url ssh://git@github.com/git/git.git。它会将项目签出到指定修订版的路径git(在这种情况下,默认值为master)。随后的repo syncs 将检出最新版本(在分支的情况下)。

【讨论】:

  • 我会试一试,告诉你进展如何。谢谢
  • 在使用 repo 工具一段时间后,我们认为当您需要在同一分支上同步大量更改以获取该分支上的最新版本时,它是一个很好的工具。与我们迄今为止的工作方式相比,它当然可以节省一些时间。但是,它并没有解决我们逐步跟踪项目的问题。例如,制作项目状态的快照,并在需要时使用该状态。
  • repo manifest -r 将捕获您可以保存并在以后使用的快照。这能满足您的需求吗?
  • repo 还支持使用子模块克隆 git 存储库,因此您可以混合搭配以获得所需的内容。
猜你喜欢
  • 2019-06-07
  • 2016-09-10
  • 1970-01-01
  • 2021-12-25
  • 2018-08-14
  • 2011-02-23
  • 1970-01-01
  • 2014-02-17
  • 1970-01-01
相关资源
最近更新 更多