Git 是一个分布式版本控制系统——帮你记录文件的每一次修改,可以随时回到之前的任何版本。
| 没有 Git 时 | 有了 Git 后 |
|---|---|
文件命名:项目_v1、项目_v2、项目_最终版、项目_最终最终版 |
一个文件夹,所有历史版本自动记录 |
| 改坏了代码不知道怎么恢复 | git checkout 一秒回到之前的版本 |
| 多人协作靠 U 盘拷来拷去 | 每个人各自开发,git merge 自动合并 |
| 不知道谁改了哪一行 | git blame 精确定位每一行的修改者和时间 |
| 不敢大胆尝试新功能 | 开个分支随便改,不影响主代码 |
| 概念 | 是什么 | 类比 |
|---|---|---|
| Git | 版本控制工具,装在你电脑上 | 本地的日记本 |
| GitHub | 在线代码托管平台(国外) | 云端备份 + 社交网络 |
| Gitee | 在线代码托管平台(国内) | 国内版 GitHub |
Git 是工具本身,GitHub/Gitee 是存放代码的云端平台。你可以只用 Git 不用 GitHub,但不能只用 GitHub 不装 Git。
- 访问 https://git-scm.com/download/win 下载安装包
- 双击运行,一路点 Next(默认配置即可)
- 安装完成后,右键桌面空白处,看到 "Git Bash Here" 说明安装成功
git --version
# 输出类似:git version 2.44.0 说明成功安装后第一件事——告诉 Git 你是谁:
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"这个名字和邮箱会出现在每一次提交记录里。建议用真实信息,尤其是邮箱要和 GitHub/Gitee 注册邮箱一致。
Git 管理文件时,有三个关键区域:
工作区(Working Directory)
│
│ git add
▼
暂存区(Staging Area)
│
│ git commit
▼
本地仓库(Repository)
│
│ git push
▼
远程仓库(Remote,如 GitHub)
| 区域 | 说明 | 类比 |
|---|---|---|
| 工作区 | 你实际编辑文件的地方 | 你的书桌 |
| 暂存区 | 选好了准备提交的文件 | 把要交的作业放进书包 |
| 本地仓库 | 正式保存的历史记录 | 作业交到老师手里 |
| 远程仓库 | 云端备份(GitHub/Gitee) | 作业存档在学校系统里 |
未跟踪 (Untracked) ──git add──▶ 已暂存 (Staged)
│
已修改 (Modified) ──git add──▶ │
│
git commit
│
▼
未修改 (Unmodified)
- Untracked:新建的文件,Git 还不认识它
- Modified:已跟踪的文件被修改了,但还没放进暂存区
- Staged:文件已经放进暂存区,等待提交
- Unmodified:文件和上次提交一致,没有变化
# 新建项目文件夹并进入
mkdir my-project
cd my-project
# 初始化 Git 仓库
git init
# 输出:Initialized empty Git repository in .../my-project/.git/# 创建一个文件
echo "print('Hello, Git!')" > hello.py
# 查看状态——会显示 hello.py 为 Untracked
git status
# 添加到暂存区
git add hello.py
# 再次查看状态——hello.py 变为 Staged(绿色)
git status
# 提交到本地仓库
git commit -m "feat: 添加 hello.py 文件"# 简洁版——推荐日常使用
git log --oneline
# 输出示例:
# a1b2c3d feat: 添加 hello.py 文件
# 详细版
git log
# 图形化版(查看分支合并历史)
git log --oneline --graph --all# 查看工作区和暂存区的差异(还没 add 的改动)
git diff
# 查看暂存区和上次提交的差异(已经 add 的改动)
git diff --staged| 场景 | 命令 |
|---|---|
| 修改了文件,想恢复到上次提交的状态 | git checkout -- 文件名 |
已经 git add,想从暂存区撤回 |
git reset HEAD 文件名 |
已经 git commit,想修改提交信息 |
git commit --amend -m "新信息" |
已经 git commit,想撤销这次提交但保留修改 |
git reset --soft HEAD~1 |
| 想彻底回到某次提交(危险,会丢失修改) | git reset --hard 提交ID |
有些文件不应该被 Git 跟踪(比如密码文件、临时文件、依赖包等)。在项目根目录创建 .gitignore 文件:
# Python 相关
__pycache__/
*.pyc
.venv/
# 编辑器相关
.vscode/
.idea/
# 系统文件
.DS_Store
Thumbs.db
# 环境变量/密钥
.env
*.key建议在项目开始时就创建
.gitignore,避免不小心提交敏感信息。
分支让你可以从主线代码"岔开",在不影响主线的情况下开发新功能或修复 bug。
feature-login
/ \
main ●──●──●──●────────●──●──▶
\ /
fix-bug
# 查看所有分支(*号标记当前分支)
git branch
# 创建新分支
git branch feature-login
# 切换到新分支
git checkout feature-login
# 或者用更新的命令(推荐)
git switch feature-login
# 创建并切换(一步到位)
git checkout -b feature-login
# 或
git switch -c feature-login
# 切回主分支
git switch main
# 合并分支(先切到主分支,再合并)
git switch main
git merge feature-login
# 删除已合并的分支
git branch -d feature-login| 前缀 | 用途 | 示例 |
|---|---|---|
feature/ |
新功能 | feature/user-login |
fix/ |
修复 bug | fix/login-crash |
docs/ |
文档修改 | docs/update-readme |
refactor/ |
代码重构 | refactor/api-module |
当两个分支修改了同一个文件的同一个位置时,Git 无法自动合并,会产生冲突(conflict)。
冲突文件中会出现这样的标记:
<<<<<<< HEAD
这是当前分支的内容
=======
这是要合并进来的分支的内容
>>>>>>> feature-login
解决步骤:
- 打开冲突文件,手动选择保留哪部分(或合并两边的内容)
- 删除
<<<<<<<、=======、>>>>>>>标记 git add 冲突文件git commit(Git 会自动生成合并提交信息)
# HTTPS 方式
git clone https://github.com/用户名/仓库名.git
# SSH 方式(需要先配置 SSH Key)
git clone git@github.com:用户名/仓库名.git# 如果本地已有项目,想推送到 GitHub
git remote add origin https://github.com/用户名/仓库名.git
# 查看远程仓库信息
git remote -v# 推送到远程(首次需要 -u 设置上游分支)
git push -u origin main
# 之后直接推送
git push
# 拉取远程最新代码并合并
git pull
# 只获取远程信息不合并(更安全)
git fetch提交信息是留给未来的自己和队友看的。想象一下这两种 git log:
差的提交历史:
a3f1d2e 修改了一些东西
b7c3e4f update
c9d5a6b fix bug
d1e7f8a 111
e3g9h0i aaa
好的提交历史:
a3f1d2e feat: 添加用户头像上传功能
b7c3e4f fix: 修复登录页面在 Safari 下的样式错位
c9d5a6b refactor: 提取公共表单验证逻辑到 utils
d1e7f8a docs: 补充 API 接口文档中缺失的参数说明
e3g9h0i test: 添加用户注册流程的集成测试
好的提交历史能让你:
- 快速定位问题——出了 bug 能迅速找到是哪次提交引入的
- 轻松回滚——知道每次提交做了什么,回滚时不会误伤
- 高效 Code Review——审查代码时一目了然每个改动的意图
- 自动生成 Changelog——很多工具能从规范的提交信息自动生成版本日志
业界最常用的提交规范是 Conventional Commits(约定式提交)。格式如下:
<类型>(<可选的作用域>): <简短描述>
<可选的详细描述>
<可选的脚注>
最常用的简化格式:
<类型>: <简短描述>
| 类型 | 含义 | 使用场景 | 示例 |
|---|---|---|---|
feat |
新功能 | 新增了用户可感知的功能 | feat: 添加微信登录功能 |
fix |
修复 bug | 修复了已有功能的缺陷 | fix: 修复订单金额计算精度丢失 |
docs |
文档 | 只改了文档,没改代码逻辑 | docs: 补充部署文档的环境变量说明 |
style |
代码格式 | 不影响逻辑的格式调整 | style: 统一使用单引号 |
refactor |
重构 | 既不是新功能也不是修 bug 的代码改动 | refactor: 用策略模式重构支付模块 |
test |
测试 | 添加或修改测试代码 | test: 添加用户服务的单元测试 |
chore |
杂务 | 构建工具、依赖更新等 | chore: 升级 pytest 到 8.0 |
perf |
性能优化 | 提升性能的代码改动 | perf: 优化首页列表查询,添加索引 |
ci |
CI/CD | 修改持续集成/部署配置 | ci: 添加 GitHub Actions 自动测试 |
build |
构建 | 影响构建系统或外部依赖 | build: 迁移构建工具从 webpack 到 vite |
revert |
回滚 | 撤销之前的某次提交 | revert: 回滚 feat: 添加微信登录功能 |
没有分支策略的团队:
- 所有人都在
main分支上直接提交 - 经常互相覆盖代码
- 线上出 bug 不敢修,怕影响别人未完成的功能
- 不知道哪些代码已经测试过、哪些还没测
有分支策略的团队:
- 每个功能在独立分支开发,互不干扰
main分支永远保持可部署状态- 通过 Pull Request 进行代码审查
- 发布、修复、开发各有各的流程
适合小型团队和持续部署的项目。只有一个原则:main 分支永远可部署。
main ●──●──●──────●──────●──●──▶
\ / \ /
●──●─╯ ●─╯
feature-A fix-bug
规则:
main分支永远是可部署的- 要开发新功能或修 bug,从
main创建分支 - 在分支上开发,频繁提交
- 完成后创建 Pull Request(PR)
- 代码审查通过后合并回
main - 合并后立即部署
适合发布周期较长、需要维护多个版本的项目。
main ●────────────●──────────────●──▶ (生产环境)
\ / /
develop ●──●──●──●──●──●──●──●──╯──▶ (开发主线)
\ / \ /
feature-A ●─╯ ●─╯
feature-B
hotfix
main ●────●──●──▶
↓
develop ●──▶
分支角色:
| 分支 | 用途 | 生命周期 | 谁能提交 |
|---|---|---|---|
main |
生产代码,每次提交都对应一个发布版本 | 永久 | 只能通过合并 |
develop |
开发主线,集成所有已完成的功能 | 永久 | 只能通过合并 |
feature/* |
新功能开发 | 临时,完成后删除 | 开发者 |
release/* |
发布前的准备和测试 | 临时,发布后删除 | 测试/开发 |
hotfix/* |
修复生产环境的紧急 bug | 临时,修复后删除 | 开发者 |
# 1. 开始写代码前,拉取最新
git pull
# 2. 写代码...
# 3. 查看改动
git status
git diff
# 4. 分批提交(相关的改动放在一起)
git add src/auth/
git commit -m "feat: 添加 JWT 认证中间件"
git add src/models/user.py
git commit -m "feat: User 模型添加 avatar 字段"
git add tests/
git commit -m "test: 添加认证中间件的单元测试"
# 5. 推送
git push技巧:不要攒一堆改动一次性
git add . && git commit。把相关的改动分成小的、有意义的提交,每个提交只做一件事。
# 1. 同步最新代码
git switch main
git pull
# 2. 创建功能分支
git switch -c feature/order-export
# 3. 开发过程中频繁提交
git add .
git commit -m "feat(order): 添加订单导出为 CSV 的基本逻辑"
git add .
git commit -m "feat(order): 支持自定义导出字段选择"
git add .
git commit -m "test(order): 添加订单导出的单元测试"
# 4. 开发完成,推送分支
git push -u origin feature/order-export
# 5. 创建 PR,等待 Review
# 6. 如果 Review 有修改意见,继续提交
git add .
git commit -m "fix(order): 根据 Review 意见修复日期格式问题"
git push
# 7. Review 通过,在网页上合并 PR
# 8. 清理本地分支
git switch main
git pull
git branch -d feature/order-export