我在服务器上创建了一个裸git repo并设置了this blog的以下post-receive挂钩:
#!/bin/bash
while read oldrev newrev ref
do
branch=`echo $ref | cut -d/ -f3`
if [ "master" == "$branch" ]; then
git --work-tree=/path/to/my/project/live/ checkout -f $branch
echo 'Changes pushed live.'
fi
if [ "develop" == "$branch" ]; then
git --work-tree=/path/to/my/project/dev/ checkout -f $branch
echo 'Changes pushed to dev.'
fi
done
因此,每当我将本地推送到我的服务器时,更改将自动发布在每个分支的文件夹上,而无需手动拉取。
我为dev文件夹设置了正确的权限:
drwxrwsr-x 2 git git 4096 Sep 29 12:10 live/
drwxrwsr-x 2 git git 4096 Sep 29 12:09 dev/
从开发分支推动按预期工作。检查主分支并执行合并时会发生此问题。当我推送主文件时,新文件会被复制到我服务器上的实时文件夹中,但我在本地删除的文件不会被删除。
如何使收件后正确更新实时文件夹?谢谢!
答案 0 :(得分:4)
我遇到了同样的问题。正在研究rsync将tmp文件夹文件复制到实时文件夹,但后来我想到为什么不在工作树上使用git glean。
我不确定这是不是很糟糕,但它应该只从文件夹中删除未跟踪的文件,并使用.gitignore设置不删除不在您的仓库中的文件。
它似乎完成了我想要的东西,即清除未被推送删除的文件。
#!/bin/sh
while read oldrev newrev refname
do
branch=$(git rev-parse --symbolic --abbrev-ref $refname)
if [ "master" == "$branch" ]; then
GIT_WORK_TREE=/home/store/public_html git checkout -f master
GIT_WORK_TREE=/home/store/public_html git clean -fd
fi
if [ "test" == "$branch" ]; then
GIT_WORK_TREE=/home/store/test_html git checkout -f test
GIT_WORK_TREE=/home/store/test_html git clean -fd
fi
if [ "dev" == "$branch" ]; then
GIT_WORK_TREE=/home/store/dev_html git checkout -f dev
GIT_WORK_TREE=/home/store/dev_html git clean -fd
fi
done
答案 1 :(得分:3)
问题是git不知道要删除什么(它在工作树中没有索引,跟踪这些事情)。应该可以使用每个工作树的索引来解决这个问题,但我认为将git checkout -f
放入一个新的空目录,然后重命名新目录和旧目录以使新版本“go”更简单生活”。这也缩小了竞争条件窗口:现在只有一个短暂的时刻(mv
次操作之间) no 版本,而不是稍长的窗口(checkout
期间)当旧版本和新版本混合使用时。
注意:如果有一个名为master
或develop
的标记,则您显示的脚本会出错,因为这两个标记的引用名称分别为refs/tags/master
和refs/tags/develop
。我建议通过shell函数和case
语句修复此问题(如果你关心:-)),以减少非部署情况下的进程产生,例如:
die() {
echo "$@" >&2
exit 1
}
# deploy (to given path, $1) the version named by $2
# if the target is /some/path/there we use a temp version
# named /some/path/tmp.<pid> to hold the new one until we
# can swap it out, and $1.old.<pid> while we remove the old.
deploy() {
local path=$1 branch=$2
local tmpdir=${path%/*}/tmp.$$ # tune this as needed
echo "deploying $branch to $path via $tmpdir..."
trap "rm -rf $tmpdir" 0 1 2 3 15
mkdir $tmpdir || die "can't create work dir $tempdir"
git --work-tree=$tmpdir/ checkout -f $branch
mv $path $path.old.$$ ||
die "unable to move live version out of the way"
mv $tmpdir $path ||
die "unable to set new version live"
trap - 0 1 2 3 15
echo "done, cleaning up old version"
rm -rf $path.old.$$
}
while read oldrev newrev ref; do
case $ref in
refs/heads/master) deploy /path/to/my/project/live master;;
refs/heads/develop) deploy /path/to/my/project/dev develop;;
esac
done
(注意:完全未经测试)。