把代码用git发送到服务器,核心思路不是直接“传文件”,而是先在服务器上建一个“裸仓库”,再通过SSH协议把本地提交推上去,最后用钩子自动同步到站点目录。这个过程听起来绕,但一旦跑通,以后发版就是一条git push命令的事,下面把完整步骤、常见坑和方案选型一次讲清楚。
为什么你不能直接对服务器执行“git推送到服务器”
很多新手会尝试在本地执行`git push 服务器IP地址`,结果要么被拒,要么提示找不到仓库,原因在于服务器上必须有一个以.git结尾的裸仓库,裸仓库没有工作目录,只存储版本历史,专门用来接收推送。
行业共识认为,裸仓库是git服务器部署的基石,它相当于一个“中转站”,本地代码推送到它这里,再由它同步到真正的网页目录(比如/var/www/html),如果不经过这一步,直接推送到普通文件夹,git会报错receiving.denyCurrentBranch,因为服务器端工作区正在被占用。
git部署代码到服务器步骤:从零到自动化
下面这套流程,适合Linux服务器(Ubuntu/Debian系),需要你有SSH登录权限,整个过程大约10分钟。
第一步:服务器安装git并创建裸仓库
先登录服务器,更新源并安装git:
sudo apt update sudo apt install git -y
然后创建一个专门存放仓库的文件夹,比如/home/git,在这里初始化裸仓库:
cd /home/git git init --bare myproject.git
看到Initialized empty Git repository提示,就成功了,此时myproject.git就是你的“接收端”。
第二步:本地添加远程地址
回到本地电脑,打开项目文件夹,如果你还没有初始化git,先执行:
git init git add . git commit -m "initial commit"
接着添加远程服务器地址:
git remote add origin 用户名@服务器IP:/home/git/myproject.git
注意把用户名替换成真实登录账号,服务器IP换成实际地址,最后推送:
git push -u origin master
这一步会要求输入服务器密码,如果看到“master -> master”的输出,代码就算“发送”到服务器了。
第三步:配置钩子让代码自动同步到网站目录
但现在代码还躺在裸仓库里,网站访问不到,需要写一个钩子脚本,让每次推送后自动把文件复制到站点目录。
进入服务器的裸仓库钩子目录:
cd /home/git/myproject.git/hooks vim post-receive
#!/bin/sh GIT_WORK_TREE=/var/www/myproject git checkout -f
第一行声明用shell执行,第二行的GIT_WORK_TREE指定站点目录,checkout -f强制检出文件,保存后赋予执行权限:
chmod +x post-receive
之后你本地执行git push,代码就会自动出现在/var/www/myproject里,如果站点目录有特殊权限需求,比如需要写入图片,别忘了chown -R www-data:www-data /var/www/myproject。
git推送代码到远程服务器时,分支怎么管理
实际操作中,你可能会碰到多个环境:测试服、预发布服、正式服,聪明做法是用分支对应环境。
用不同分支推不同服务器
比如测试服务器对应`develop`分支,正式服务器对应`master`分支,本地推送时指定分支:
git push origin develop
然后在测试服务器的hook里加上分支判断,避免开发分支代码冲到正式环境,在post-receive脚本开头加一行:
if [ "$refname" = "refs/heads/master" ]; then GIT_WORK_TREE=/var/www/production git checkout -f fi
如果推的是develop,正式目录就不会被更新。
分支回滚别用“删库跑路”
代码出问题要回滚,简洁做法是本地强制推旧提交:
git reset --hard HEAD~1 git push origin master -f
但-f会覆盖服务器历史,多人协作时慎用,更稳妥是用git revert生成反向提交,虽然历史多了点,但不会丢记录。
git代码部署服务器哪种方式好:自建裸仓库 vs Git服务端 vs 面板工具
自建裸仓库适合10人以内团队,但每次改钩子、管权限比较费事,下面用表格对比主流方案:
| 方案 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| 裸仓库+Hooks | 轻量、免费、可控性高 | 需要服务器运维能力 | 个人项目、小团队 |
| GitLab/Gitea | 有Web界面、权限管理、MR流程 | 吃内存,至少2G RAM | 中等团队,需要代码审查 |
| 宝塔WebHook | 界面化操作,点几下就行 | 依赖面板,自动化弱 | 不想写命令行的人 |
业内专家指出,情况合适时选择自建裸仓库仍是主流方式,因为它的哲学最贴近git本质:推送和同步都发生在同一台机器上,延迟最低。
宝塔面板的部署路径
如果你用宝塔,可以在软件商店安装“WebHook”插件,然后git项目里配置推送地址:
git remote add origin http://服务器IP:端口/webhook?token=你的密钥
推送后宝塔会自动执行预设的shell脚本,通常是cd /www/wwwroot/项目目录 && git pull,这个方案省去了SSH密钥配置,适合新手。
git怎么把代码上传到服务器常见问题排查
推送过程经常碰到报错,下面几个高频问题直接给解法。
提示“Permission denied (publickey)”
说明SSH密钥没配对,检查本地有`~/.ssh/id_rsa`(私钥),服务器`~/.ssh/authorized_keys`里有`id_rsa.pub`(公钥),没有就执行:
ssh-keygen -t rsa -b 4096 ssh-copy-id 用户名@服务器IP
推送成功但网站没变
多半是hook里的站点目录路径不对,先在服务器上手动执行`git checkout -f`,看是否报错“找不到仓库”,如果目录有文件但没更新,检查`post-receive`脚本是不是忘了加`chmod +x`。
push时要求输入密码但无法交互
这种情况出现在用HTTP协议而不是SSH协议,确认远程地址以`git@`开头,或者配置credential helper缓存密码。
Q&A:相关高频搜索整理
git部署代码到服务器会不会覆盖现有文件
会,`git checkout -f`会强制覆盖工作区文件,如果目录里有非git管理的文件(比如用户上传的图片),会被保留,前提是这些文件没有和仓库里的文件同名冲突,建议把upload目录写进`.gitignore`,避免重要数据被误删。
git推送代码到远程服务器后,本地和服务器如何保持一致
推送本身是单向的:本地传到服务器,服务器上有本地没有的提交(比如直接在服务器改了文件),下次推送会报冲突,解决方法是推送前先`git pull origin master`拉取服务器最新记录,解决冲突后再推送。
用git部署网站到服务器安全吗
相对安全,前提是开启SSH密钥登录并禁用密码登录,密钥登录比密码更难暴力破解,而且git钩子只执行你定义的同步命令,不会暴露数据库密码等敏感信息,除非你主动把配置文件推送上去,建议将`.env`、数据库密码文件加入`.gitignore`,不上传服务器仓库。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/746528.html





