【问题标题】:Git submodule on remote bare远程裸机上的 Git 子模块
【发布时间】:2012-03-15 23:04:46
【问题描述】:

我已经设置了我的环境,所以我可以推送到远程裸存储库。我使用这些命令来设置远程存储库:

$ mkdir ~/website.git && cd ~/website.git
$ git init --bare

$ cat > hooks/post-receive

#!/bin/sh
GIT_WORK_TREE=/var/www/website git checkout -f

$ chmod +x hooks/post-receive

在我的本地环境中:

$ git remote add web ssh://website.com/home/website.git
$ git push web +master:refs/heads/master

现在我可以使用git push web 部署到这个远程,并且一切正常..

问题:子模块

我的项目中有一些 子模块 没有在远程存储库中初始化/更新。我不能在裸机上运行git submodule update,因为它是裸机,我不能在/var/www/website 文件夹上运行它,因为它只是文件的副本而不是git repo。

【问题讨论】:

    标签: git git-submodules git-bare


    【解决方案1】:

    一种可能的方式可能是:

    换句话说:
    从裸仓库中提取而不是尝试从裸仓库中结帐:非裸仓库应该能够容纳 git submodule update 步骤。

    示例脚本可能如下所示

    #!/bin/sh
    
    # Get the latest code
    cd /path/to/bare/repo
    
    # Set git variables
    GIT_WORK_TREE=/var/www/website
    GIT_DIR=/var/www/website/.git
    
    # Go to website and pull
    cd /var/www/website
    git pull /path/to/bare/repo
    git submodule update --init --recursive
    
    # Run additional build stuff here
    

    【讨论】:

    • 您能否提供一个接收后/更新后脚本的示例(尽管这个答案已经很老了)?每次我尝试推送时都会出错。
    • 远程:致命:不是 git 存储库:'/var/www/website'
    • @raveN 在/var/www/website 中有.git 文件夹吗?
    • 是否将GIT_DIR 设置为/var/ww/website/.gitGIT_WORK_TREE 设置为/var/ww/website/
    • @johnshumon 对!我已经删除了不必要的步骤。不知道我在 6 年前写这个答案时在想什么……
    【解决方案2】:

    两天前,我在为同样的问题苦苦挣扎时偶然发现了这个帖子。在终于找到了一个不错、整洁的解决方案后,我在这里写了一篇关于它的文章:

    Git push with submodules: a how-to guide

    我意识到,如果我要去 push 到一个裸仓库,只使用 post-receivepull 到一个非裸仓库,我还不如保持简单和直接 push到非裸存储库。这是一个明显的案例,其中仅推送到裸仓库的“最佳实践”只会增加复杂性。

    如果链接失效,我将在此处粘贴我的解决方案,跳过我确定遇到的所有相同问题的部分。


    首先,让我们创建一个 通用 post-receive 挂钩,我不需要在每个存储库的基础上进行更改:

    [aaron@aaronadams]$ cat > /usr/local/share/git-core/templates/hooks/post-receive.sample
    #!/bin/sh
    #
    # An example hook script to update the working tree, including its
    # submodules, after receiving a push.
    #
    # This hook requires core.worktree to be explicitly set, and
    # receive.denyCurrentBranch to be set to false.
    #
    # To enable this hook, rename this file to "post-receive".
    
    # Read standard input or hook will fail
    while read oldrev newrev refname
    do
    :
    done
    
    # Unset GIT_DIR or the universe will implode
    unset GIT_DIR
    
    # Change directory to the working tree; exit on failure
    cd `git config --get core.worktree` || exit
    
    # Force checkout
    git checkout --force
    
    # Force update submodules
    git submodule update --init --recursive --force
    [aaron@aaronadams]$ chmod +x /usr/local/share/git-core/templates/hooks/post-receive.sample
    

    现在让我们继续打破所有规则。

    我们将在我们的网站目录中初始化一个 non-bare Git 存储库;确保它可以从git push 接收;将其工作树显式设置为其父目录;并启用我们刚刚创建的钩子。

    [aaron@aaronadams]$ cd /var/www/vhosts/aaronadams.ca/sites/staging.aaronadams.ca
    [aaron@aaronadams]$ git init && git config --bool receive.denyCurrentBranch false && git config --path core.worktree ../ && mv .git/hooks/post-receive.sample .git/hooks/post-receive
    Initialized empty Git repository in /var/www/vhosts/aaronadams.ca/sites/staging.aaronadams.ca/.git/
    

    最后,在我们的本地机器上,我们将更改远程以反映我们新存储库的位置,然后推送。

    [aaron@aaronadams]$ git remote set-url staging aaron@aaronadams.ca:sites/staging.aaronadams.ca
    [aaron@aaronadams]$ git push staging master
    remote: Submodule 'codeigniter' (git://github.com/EllisLab/CodeIgniter.git) registered for path 'codeigniter'
    remote: Cloning into 'codeigniter'...
    remote: Submodule path 'codeigniter': checked out 'fd24adf31255822d6aa9a5d2dce9010ad2ee4cf0'
    To aaron@aaronadams.ca:sites/staging.aaronadams.ca
     * [new branch]      master -> master
    

    天哪,它成功了!

    这种方法不仅与子模块兼容,还只需要一个命令来设置一个新的远程存储库(好吧,由四个命令组成)。它还将存储库和工作树保持在同一位置;而且我们的配置或挂钩文件中不需要绝对路径,现在它也完全可移植


    我希望这个答案对某人有所帮助,就像其他人的 Stack Exchange 帖子在过去两天对我有所帮助一样!

    【讨论】:

    • 我试过你的文章,但在第一次推送后它就坏了。我注意到它没有将文件存储在对象目录中。错误是:错误:无法创建临时 sha1 文件名 ./objects/9e:没有这样的文件或目录。我相信它应该是.git/objects/9e。有任何想法吗?这很接近
    • 有趣。听起来你的配置最终可能与我的有点不同——但是嘿,只要它工作正常!
    • 如果多个程序员部署到同一个网站,这可能会导致问题。见"all about bare repos"。 VonC 的解决方案避免了这个问题。
    • @jrhorn424 确实,上述解决方案有很多问题;自从我编写它以来,我学到了很多东西,最重要的是子模块产生的问题比它们解决的问题多。我强烈建议切换到我在此处记录的无子模块解决方案:stackoverflow.com/questions/14656047/…
    • @jrhorn424 事实上,我最初的博客文章记录了我在尝试自己实施该解决方案时遇到的所有痛苦。
    【解决方案3】:

    我想出了另一种对我来说看起来相当干净的解决方案。只需为 git 提供执行子模块所需的所有信息:

    $ cd /path/to/your/git_work_tree
    $ git --git-dir=/path/to/your/bare_repo.git --work-tree=. submodule init
    $ git --git-dir=/path/to/your/bare_repo.git --work-tree=. submodule update
    

    【讨论】:

    • 如何实现自动化,以便在每次 push 部署后执行此操作?
    猜你喜欢
    • 2018-08-02
    • 1970-01-01
    • 2015-11-25
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    • 1970-01-01
    • 2016-12-16
    • 1970-01-01
    相关资源
    最近更新 更多