上篇我们建好了仓库,但文件还在工作区里”飘着”。这一篇讲怎么把改动真正存进版本库——也就是 提交(commit)。提交是 Git 里你用得最频繁的动作,几乎每天都会做。
把提交想成”存档点”:玩游戏时你到一个安全屋就存个档,万一后面团灭还能读档重来。Git 的每次提交就是这样一个存档点,而且每个存档点都带着”谁、什么时候、改了什么、为什么改”的信息。
暂存区:提交前的”选菜盘”
提交不是把工作区所有改动一股脑存进去,而是只存你放进暂存区的那些。这给了你精细控制的能力:你可以改了十个文件,但只提交其中三个相关的,剩下七个留着继续改。
# 把单个文件加入暂存区
git add README.md
# 把整个目录的改动都加入(谨慎使用)
git add src/
# 把所有修改过的文件加入(不包括新增的未跟踪文件)
git add -u
# 把所有改动(含新增文件)都加入
git add -A
新手最容易犯的错是 git add -A 一把梭,结果把调试用的临时文件、密码配置也一起提交了。建议少用 -A,多用指定文件名或目录,提交前 git status 看一眼暂存了什么。
提交:拍下这一刻的快照
暂存好了,就可以提交了:
git commit -m "修复登录页验证码不刷新的问题"
-m 后面跟的是提交说明,用一句话说清这次改了什么。如果说明要写多行,直接 git commit(不带 -m)会打开编辑器让你写,第一行是标题,空一行后写正文细节。
怎么写一条好提交说明
糟糕的说明:"fix"、"update"、"改了点东西"——半年后你自己都看不懂。好的说明让团队协作和回滚都轻松:
- 用祈使句、现在时:
"修复登录失败"而不是"修复了登录失败的问题"(更贴近 Git 自带信息的风格)。 - 标题控制在 50 字内,说清”做了什么”,不写”为什么”。
- 需要解释时,正文说明”为什么这么做”,比如”因为接口返回结构变了,所以调整了字段映射”。
常见前缀(约定式提交)能一眼看出改动类型:
feat: 新增用户导出功能
fix: 修复移动端菜单错位
docs: 更新部署文档
refactor: 重构支付模块,逻辑不变
chore: 升级依赖版本
查看历史:回看每一个存档点
# 最基础的日志
git log
# 一行一条,紧凑好看
git log --oneline
# 看最近 5 条
git log -5 --oneline
# 看某个文件的改动历史
git log --oneline README.md
# 看某次提交具体改了什么
git show <提交号前几位>
每条提交都有一个长长的哈希值(如 a1b2c3d...)作为唯一身份证。git log --oneline 显示的短哈希就够你引用了。
改错了提交说明怎么办
如果刚 commit 完发现说明写错了,还没推送到远程,可以补:
git commit --amend -m "正确的提交说明"
--amend 会用这次提交替换上一次提交(生成新哈希)。注意:已经推送到远程的提交不要随便 --amend,会改写历史,给别人造成麻烦。
常见新手坑
- 只
add不commit:以为加进暂存区就存好了,其实快照还没生成,回滚不了。 - 提交说明太水:
"fix"、"test"之类,日后排查问题像大海捞针。 - 一把梭
git add -A:把不该提交的文件(日志、密钥、node_modules)全交了。 - 频繁
--amend已推送的提交:改写公共历史,协作时别人拉取会冲突。
小测验
- 问题1:
git add之后、git commit之前,文件在哪个区域?答案:暂存区。 - 问题2:已经推送到远程的提交,能用
--amend随意修改吗?答案:不建议,会改写公共历史,影响协作者。 - 问题3:提交说明写
"修复了 bug"和"fix: 修复登录失败"哪个更好?答案:后者,带类型前缀且说清了具体改了什么。
更多实战:一次标准的提交长什么样
假设你改好了登录功能的两个文件,规范地提交:
git status # 确认改了哪几个文件
git add src/login.js # 只加相关的
git add src/api/auth.js
git commit -m "fix: 修复登录失败时的错误提示缺失"
git push
注意这里没有用 git add -A,而是精确指定文件——避免把调试日志、本地配置一并交了。提交说明用 fix: 前缀,半年后看历史一眼就知道这次是修 bug。
提交粒度:一次提交该多大
新手常走两个极端:要么一个提交改了二十个不相关的文件(回滚时牵一发动全身),要么改一行就提交一次(历史刷屏)。经验法则:一个提交只解决一件事。修一个 bug、加一个功能、改一次格式,各算一次提交。这样哪次提交引入问题,git revert 或 git bisect 都能精准定位。
自测:你真的懂了吗
- 为什么推荐”一个提交只做一件事”?答案:便于回滚和定位问题,哪次提交出错能精准撤销。
git commit --amend改了说明,哈希变不变?答案:变,它用新提交替换上一次,生成新哈希。- 提交说明写
"fix"和"fix: 修复登录失败"哪个好?答案:后者,带类型前缀且说清具体改了什么。
常见认知误区
关于提交,新手常踩几个坑。有人觉得”提交越频繁越好”,于是改一行就提交,历史刷成流水账,真要回滚时反而难定位;也有人走向反面,攒了一周才提交一次,结果一次提交里混了十个不相关的改动,出问题时没法单独撤销某一项。正确姿势是”一个提交只解决一件事”:修一个 bug、加一个功能、调一次格式,各算一次。还有人迷信 git commit --amend 能随意改历史,却忘了它生成的是新哈希,如果已经推送到远程,强行 amend 再 push 会扰乱协作者——未推送前随便改,推送后别乱改。最后,提交说明写 "fix"、"update" 这类水词,等于给未来的自己埋雷,半年后翻历史根本想不起当时改了什么,务必写清”做了什么、为什么”。
这一篇你该记住的
- 提交前先
git add把改动放进暂存区(建议指定文件,别老用-A)。 git commit -m "说明"生成快照;说明要用祈使句、写清”做了什么”。- 约定式提交前缀(
feat/fix/docs/...)让历史一目了然。 git log --oneline回看历史,git show <哈希>看具体改动。- 未推送的提交可用
--amend修正,已推送的不要乱改。
下一篇我们讲 分支:怎么在不影响主线的情况下开一条”实验线”开发新功能,做完再合回来——这是 Git 最强大的能力之一。