很多草根站长管理网站代码的方式,就是打开宝塔面板或者 FTP 软件,把文件传上去,改坏了再传一次,实在不行就删掉重来。网站规模小的时候,这种做法勉强够用。可一旦代码文件多起来,或者你开始折腾主题、插件、定时脚本,问题就接踵而来:这个文件是什么时候改的?上次改了什么内容?网站突然挂了,该回退到哪个版本?两台电脑上的代码哪个才是最新的?这篇文章就来讲讲,个人站长如何用 Git 管理网站代码,再借助 Git Hook 实现推送代码后自动部署到服务器,让网站更新变成一条命令的事情。
为什么要用 Git 管理网站代码
Git 是目前世界上最流行的分布式版本控制系统,Linux 内核就是用它来管理的。对个人站长来说,Git 带来的好处非常实在:
- 版本历史:每一次修改都有完整记录,随时可以查看某个文件在任意时间点的内容,再也不会出现"改完找不到原来的代码"的尴尬。
- 一键回滚:线上出问题的时候,一条 git reset 就能把代码恢复到任意历史版本,比翻备份文件快得多。
- 大胆试验:想改版?新建一个分支随便折腾,改坏了不影响线上,满意了再合并回去。
- 多设备同步:家里电脑、办公室电脑、服务器之间轻松同步代码,不用再靠 U 盘和网盘传来传去。
- 自动部署的基础:有了 Git,配合钩子脚本,可以实现"本地提交推送,服务器自动更新",省去手动上传的麻烦。
安装与初始化 Git
Debian 和 Ubuntu 系统用 apt 安装,CentOS 和 Rocky Linux 用 yum 或 dnf 安装:
# Debian / Ubuntu
sudo apt update
sudo apt install -y git
# CentOS / Rocky Linux
sudo yum install -y git
git --version安装完成后,先配置用户名和邮箱,这个信息会记录在每一次提交里,方便以后追溯是谁改的代码:
git config --global user.name "YourName"
git config --global user.email "you@example.com"然后进入网站根目录,初始化一个仓库。以常见的 /var/www/html 为例:
cd /var/www/html
git init
git statusgit status 会显示当前仓库的状态,包括哪些文件是新增的、哪些被修改过。第一次使用,你会看到一大堆未跟踪的文件,不要慌,下一步先写好 .gitignore 再提交。
日常提交:把修改记录下来
Git 的工作流程很简单:修改文件后,用 git add 把改动加入暂存区,再用 git commit 提交,形成一个新的版本:
git add . # 添加所有修改
git add index.php # 也可以只添加某个文件
git commit -m "修复首页标题乱码问题"几个最常用的查看命令:
- git status:查看工作区状态,哪些文件改过了。
- git log --oneline:查看提交历史,每一行就是一个版本。
- git diff:查看尚未提交的具体改动内容。
- git show 版本号:查看某个历史提交的完整内容。
提交信息建议写得清楚一点,比如"修复搜索页 500 错误"就比"update"有价值得多。几个月后再看历史,你能快速知道每个版本干了什么。
.gitignore:不该提交的文件千万别提交
网站目录里有很多文件是不需要、也不应该进入版本库的,比如用户上传的图片、缓存文件、日志、数据库备份、包含密码的配置文件。解决办法是在仓库根目录创建 .gitignore 文件:
# 用户上传与缓存
/usr/uploads/
/var/cache/
*.log
# 敏感配置与备份
.env
config.inc.php
backup*.sql
*.sql.gz
# 系统与编辑器文件
.DS_Store
*.swp特别注意:包含数据库密码、API 密钥的文件一旦提交进 Git 历史,即使之后删掉,也仍然存在于历史记录里,非常危险。所以 .gitignore 要在一开始就写好,宁可多排除,不要少排除。
推送到远程仓库:给代码上双保险
只在服务器本地做版本管理还不够,万一服务器硬盘坏了,代码还是会丢。建议把仓库推到 Gitee 或 GitHub 的私有仓库,相当于多了一份异地备份。先在本地生成 SSH 密钥,把公钥添加到代码托管平台:
ssh-keygen -t ed25519 -C "you@example.com"
cat ~/.ssh/id_ed25519.pub然后在 Gitee 或 GitHub 上新建一个私有仓库,把本地仓库关联上去并推送:
git remote add origin git@gitee.com:username/mywebsite.git
git push -u origin master推送成功后,本地、服务器、代码托管平台三处都有完整的代码历史,任何一处出问题都能恢复。
分支与回滚:出问题不慌张
个人站长不必把分支用得太复杂,但两个基本场景要会:
- 开分支做试验:git checkout -b test 新建并切换到 test 分支,随便改,满意了用 git checkout master 切回主分支再合并。
- 线上回滚:git log --oneline 找到出问题之前那个版本的编号,执行 git reset --hard 版本号 把代码整体回退,网站立刻恢复。
建议线上环境永远只使用主分支,新功能都在分支上测试好了再合并,这样线上代码始终是可控的。
Git Hook 自动部署:推送即上线
版本管理解决的是"代码怎么存",自动部署解决的是"代码怎么上线"。最经典的做法是在服务器上建一个裸仓库,利用 Git 的 post-receive 钩子,在收到推送后自动把代码同步到网站目录。先在服务器上创建裸仓库:
sudo mkdir -p /home/git/site.git
cd /home/git/site.git
sudo git init --bare然后创建钩子脚本 /home/git/site.git/hooks/post-receive,内容如下:
#!/bin/bash
GIT_WORK_TREE=/var/www/html git checkout -f
chown -R www-data:www-data /var/www/html
echo "网站代码已自动更新"给脚本加上执行权限:
sudo chmod +x /home/git/site.git/hooks/post-receive以后在本地电脑上,把远程地址指向这个裸仓库,推送一次,网站代码就自动更新一次:
git remote add deploy root@你的服务器IP:/home/git/site.git
git push deploy master推送到线上仓库的分支请谨慎,建议部署仓库只接受主分支的推送,配合 hook 里检查分支名,防止误推把开发中的代码直接上线。
常用命令速查
用久了你会发现,Git 日常来来回回就那么几条命令,整理成速查表放在手边,用的时候一眼就能找到:
- git init:在当前目录初始化仓库,只需要做一次。
- git add 文件名:把指定文件的修改加入暂存区,用 git add . 添加全部。
- git commit -m "说明":把暂存区的内容提交成一个新版本。
- git status:查看当前状态,哪些文件改过、哪些还没提交。
- git log --oneline:按行查看提交历史,版本号一目了然。
- git diff:查看还没暂存的修改内容,提交前检查必用。
- git checkout -- 文件名:放弃某个文件未提交的修改,恢复到上次提交的状态。
- git reset --hard 版本号:把整个项目回退到指定版本,慎用,会丢掉之后的提交。
- git branch:列出本地分支,前面带星号的是当前所在分支。
- git pull:从远程仓库拉取最新代码并合并到本地。
- git push:把本地提交推送到远程仓库。
建议把 git status 和 git diff 变成肌肉记忆:每次提交前看一眼,能避免大量"改错了还提交了"的低级失误。个人站长的代码就是网站本身,提交之前多花十秒钟检查,上线之后就能少折腾一个小时。
注意事项与安全建议
- 密钥密码不进仓库:数据库密码、API 密钥用环境变量或单独的不入库配置文件管理,仓库里只放示例文件。
- 数据库不进仓库:数据库内容变化频繁且包含用户数据,用 mysqldump 定时备份,不要纳入 Git 管理。
- 自动部署不等于自动备份:Git 管的是代码,数据备份仍然要靠数据库定时备份和整站备份,两者互补而不是替代。
- 配置差异问题:本地、测试、生产环境的配置可能不同,部署脚本里不要覆盖线上已有的配置文件,或者在 .gitignore 里排除它们。
- 推送前先看 diff:养成 git diff 的习惯,确认要提交的就是你想提交的内容,避免把调试代码一起推上去。
常见问题
问:误提交了大文件怎么办?答:如果文件还在工作区,git rm --cached 文件名 可以把它从版本库移除;如果已经推送到远程,需要重写历史,建议直接把这个文件加入 .gitignore,以后不再提交即可,历史里的大文件可以等仓库重建时清理。
问:服务器上要不要也 git init?答:如果用了 Git Hook 自动部署,网站目录由裸仓库的钩子更新,不需要在网站目录里再 init 一个仓库,否则容易冲突。
问:Git 和 rsync 备份冲突吗?答:不冲突。Git 管代码版本,rsync 管整站文件快照,两者是不同层面的保障,配合使用最稳妥。
问:网站文件被篡改(挂马)了,Git 能帮忙吗?答:能。如果入侵者改了文件,git status 会立刻显示哪些文件被改动,git diff 能看出被改了什么,git checkout 能快速恢复原文件,这也是 Git 给网站安全带来的额外好处。