Git submodule on remote bare

前端 未结 3 2043
予麋鹿
予麋鹿 2020-11-29 03:38

I\'ve setup my environment so I can push to a remote bare repository. I used these commands to set up the remote repository:

$ mkdir ~/website.git &&         


        
相关标签:
3条回答
  • 2020-11-29 04:05

    I figured out another solution which looks rather clean to me. Just give git all the info it needs to perform the submodule stuff:

    $ 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
    
    0 讨论(0)
  • 2020-11-29 04:18

    One possible way might be:

    • to setup /var/www/website as a (non-bare) repo
    • have your post-receive hook of your bare repo:
      • set GIT_DIR and GIT_WORK_TREE to the non-bare repo at /var/www/website
      • cd /var/ww/website
      • git pull ~/website
      • git submodule update (a bit like in "How do I init/update a git submodule in a working tree after pushing to a bare working directory?")

    In other words:
    Pull from the bare repo instead of trying to checkout from a bare repo: a non-bare repo should be able then to accommodate the git submodule update step.

    An example script may look like

    #!/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
    
    0 讨论(0)
  • 2020-11-29 04:22

    I stumbled across this thread two days ago while I struggled with the same issue. After finally arriving at a nice, tidy solution, I wrote an article about it here:

    Git push with submodules: a how-to guide

    I realized that if I'm going to push to a bare repo, only to use post-receive to pull into a non-bare repo, I might as well just keep it simple and push directly to the non-bare repository. This is a clear case where the "best practice" of only pushing to a bare repo is only adding complexity.

    In case of link rot, I'll paste my solution here, skipping over the bits where I run into all of the same problems that I'm sure you did.


    First, let’s create a universal post-receive hook, one that I won’t need to change on a per-repository basis:

    [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
    

    Now let’s go ahead and break all the rules.

    We’re going to initialize a non-bare Git repository, right in our website directory; make sure it can receive from git push; explicitly set its working tree to its parent directory; and enable our hook we just created.

    [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/
    

    Finally, on our local machine, we’ll change our remote to reflect the location of our new repository, and push.

    [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
    

    Holy crap, it worked!

    Not only is this method compatible with submodules, it also requires just one command to set up a new remote repository (which, okay, consists of four commands). It also keeps the repository and the working tree in the same place; and with no absolute paths required in our configuration or hook files, it’s now completely portable as well.


    I hope this answer helps somebody as much as everyone else's Stack Exchange posts helped me over the last two days!

    0 讨论(0)
提交回复
热议问题