是否可以使用git push部署一个网站?我有一种预感,它与使用git挂钩来执行git重置有关——在服务器端很难,但我该如何完成这一点呢?
当前回答
从本质上讲,你所需要做的就是:
server = $1
branch = $2
git push $server $branch
ssh <username>@$server "cd /path/to/www; git pull"
我在我的应用程序中有这些行,作为一个名为deploy的可执行文件。
所以当我想要部署时,我输入。/deploy myserver mybranch。
其他回答
在经历了许多错误的开始和死胡同之后,多亏了这篇文章,我终于能够使用“git push remote”部署网站代码。
作者的更新后脚本只有一行长,并且他的解决方案不像其他一些解决方案那样需要.htaccess配置来隐藏Git回购。
如果您在Amazon EC2实例上部署它,则会遇到几个绊脚石;
1)如果使用sudo创建裸目标存储库,必须将repo的所有者更改为ec2-user,否则推送将失败。(尝试“chown ec2-user:ec2-user repo”)
2)如果你没有预先配置你的amazon-private-key的位置,推送会失败。可以在/etc/ssh/ssh_config中作为IdentityFile参数,也可以在~/。ssh/config使用“[主机]- HostName - IdentityFile - User”布局在这里描述…
...但是,如果在~/中配置了Host。ssh/config和不同于HostName的Git推送将失败。(这可能是Git的bug)
我在这个网站上找到了这个脚本,它似乎工作得很好。
复制你的。git目录到你的web服务器 在你的本地副本上,修改你的.git/config文件,并添加你的web服务器作为远程服务器: (远程“生产”) Url = username@webserver:/path/to/htdocs/.git 在服务器上,用这个文件替换。git/hooks/post-update(在下面的答案中) 添加对文件的执行访问(同样是在服务器上): Chmod +x .git/hooks/post-update 现在,只要本地推送到你的web服务器,它就会自动更新工作副本: Git推送生产
我最终创建了我自己的基本部署工具,它会自动从repo - https://github.com/jesalg/SlimJim -下拉新的更新,基本上它会监听github的接收后钩子,并使用代理来触发更新脚本。
对于post-receive hook,我使用了两种解决方案:
部署方案1
#!/bin/bash
# /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 1
export GIT_DIR=/git/repo-bare.git
export GIT_BRANCH1=master
export GIT_TARGET1=/var/www/html
export GIT_BRANCH2=dev
export GIT_TARGET2=/var/www/dev
echo "GIT DIR: $GIT_DIR/"
echo "GIT TARGET1: $GIT_TARGET1/"
echo "GIT BRANCH1: $GIT_BRANCH1/"
echo "GIT TARGET2: $GIT_TARGET2/"
echo "GIT BRANCH2: $GIT_BRANCH2/"
echo ""
cd $GIT_DIR/
while read oldrev newrev refname
do
branch=$(git rev-parse --abbrev-ref $refname)
BRANCH_REGEX='^${GIT_BRANCH1}.*$'
if [[ $branch =~ $BRANCH_REGEX ]] ; then
export GIT_WORK_TREE=$GIT_TARGET1/.
echo "Checking out branch: $branch";
echo "Checking out to workdir: $GIT_WORK_TREE";
git checkout -f $branch
fi
BRANCH_REGEX='^${GIT_BRANCH2}.*$'
if [[ $branch =~ $BRANCH_REGEX ]] ; then
export GIT_WORK_TREE=$GIT_TARGET2/.
echo "Checking out branch: $branch";
echo "Checking out to workdir: $GIT_WORK_TREE";
git checkout -f $branch
fi
done
部署方案2
#!/bin/bash
# /git-repo/hooks/post-receive - file content on server (chmod as 755 to be executed)
# DEPLOY SOLUTION 2
export GIT_DIR=/git/repo-bare.git
export GIT_BRANCH1=master
export GIT_TARGET1=/var/www/html
export GIT_BRANCH2=dev
export GIT_TARGET2=/var/www/dev
export GIT_TEMP_DIR1=/tmp/deploy1
export GIT_TEMP_DIR2=/tmp/deploy2
echo "GIT DIR: $GIT_DIR/"
echo "GIT TARGET1: $GIT_TARGET1/"
echo "GIT BRANCH1: $GIT_BRANCH1/"
echo "GIT TARGET2: $GIT_TARGET2/"
echo "GIT BRANCH2: $GIT_BRANCH2/"
echo "GIT TEMP DIR1: $GIT_TEMP_DIR1/"
echo "GIT TEMP DIR2: $GIT_TEMP_DIR2/"
echo ""
cd $GIT_DIR/
while read oldrev newrev refname
do
branch=$(git rev-parse --abbrev-ref $refname)
BRANCH_REGEX='^${GIT_BRANCH1}.*$'
if [[ $branch =~ $BRANCH_REGEX ]] ; then
export GIT_WORK_TREE=$GIT_TARGET1/.
echo "Checking out branch: $branch";
echo "Checking out to workdir: $GIT_WORK_TREE";
# DEPLOY SOLUTION 2:
cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR1;
export GIT_WORK_TREE=$GIT_TEMP_DIR1/.
git checkout -f $branch
export GIT_WORK_TREE=$GIT_TARGET1/.
rsync $GIT_TEMP_DIR1/. -v -q --delete --delete-after -av $GIT_TARGET1/.
rm -rf $GIT_TEMP_DIR1
fi
BRANCH_REGEX='^${GIT_BRANCH2}.*$'
if [[ $branch =~ $BRANCH_REGEX ]] ; then
export GIT_WORK_TREE=$GIT_TARGET2/.
echo "Checking out branch: $branch";
echo "Checking out to workdir: $GIT_WORK_TREE";
# DEPLOY SOLUTION 2:
cd $GIT_DIR/; mkdir -p $GIT_TEMP_DIR2;
export GIT_WORK_TREE=$GIT_TEMP_DIR2/.
git checkout -f $branch
export GIT_WORK_TREE=$GIT_TARGET2/.
rsync $GIT_TEMP_DIR2/. -v -q --delete --delete-after -av $GIT_TARGET2/.
rm -rf $GIT_TEMP_DIR2
fi
done
这两种解决方案都基于本文中提供的早期解决方案。
请注意, 美元BRANCH_REGEX = ' ^ $ {GIT_BRANCH1}。” 过滤匹配“master”或“dev*”字符串的分支名称,如果推送的分支匹配,则部署工作树。 这使得将开发版本和主版本部署到不同的位置成为可能。
DEPLOY SOLUTION 1仅删除文件,这些文件是repo的一部分,并由提交删除。比部署方案2快。
DEPLOY SOLUTION 2的优势在于,它将从生产目录中删除添加到服务器端的任何新文件,无论这些文件是否添加到repo。它将永远是回购的干净的欺骗。比部署方案1慢。
部署场景
在我们的场景中,我们将代码存储在github/bitbucket上,并希望将其部署到活动服务器上。 在这种情况下,以下组合对我们来说是有效的(这是这里高度好评的答案的混合):
复制你的。git目录到你的web服务器 在本地复制git远程添加live ssh://user@host:port/文件夹 在远程:git配置receive.denyCurrentBranch忽略 在远程:nano .git/hooks/post-receive并添加以下内容: #!/bin/sh GIT_WORK_TREE=/var/www/vhosts/example.org 远程:chmod +x .git/hooks/post-receive 现在你可以用git push live来推送
笔记
此解决方案适用于较旧的git版本(使用1.7和1.9进行测试) 你需要确保先推送到github/bitbucket,这样你就会有一个一致的实时回购 如果你的。git文件夹在根目录中,请确保通过添加.htaccess (source)来隐藏它: RedirectMatch 404 /\..*$
推荐文章
- 为什么我需要显式地推一个新分支?
- 如何撤消最后的git添加?
- Rubymine:如何让Git忽略Rubymine创建的.idea文件
- Gitignore二进制文件,没有扩展名
- Git隐藏错误:Git隐藏弹出并最终与合并冲突
- 了解Git和GitHub的基础知识
- 没有。Git目录的Git克隆
- Git与Mercurial仓库的互操作性
- 忽略git中修改(但未提交)的文件?
- “git restore”命令是什么?“git restore”和“git reset”之间有什么区别?
- Git合并与强制覆盖
- Git拉另一个分支
- 在Bash命令提示符上添加git分支
- 如何更改Git日志日期格式
- git pull -rebase和git pull -ff-only之间的区别