如何将推送的分支复制到另一个目录?

时间:2015-04-24 12:54:28

标签: git ubuntu githooks

我有一个名为master(生产)的分支,另一个名为development。当我从master推送提交时,post-receive钩子执行:

git --work-tree=/var/www/mywebsite.com --git-dir=/var/repo/mywebsite.com.git checkout -f

网站现场直播。但我希望将development分支复制到/var/www/mywebsite.com.dev。

1 个答案:

答案 0 :(得分:1)

What you're trying to do by hand is what tools like Capistrano are meant for, and they will do it better (for example, your version is not atomic so your website has a mix of old/new files for a while, while capistrano will check out your tree in a directory, and then point a symlink to it, which is atomic).

If you stay with "git checkout", then "git checkout development" will checkout the development branch, so you want to execute this command when you receive a ref update on development. The script would go along the lines of:

#!/bin/sh

while read old new refname
do
    case "$refname" in
        refs/heads/master)
            git --work-tree=/var/www/mywebsite.com --git-dir=/var/repo/mywebsite.com.git checkout -f
            ;;
        refs/heads/development)
            git --work-tree=/var/www/mywebsite.com.dev --git-dir=/var/repo/mywebsite.com.git checkout -f refs/heads/development
            ;;
    esac
done

Now, we can improve the script in several ways:

  • Actually, since the hook receives the new ref value, you don't even need the branch name, and can use $new instead (more robust in case there are several ref updates close to each other in time).

  • For efficiency we can maintain one index file per checkout (so that unmodified files do not need to be actually checked-out)

  • The --git-dir option can be dropped, since we're checking out from the current directory (the hook is executed within the repository).

The improved script is:

#!/bin/sh

while read old new refname
do
    case "$refname" in
        refs/heads/master)
            GIT_INDEX_FILE="$PWD"/index.master git --work-tree=/tmp/www/mywebsite.com checkout -f $new
            ;;
        refs/heads/development)
            GIT_INDEX_FILE="$PWD"/index.development git --work-tree=/tmp/www/mywebsite.com.dev checkout -f $new
            ;;
    esac
done

On a related subject, you can also look at the new updateInstead value for receive.denyCurrentBranch introduced in Git 2.3. See for example the "Push to deploy" section on https://github.com/blog/1957-git-2-3-has-been-released