【问题标题】:git submodule not pushed to productiongit子模块未推送到生产
【发布时间】:2021-03-08 17:01:30
【问题描述】:

刚刚创建了一个包含两个子模块的新存储库。它在本地运行良好,但在推送到生产环境时,子模块不存在。每个子模块根目录都存在,但里面没有文件

git version 2.27.0

在生产环境中创建仓库

git --bare init
cd hooks && touch post-receive && chmod +x post-receive

cat hooks/post-receive
#/bin/sh
git --work-tree=/var/www/repo --git-dir=/var/git_repos/repo.git checkout -f

从 dev/local 推送到生产环境

git push production master

git status 表示一切都是最新的。即使在子模块文件夹中调用它。已尝试删除本地存储库上的子模块文件夹,提交/推送到存储库。然后git push production master 和根子模块文件夹在生产服务器上被删除。然后尝试再次添加它

# git submodule add git@github.com:alias/repo_name.git php/repo/repo_name
Cloning into '/var/www/project/php/repo/repo_name'...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (19/19), done.
remote: Compressing objects: 100% (11/11), done.
remote: Total 19 (delta 8), reused 19 (delta 8), pack-reused 0
Receiving objects: 100% (19/19), 8.62 KiB | 8.62 MiB/s, done.
Resolving deltas: 100% (8/8), done.

然后提交到存储库,然后是 git push production master 。同样的问题。在生产中,子模块的根文件夹存在,但目录中没有文件。

当我浏览 github 上的存储库时,子模块已正确链接。

一切都在本地存储库中工作

【问题讨论】:

  • 添加子模块后,仅克隆是不够的。 git submodule initgit submodule update 也是需要的。
  • 这能回答你的问题吗? Empty Git submodule folder when repo cloned
  • 我假设生产 repo 不是这里的裸存储库,并且您正在通过克隆检查它(从外观上看)。如果没有,请提供更多详细信息。
  • 我不是克隆而是推向生产
  • 如何检查生产仓库的内容?

标签: git github


【解决方案1】:

子模块文件夹在 github(或本地 repo)上不是空的,但在推送到生产时它们是

这是预期的:一个子模块由以下部分组成:

  • .gitmodules 中注册的 URL
  • gitlink,索引中的一个特殊条目,表示子模块存储库的根树的 SHA1。

当您克隆带有子模块的远程存储库时(使用 git clone --recurse-submodules 选项,这些子模块存储库会自行克隆,并在该 gitlink 表示的 SHA1 处签出。

“推送到生产环境”很棘手,因为您不应该推送到已签出(非裸机)存储库(即使你是 can technically do it)。

生产时最好推送到裸仓库,它将使用post-receive hook 来恢复文件(包括子模块内容,使用git restore --recurse-submodules


discussion之后:

  1. 您需要为生产服务器注册一个公共 SSH 密钥到您的帐户,因为子模块是在 .gitmodules 中使用 SSH URL 注册的。

  2. 接收后脚本变为:

    #!/bin/bash
    cd /var/www/repo
    git --git-dir=/var/git_repos/repo.git --work-tree=. restore --recurse-submodules :/
    

git submodule,你cannot set the working tree apparently

这意味着,如果涉及子模块,则当前文件夹必须是工作树。

然后您可以使用--recurse-submodulesgit submodule update --init 执行诸如git checkout/git restore 之类的命令,即使使用不同的git-dir (--git-dir=/path/to/bare/repo.git)。

子模块将被更新,因为您当前的工作树是正确的。

如果您不是/var/www/repo,即使您指定git --work-tree=/var/www/repo ...,上述命令git checkout/git restore--recurse-submodulesgit submodule update --init 都不适用于您的repo 的子模块。
即:您的/var/www/repo 文件将被恢复,但子模块将保持为空。

【讨论】:

  • 那么在这种情况下最佳做法是什么?
  • 这个命令不适合添加子模块吗? git submodule add git@github.com:alias/repo_name.git php/repo/repo_name
  • @clarkk 在产品上有一个裸仓库,您可以直接推送到该仓库(及其相关的 post-receive 挂钩),或者在产品上有一个非裸仓库,以及一个按需流程从 GitHub 执行 git pull --recurse-submodules(意味着您推送到 GitHub,然后从产品中提取)
  • 我创建了这样的生产仓库:git --bare init 并且已经有了一个接收后挂钩:git --work-tree=/var/www/repo --git-dir=/var/git_repos/repo.git checkout -f ...所以我只需要在后添加一个新行-收到:git pull --recurse-submodules?
  • @clarkk 不需要拉,因为你正在推动它。您需要做的就是使用git checkout -f --recurse-submodules(或者,如果您的 Git 足够现代:git restore -f --recurse-submodules
猜你喜欢
  • 1970-01-01
  • 2014-07-31
  • 2017-10-05
  • 2015-07-07
  • 2011-02-26
  • 2019-02-22
  • 2021-01-31
  • 2015-05-28
  • 2018-08-02
相关资源
最近更新 更多