Search code examples
gitbranchgit-checkoutgit-worktree

git checkout branches for development/staging/production


I am currently restructuring how our company is handling development procedures. Since it is quite the hazzle for us to always ssh into the server to promote files/folders from DEV to STAGE/PRODUCTION servers I thought it might be a good idea to setup the git environment in a way that would allow us to simple merge the dev-branch into the stage-branch to perform a "promotion".

For this we would need 3 different branches in our projects which checkout to different locations on the server when a new push is received.

Lets say we have 3 folders on our server which contain the data for our 3 different environments (DEV - STAGE - PROD). Then the schema would look somewhat like this:

Branch checkout schema

I set up the git as bare repos and I was wondering if something of that sort is possible with git.

I will be grateful for every bit of help you guys can provide me with! :D


Solution

  • the idea is to use a post-receive hook on the server and setting a forced (-f option) checkout in a specific directory

    you can obtain a checkout in a specific working directory using the --work-tree=/path/ option...

    a sample code (to be saved on the bare repos on the server as file hooks/post-receive with execution bit set) adapted by this Gist could be:

    #!/bin/bash
    echo '--- --- --- --- --- --- --- --- --- --- ---'
    echo 'Deploying site...'
    echo '--- --- --- --- --- --- --- --- --- --- ---'
    
    if ! [ -t 0 ]; then
        read -a ref
    fi
    
    IFS='/' read -ra REF <<< "${ref[2]}"
    branch="${REF[2]}"
    
    # Master Branch
    if [ "PROD" == "$branch" ]; then
        git --work-tree=/path/to/public/PROD checkout -f $branch
        echo 'Changes pushed to production site'
    fi
    
    # Stage Branch
    if [ "STAGE" == "$branch" ]; then
        git --work-tree=/path/to/public/STAGE checkout -f $branch
        echo 'Changes pushed to stage site'
    fi
    
    # Development Branch
    if [ "DEV" == "$branch" ]; then
        git --work-tree=/path/to/public/DEV checkout -f $branch
        echo 'Changes pushed to dev site'
    fi
    
    echo '--- --- --- --- --- --- --- --- --- --- ---'   
    

    another possible sintax for the checkout is

    GIT_WORK_TREE=/path/to/test/site git checkout -f