GIT 嵌套存储库:Composer vs. SubModules vs. Subtree vs.?

Posted

技术标签:

【中文标题】GIT 嵌套存储库:Composer vs. SubModules vs. Subtree vs.?【英文标题】:GIT Nested repositories: Composer vs. SubModules vs. Subtree vs.? 【发布时间】:2014-06-26 08:55:22 【问题描述】:

我终于在我的工作流程中加入了 GitHubComposer 依赖管理。这绝对是向前迈出的一大步,尽管我仍然对 GIT 管理“嵌套”依赖项感到非常困惑。

由于我使用了很棒的 Wordpress Stack ROOTS/BEDROCK,我的简化目录结构如下所示:

|-- /project
|   |-- /.git                    // git repository for the skeleton/stack of the project
|   |-- composer.json            // list of dependencies, most of them are my own repositories on GitHub
|   |-- /vendor
|   |   |-- /php-dependency-1    // 3rd party dependencies not directly related to Wordpress
|   |-- /web
|   |   |-- /app                 // acts as "wp-admin" folder
|   |   |   |-- /mu-plugins       
|   |   |   |   |-- /SUBREPOSITORY-1    // my own framework feature, public, GitHub
|   |   |   |   |-- /SUBREPOSITORY-2    // my own framework feature, public, GitHub
|   |   |   |-- /plugins
|   |   |   |   |-- /SUBREPOSITORY-3    // my own plugin, public, GitHub
|   |   |   |-- /themes
|   |   |   |   |-- /SUBREPOSITORY-5-PARENT-THEME    // parent theme used on my framework, public, GitHub
|   |   |   |   |-- /SUBREPOSITORY-6-CHILD-THEME     // work for client, private, BitBucket
|   |   |-- /wordpress           // Wordpress CMS
|   |   |   |-- /wp-admin
|   |   |   |-- /wp-includes

“子存储库”在我的项目根目录composer.json中定义,由composer install从GitHub下载。到目前为止一切顺利。

但是!我希望调整我的parent-theme 和一些mu-plugins 很多,我需要能够从我的每个项目中推送/提交它们将被包括在内。如您所知,如果没有安装 wordpress,您将无法真正测试 wordpress 主题...

那么……走哪条路? 有很多关于这个主题的帖子,其中大多数都提到了 SubModules,但是如果我正确理解 Composer 的概念,它们就会相互冲突。

仅使用嵌套的 .git 存储库对我来说似乎很棒,尽管它似乎不起作用 - 如果我尝试推送/提交嵌套存储库,要么“一切都是最新的”,要么我收到诸如 Your branch is ahead by 1 commit. 之类的消息所以仅仅“嵌套”是不行的吗?

提前感谢并抱歉问题的语气有点混乱,我在这个话题上有点淹死了。 :) 任何帮助将不胜感激。

【问题讨论】:

这个问题似乎很自以为是。我仍然想听听不同的方法。 根据定义,“问题”不能固执己见。只有一个答案。这个问题很简单(嵌套是不行的),答案很丰富。但公平地说,也许帖子也被编辑了。 【参考方案1】:

我有几个问题,考虑到这一点,下面的答案很笼统。如果你回答我的问题,我会很乐意更新它。

    作曲家是否会在更新时提取存储库?或重新克隆回购? (它甚至在做更新吗?)

    如果它重新克隆,那么将其用于更新将有覆盖您在这些子存储库上的工作树的风险(仅将其用于安装或将其全部删除) 如果它没有进行更新(或依赖递归 -- 见下文),那么它会给您的项目增加不必要的复杂性(删除它并使用以下选项之一

    composer 是否真的在做任何依赖管理(即递归查找嵌套依赖)?还是只是将 git 项目克隆为子文件夹?

    如果是,那么是的,子模块可能不适合您的情况,因为它们是替代的依赖管理系统,但如果您的子项目也使用子模块管理它们的依赖关系,那么执行 git clone --recursive应该也可以管理它们

    您希望您的主项目跟踪子项目的新更改吗?

    如果是:查看选项 #2:子存储库 否则:尝试选项 #1:子模块 [我将链接到第三个选项,但我没有使用它,因此无法详细解释(cmets/edits 赞赏)]

选项 #1:Submodules

您还可以通过cd LOCAL_DIR_NAME_I 并使用普通的 git 命令管理单个子模块

    设置:
git submodule add REMOTE_URI_1 LOCAL_DIR_NAME_1
...
...
git submodule add REMOTE_URI_N LOCAL_DIR_NAME_N
git commit -m "Add submodules..."

    克隆(主项目)

    git clone MAIN_URI REPO && cd REPO && git submodule update --init --recursive

    --init 将在执行更新之前将配置从 .gitmodules 复制到 .git/config(如有必要),--recursive 将在每个子模块中递归执行该操作。

    git clone --recursive MAIN_URI

    --recursive 告诉 git 在克隆时更新和初始化所有子模块

    更新(将保留未保存的更改)

    本地副本没有未推送的更改(默认更新所有子模块):

    git submodule update [LOCAL_DIR_NAME_I ... LOCAL_DIR_NAME_J]

    本地副本有未推送的更改(默认更新所有子模块):

    git submodule update --remote --rebase [LOCAL_DIR_NAME_I ... LOCAL_DIR_NAME_J]

    发布/推送

这会首先尝试子模块推送,如果成功则执行主项目推送

git push --recurse-submodules=on-demand

选项 #2:Subrepositories

你说你使用这种方法有问题,但我不明白它们是什么。如果可能,请详细说明。

(git book 也谈到了 subrepos,但我一辈子都找不到现在在哪里;如果你找到了,请告诉我)

    设置:

注意:主仓库不会跟踪对子仓库 .git 的更改,只会跟踪文件本身

目录名后面的斜杠 (/) 是避免创建子模块的必要条件

git clone REMOTE_URI_1 LOCAL_DIR_NAME_1 && git add LOCAL_DIR_NAME_1/
...
...
git clone REMOTE_URI_N LOCAL_DIR_NAME_N && git add LOCAL_DIR_NAME_N/
git commit -m "Add subrepos..."

如果使用 Composer:(它正在为您进行克隆)您可以简单地进行添加和提交,但也许您也可以配置 composer 来执行此操作。

    管理

通过以下方式管理单个子代表: `cd LOCAL_DIR_NAME_N' 并使用普通的 git 命令

请记住,对子存储库文件的更改将由您的主存储库跟踪

最大的问题是克隆(如果您希望合作者能够处理子项目),因为您的 subrepo .git 文件不会被跟踪。在存储遥控器的每个子存储库中包含一个文件 remote.info 应该可以解决这个问题。然后将一个脚本添加到您的主存储库中,该脚本适用于每个子目录cd SUBDIR && git init && cat remote.info | xargs git remote add origin。根据 Composer 正在做什么(请参阅上面的问题),您可能需要在此脚本中添加 composer update 命令

Option #3: Subtree Merging

我对这种方法的微妙之处并不完全有信心,所以我只是链接到它

Try this link for a bit of a tutorial

选项#N:任意方式

当然,您可以设置许多其他工作流程,在某些情况下可能会更简单。例如,您可以坚持使用 Composer 进行 dep 管理,并在主项目之外克隆您的子项目,在主项目中创建未跟踪的符号链接,以便在处理主项目时轻松访问这些文件。这可以通过脚本自动完成(所有这些 repos 的批量推送也可以)。您甚至可以解析 composer.json 以自动为新的(基于 git 的)依赖项执行此操作。

注意:在我看来,您根本不需要使用 Composer。如果此假设不正确,则上述 3 个选项都可能无法解决您的问题。

【讨论】:

迪伦,这是一个非常全面的答案!谢谢您,每当我有更多时间时,我都会将您的建议纳入我的工作流程。祝你有美好的一天! 感谢解释选项的答案,而不是提倡特定的解决方案。说得好!

以上是关于GIT 嵌套存储库:Composer vs. SubModules vs. Subtree vs.?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 composer 安装部分 git 存储库?

如何使用 Composer 从本地 Git 存储库安装标记提交?

json composer需要git存储库

Composer Github 私有存储库无法使用给定的密钥

Visual Studio 2017 的多个 Git 存储库

如何将 Git 存储库转换为嵌套在另一个(父)Git 存储库中的子模块?