【问题标题】:How to push a submodule to a remote repository如何将子模块推送到远程存储库
【发布时间】:2022-02-02 14:13:32
【问题描述】:

我在服务器上设置了一个远程存储库。我从本地计算机推送到存储库并设置了一个挂钩以将推送重定向到另一个目录。它看起来像这样:

post-receive

#!/bin/sh
git --work-tree=/var/www/laravel --git-dir=/var/repo/site.git checkout -f main

当我去 /var/www/laravel 并尝试做时

git submodule init
git submodule update

它给出:

fatal: not a git repository (or any of the parent directories): .git

我知道在重定向推送之前我可能必须启动和更新子模块。我可能必须创建另一个钩子命令,但我不知道它应该是什么。谢谢!

【问题讨论】:

    标签: git server terminal


    【解决方案1】:

    [某些现有裸存储库的接收后脚本包含该行]

    git --work-tree=/var/www/laravel --git-dir=/var/repo/site.git checkout -f main
    

    [但是]

    当我去/var/www/laravel并尝试做时

    git submodule init
    git submodule update
    

    它给出:

    fatal: not a git repository (or any of the parent directories): .git
    

    错误本身当然是正确的。问题是/var/www/laravel 没有.git:既没有指向存储库位置的.git 文件,也没有包含存储库的.git 目录/文件夹(无论您喜欢哪个术语)。简而言之,它只是一个工作树,因为 确实 操作 Git 存储库的其他一些 git ... 命令包含 --work-tree=/var/www/laravel

    因此,直接的解决方案是运行:

    git --git-dir=/var/repo/site.git submodule init
    git --git-dir=/var/repo/site.git submodule update
    

    或等价物。但是请注意,子模块涉及克隆其他 Git 存储库,而同样的推理(无论它是什么)导致您首先将 Git 存储库本身放入 /var/www/laravel/.git 可能 引导您避免在/var/www/laravel 的子目录中放置额外的.git 条目。这将更难实现。

    如果——这是一个相当大的问题if——可以将.git 文件留在子模块工作树中,如果(另一个相当大的如果)测试表明一切正常,考虑让您的接收后脚本如下:

    # configuration: where the directory and submodules go
    wt=/var/www/laravel
    
    export GIT_DIR=$(realpath $GIT_DIR) &&
    git --work-tree=$wt checkout -f main &&
    cd $wt &&
    git submodule update --init
    

    这里的想法是:

    1. 我们将 $GIT_DIR(在接收后脚本中设置,但通常设置为 相对 路径,例如 .git.,并将其转换为绝对路径。 (abspath 函数在这里可能会更好,但它不如 realpath 命令常用。)

    2. 然后我们使用git --worktree 来检查main 尖端的提交。如果这可能会覆盖一些未保存的文件,则需要此处的 -f 选项。这种方法非常不完善,最好一次准备一个完整的工作树,然后用近乎原子的mv 替换它,但我们在这里坚持使用现有的钩子方法。我们所做的只是删除--git-dir,无论如何它都隐含在$GIT_DIR 变量中。

    3. 然后我们在目标工作树中运行git submodule update --init$GIT_DIR 仍设置为绝对路径。这结合了initupdate 步骤。与结帐步骤一样,它相当不完美。我们可以在第二步中使用git checkout --recurse-submodules 来达到类似的效果,并且在某些(更新的)Git 版本中可能会更好。

    将替代方案(递归结账)与原子交换相结合,我们得到类似的东西作为我们的后接收:

    wt=/var/www/laravel.update-tmp.$$
    rm -rf $wt # just in case
    export GIT_INDEX_FILE=$GIT_DIR/index.tmp.$$
    rm -f $GIT_INDEX_FILE # also just in case
    mkdir $wt
    git --work-tree=$wt checkout --recurse-submodules main
    rm -f $GIT_INDEX_FILE
    
    t=/var/www/laravel
    
    # We now try to put $wt in place of $t with as little
    # interruption as possible.  This means renaming the
    # existing $t out of the way (using a pid-based directory
    # name), renaming $wt into place, and only then removing
    # (recursively) the backup.
    mv $t $t.backup.$$ && mv $wt $t && rm -rf $t.backup.$$
    

    如果你愿意,可以将不同的行串成一个大的&&-chain,或者你可以在顶部使用set -e。请注意,以上内容完全未经测试。

    【讨论】:

    • 感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 2012-05-19
    • 2015-04-14
    • 2015-05-17
    • 2018-10-29
    相关资源
    最近更新 更多