是否可以使用git push部署一个网站?我有一种预感,它与使用git挂钩来执行git重置有关——在服务器端很难,但我该如何完成这一点呢?
当前回答
更新:我现在使用Lloyd Moore解决方案与密钥代理ssh -A ....推入一个主回购,然后从所有机器上并行地从主回购中提取,这稍微快一些,在这些机器上需要的设置也更少。
这里没有解。如果服务器上安装了git,只需通过SSH推送即可。
在本地的.git/配置中需要以下条目
[remote "amazon"]
url = amazon:/path/to/project.git
fetch = +refs/heads/*:refs/remotes/amazon/*
但是嘿,亚马逊是怎么回事?在你的本地~/。Ssh /config你需要添加以下条目:
Host amazon
Hostname <YOUR_IP>
User <USER>
IdentityFile ~/.ssh/amazon-private-key
现在你可以打电话
git push amazon master
ssh <USER>@<YOUR_IP> 'cd /path/to/project && git pull'
(顺便说一句:/ /项目/路径。Git与实际的工作目录/路径/到/项目不同)
其他回答
更新:我现在使用Lloyd Moore解决方案与密钥代理ssh -A ....推入一个主回购,然后从所有机器上并行地从主回购中提取,这稍微快一些,在这些机器上需要的设置也更少。
这里没有解。如果服务器上安装了git,只需通过SSH推送即可。
在本地的.git/配置中需要以下条目
[remote "amazon"]
url = amazon:/path/to/project.git
fetch = +refs/heads/*:refs/remotes/amazon/*
但是嘿,亚马逊是怎么回事?在你的本地~/。Ssh /config你需要添加以下条目:
Host amazon
Hostname <YOUR_IP>
User <USER>
IdentityFile ~/.ssh/amazon-private-key
现在你可以打电话
git push amazon master
ssh <USER>@<YOUR_IP> 'cd /path/to/project && git pull'
(顺便说一句:/ /项目/路径。Git与实际的工作目录/路径/到/项目不同)
对于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慢。
我使用toroid.org的以下解决方案,它有一个更简单的钩子脚本。
服务器端:
$ mkdir website.git && cd website.git
$ git init --bare
Initialized empty Git repository in /home/ams/website.git/
并在服务器上安装钩子:
$ mkdir /var/www/www.example.org
$ cat > hooks/post-receive
#!/bin/sh
GIT_WORK_TREE=/var/www/www.example.org git checkout -f
GIT_WORK_TREE=/var/www/www git clean -f -d # clean directory from removed files
$ chmod +x hooks/post-receive
在您的客户端:
$ mkdir website && cd website
$ git init
Initialized empty Git repository in /home/ams/website/.git/
$ echo 'Hello, world!' > index.html
$ git add index.html
$ git commit -q -m "The humble beginnings of my web site."
$ git remote add web ssh://server.example.org/home/ams/website.git
$ git push web +master:refs/heads/master
然后要发布,只需输入
$ git push web
网站上有完整的描述:http://toroid.org/ams/git-website-howto
git配置——local receive.denyCurrentBranch updateInstead
在Git 2.3中添加了一个很好的可能性:https://github.com/git/git/blob/v2.3.0/Documentation/config.txt#L2155
您在服务器存储库上设置它,如果工作树是干净的,它也会更新工作树。
在2.4中有进一步的改进,包括push-to-checkout钩子和未出生分支的处理。
示例用法:
git init server
cd server
touch a
git add .
git commit -m 0
git config --local receive.denyCurrentBranch updateInstead
cd ..
git clone server local
cd local
touch b
git add .
git commit -m 1
git push origin master:master
cd ../server
ls
输出:
a
b
这确实有以下GitHub公告中提到的缺点:
Your server will contain a .git directory containing the entire history of your project. You probably want to make extra sure that it cannot be served to users! During deploys, it will be possible for users momentarily to encounter the site in an inconsistent state, with some files at the old version and others at the new version, or even half-written files. If this is a problem for your project, push-to-deploy is probably not for you. If your project needs a "build" step, then you will have to set that up explicitly, perhaps via githooks.
但是所有这些点都超出了Git的范围,必须由外部代码来处理。因此,从这个意义上说,这和Git钩子一起是最终的解决方案。
我们使用capistrano来管理部署。 我们构建capistrano以部署在登台服务器上,然后与我们所有的服务器运行rsync。
cap deploy
cap deploy:start_rsync (when the staging is ok)
使用capistrano,我们可以在出现bug时轻松回滚
cap deploy:rollback
cap deploy:start_rsync
推荐文章
- 当git说它正在“解析delta”时,它实际上在做什么?
- Git命令将一个文件夹移动到另一个文件夹
- 在单个文件中重新启动/撤消冲突解决方案
- Visual Studio代码如何解决合并冲突与git?
- 无法推送到远程分支,无法解析到分支
- Git:如何将数据库重置为特定的提交?
- 如何在合并期间使用Git和命令行保存本地文件或远程文件?
- 能够用一个命令推到所有git遥控器?
- 重新基于Git合并提交
- 忽略已经签入目录的内容?
- 如何从windows cmd保存git提交消息?
- (Mac) -bash: __git_ps1:命令未找到
- 如何删除多个已删除的文件在Git仓库
- 使用vimdiff查看所有' git diff '
- 如何拉特定的目录与git