使用git push
是否可以部署网站?我有一种预感这与使用git hooks在服务器端执行git reset --hard
有关,但我该如何完成它呢?
使用git push
是否可以部署网站?我有一种预感这与使用git hooks在服务器端执行git reset --hard
有关,但我该如何完成它呢?
在您的本地副本上,修改您的.git/config文件并将Web服务器添加为远程主机:
[remote "production"]
url = username@webserver:/path/to/htdocs/.git
在服务器上,使用这个文件替换.git/hooks/post-update
给该文件添加执行权限(同样在服务器上):
chmod +x .git/hooks/post-update
现在,只需将更改推送到您的Web服务器,它就应该自动更新工作副本: git push production
使用以下的post-update文件:
在本地副本上,修改你的.git/config文件并将你的web服务器作为一个远程仓库添加:
[remote "production"]
url = username@webserver:/path/to/htdocs/.git
在服务器上,用下面的文件替换.git/hooks/post-update
给该文件添加执行权限(同样在服务器上):
chmod +x .git/hooks/post-update
现在,只需将更改推送到您的 Web 服务器上,它应该会自动更新工作副本: git push production
#!/bin/sh
#
# This hook does two things:
#
# 1. update the "info" files that allow the list of references to be
# queries over dumb transports such as http
#
# 2. if this repository looks like it is a non-bare repository, and
# the checked-out branch is pushed to, then update the working copy.
# This makes "push" function somewhat similarly to darcs and bzr.
#
# To enable this hook, make this file executable by "chmod +x post-update".
git-update-server-info
is_bare=$(git-config --get --bool core.bare)
if [ -z "$is_bare" ]
then
# for compatibility's sake, guess
git_dir_full=$(cd $GIT_DIR; pwd)
case $git_dir_full in */.git) is_bare=false;; *) is_bare=true;; esac
fi
update_wc() {
ref=$1
echo "Push to checked out branch $ref" >&2
if [ ! -f $GIT_DIR/logs/HEAD ]
then
echo "E:push to non-bare repository requires a HEAD reflog" >&2
exit 1
fi
if (cd $GIT_WORK_TREE; git-diff-files -q --exit-code >/dev/null)
then
wc_dirty=0
else
echo "W:unstaged changes found in working copy" >&2
wc_dirty=1
desc="working copy"
fi
if git diff-index --cached HEAD@{1} >/dev/null
then
index_dirty=0
else
echo "W:uncommitted, staged changes found" >&2
index_dirty=1
if [ -n "$desc" ]
then
desc="$desc and index"
else
desc="index"
fi
fi
if [ "$wc_dirty" -ne 0 -o "$index_dirty" -ne 0 ]
then
new=$(git rev-parse HEAD)
echo "W:stashing dirty $desc - see git-stash(1)" >&2
( trap 'echo trapped $$; git symbolic-ref HEAD "'"$ref"'"' 2 3 13 15 ERR EXIT
git-update-ref --no-deref HEAD HEAD@{1}
cd $GIT_WORK_TREE
git stash save "dirty $desc before update to $new";
git-symbolic-ref HEAD "$ref"
)
fi
# eye candy - show the WC updates :)
echo "Updating working copy" >&2
(cd $GIT_WORK_TREE
git-diff-index -R --name-status HEAD >&2
git-reset --hard HEAD)
}
if [ "$is_bare" = "false" ]
then
active_branch=`git-symbolic-ref HEAD`
export GIT_DIR=$(cd $GIT_DIR; pwd)
GIT_WORK_TREE=${GIT_WORK_TREE-..}
for ref
do
if [ "$ref" = "$active_branch" ]
then
update_wc $ref
fi
done
fi
不要在服务器上安装 Git 或复制 .git 文件夹。 要从 Git 克隆更新服务器,可以使用以下命令:
git ls-files -z | rsync --files-from - --copy-links -av0 . user@server.com:/var/www/project
你可能需要删除已从项目中移除的文件。
这将复制所有被选中的文件。rsync 使用在服务器上已经安装的 ssh。
你在服务器上安装的软件越少,它就越安全,也更容易管理其配置和文档。并且没有必要在服务器上保留完整的 git 克隆。这只会使一切变得更加复杂,更难以正确地保护所有内容。
git config --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的公告上提到:
但所有这些问题都超出了Git的范畴,必须由外部代码来解决。因此,在这个意义上,这个方法与Git hooks一起是终极解决方案。
基本上你只需要做以下几点:
server = $1
branch = $2
git push $server $branch
ssh <username>@$server "cd /path/to/www; git pull"
我在我的应用程序中有这些行作为可执行文件 deploy
。
所以当我想要部署时,我键入 ./deploy myserver mybranch
。
ssh -A ...
- Karussellgit pull
,因为合并部分可能需要手动清理,如果存在任何冲突。 - Quinn Comendant我个人的做法是在我的部署服务器上有一个裸的Git仓库,然后我将更改推送到这里。接着我登录进部署服务器,切换到实际的Web服务器文档目录,并执行git pull命令。我不使用任何钩子来自动化此过程,因为这样做似乎会带来更多麻烦。
git reset
来向后移动到最新的更改(所有提交,而不仅仅是整个pull)。如果您需要回滚某些特定的东西,而不是最新的提交,那么可以使用git revert
,但这应该只在紧急情况下使用( git revert
创建一个新的提交,以撤消某个先前提交的影响)。 - Greg Hewgill在我们的方案中,我们将代码存储在 github/bitbucket 上,并希望部署到实时服务器上。 在这种情况下,以下组合对我们有用(这是高赞答案的混合体):
.git
目录复制到你的 Web 服务器上git remote add live ssh://user@host:port/folder
git config receive.denyCurrentBranch ignore
在远程: nano .git/hooks/post-receive
并添加以下内容:
#!/bin/sh
GIT_WORK_TREE=/var/www/vhosts/example.org git checkout -f
在远程: chmod +x .git/hooks/post-receive
git push live
推送到远程了如果你的 .git
文件夹在文档根目录中,请确保通过将以下内容添加到 .htaccess
(来源)来从外部隐藏它:
RedirectMatch 404 /\..*$
cap deploy
cap deploy:start_rsync (when the staging is ok)
cap deploy:rollback
cap deploy:start_rsync
ssh -A...
。从主存储库推送,然后在所有计算机上并行地从中拉取速度更快,需要的设置更少。
[remote "amazon"]
url = amazon:/path/to/project.git
fetch = +refs/heads/*:refs/remotes/amazon/*
但是,嘿,那个有关于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'