Git 新手教程
一、基础概念
Git 是什么?
Git 是分布式版本控制系统。每次提交(commit)就像游戏存档,随时可以回档。
三个区域
工作区 (Working Directory) → 暂存区 (Staging Area) → 仓库 (Repository)
你正在编辑的文件 git add 之后 git commit 之后
文件状态
| 状态 | 含义 |
|---|---|
| untracked | Git 不跟踪的新文件 |
| modified | 已跟踪但被修改了 |
| staged | 已 add,等待 commit |
| committed | 已提交到本地仓库 |
二、安装与初始配置
# 安装(Mac 推荐 brew)
brew install git
# 必做的全局配置
git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
# 查看配置
git config --list
# 设置默认分支名(推荐 main 而非 master)
git config --global init.defaultBranch main
三、常用命令速查
🏗️ 创建仓库
# 从零开始
git init
# 克隆远程仓库
git clone https://github.com/user/repo.git
# 克隆到指定目录
git clone https://github.com/user/repo.git my-folder
📝 日常三步曲:add → commit → push
# 1. 查看当前状态
git status
# 2. 把修改加入暂存区
git add file.py # 添加单个文件
git add . # 添加所有修改
# 3. 提交
git commit -m "描述你改了什么"
# 4. 推送到远程
git push
# 一句话搞定(已跟踪文件的修改)
git commit -am "修复登录bug"
📥 拉取更新 (git fetch 完全指南)
核心区别:
git pull=git fetch+git merge(一步到位)git fetch= 只下载远程最新数据,不会自动合并- 先用 fetch 看远程有什么变化,再决定怎么合并——更安全可控
# 最常用
git pull # 拉取并自动合并(一步到位)
# 更安全的做法:先看再合
git fetch # 只下载,不合并
git log --oneline main..origin/main # 看看远程有哪些新提交
git merge origin/main # 确认没问题后再合并
基础用法
# 从默认远程(origin)拉取
git fetch
# 从指定远程拉取
git fetch origin
git fetch upstream # 如果有多个远程
# 从所有远程拉取
git fetch --all
拉取特定分支
# 拉取远程的某个分支
git fetch origin main # 只拉取 main 分支
git fetch origin feature/login # 拉取指定功能分支
# 拉取后查看远程分支
git branch -r # 查看所有远程分支
# origin/main
# origin/feature/login
# 基于远程分支创建本地分支
git switch -c login origin/feature/login
清理远程分支信息
# 远程已删除的分支,本地还残留在 remote 列表里
git branch -r # 可能看到 origin/old-feature
# 清理已不存在的远程分支
git fetch --prune
# 或简写
git fetch -p
# 同时拉取并清理
git fetch --all --prune
# 查看清理效果
git branch -r # 已删除的远程分支不再显示
安全 fetch 的技巧
# 先 fetch 看看远程情况
git fetch origin
git status # 提示:Your branch is behind 'origin/main' by 3 commits
# 查看远程新提交的内容(不合并就不会冲突)
git log --oneline main..origin/main
# 或看 diff
git diff main origin/main
# 确认可以合并后再操作
git merge origin/main # 快进合并(fast-forward)
# 如果不想 merge,也可以 rebase
git rebase origin/main
强制覆盖本地(谨慎使用)
# 场景:本地已经改乱了,想完全重置为远程版本
git fetch origin
git reset --hard origin/main # ⚠️ 会丢弃所有本地修改!
多远程协同
# 查看所有远程
git remote -v
# origin https://github.com/你自己/repo.git (fetch)
# upstream https://github.com/原作者/repo.git (fetch)
# 从不同远程拉取
git fetch upstream # 拉取原作者的更新
git log --oneline main..upstream/main # 和原作者有哪些差异
git merge upstream/main # 合并到本地
💡 最佳实践: 养成先
git fetch再决定合并方式的习惯,而不是直接用git pull。fetch 让你有机会在合并前检查远程的改动,避免被意外的合并冲突打个措手不及。
🔀 分支操作
# 查看分支
git branch # 本地分支
git branch -a # 包含远程分支
# 创建并切换分支
git checkout -b feature-login
# 或新版语法
git switch -c feature-login
# 切换分支
git checkout main
# 或
git switch main
# 合并分支(先切到目标分支)
git switch main
git merge feature-login
# 删除分支
git branch -d feature-login # 已合并的
git branch -D feature-login # 强制删除
🔍 查看历史 (git log 完全指南)
# 最常用
git log
git log --oneline # 简洁版(一行一条)
git log --oneline --graph # 带 ASCII 分支图
格式化输出
# 自定义格式
git log --format="%h - %an: %s"
# %h = 短 hash, %an = 作者, %s = 标题, %ad = 日期
# 内置漂亮格式
git log --pretty=format:"%C(yellow)%h%Creset %C(cyan)%ad%Creset %s" --date=short
# 显示分支拓扑图(必学!)
git log --oneline --graph --all --decorate
按条件过滤
# 按作者
git log --author="张三"
git log --committer="李四"
# 按时间
git log --since="2025-01-01"
git log --until="2025-06-01"
git log --since="2 weeks ago"
git log --since="yesterday"
# 按提交信息
git log --grep="修复"
git log --grep="feat" --grep="fix" --all-match # 同时匹配多个
# 按文件
git log -- app/models/user.rb # 只看某个文件的历史
git log -p app/models/user.rb # 同时看每个版本的 diff
查看变更内容
git log -p # 每次提交的完整 diff
git log --stat # 统计改了多少文件,多少行
git log --name-only # 只看改了哪些文件
git log --name-status # 文件及变更类型(A/M/D)
限制输出数量
git log -5 # 只看最近 5 条
git log -n 10 # 同上
git log --max-count=20
# 只看某个范围内的提交
git log main..feature # feature 有但 main 没有的提交
git log --since="2025-01-01" --until="2025-03-01" -10
分支对比
# 查看两个分支的差异提交
git log main..feature # feature 有而 main 没有
git log --oneline --left-right main...feature # 两侧对比
# 查看分支的合并关系
git log --oneline --graph --merges
高级用法
# 搜索包含特定字符串的提交
git log -S "console.log" # 新增或删除该字符串的提交
git log -G "console.log" # 匹配正则的提交(比 -S 更广)
# 查看某个函数的修改历史
git log -L :functionName:file.py
# 查看所有分支的提交(不只是当前分支)
git log --all --oneline
# 只看合并提交
git log --merges
git log --no-merges # 排除合并提交
# 自定义漂亮输出(推荐配置别名)
git log --graph --pretty=format:'%C(yellow)%h%Creset %C(blue)%d%Creset %s %Cgreen(%cr) %C(cyan)<%an>%Creset' --all
💡 建议配置别名:
git config --global alias.lg "log --graph --pretty=format:'%C(yellow)%h%Creset %C(blue)%d%Creset %s %Cgreen(%cr) %C(cyan)<%an>%Creset' --all",之后用git lg即可享受漂亮的日志展示。
# 查看谁改了什么(不是 log,但常一起用)
git blame file.py
↩️ 撤销操作
# 撤销工作区修改(还没 add)
git restore file.py
# 或旧语法
git checkout -- file.py
# 撤销暂存(已 add,还没 commit)
git restore --staged file.py
# 或旧语法
git reset HEAD file.py
# 撤销最近一次提交(保留修改)
git reset --soft HEAD~1
# 撤销最近一次提交(丢弃修改)⚠️ 危险
git reset --hard HEAD~1
# 修改最近一次提交信息
git commit --amend -m "新的提交信息"
🏷️ 标签
git tag v1.0 # 轻量标签
git tag -a v1.0 -m "版本1.0" # 附注标签
git push origin v1.0 # 推送标签
四、场景实战
场景 1:第一次参与项目
# 1. 克隆仓库
git clone https://github.com/team/project.git
cd project
# 2. 创建自己的功能分支
git switch -c feature/my-feature
# 3. 写代码...然后提交
git add .
git commit -m "添加用户注册功能"
# 4. 推送到远程
git push -u origin feature/my-feature
# 5. 在 GitHub/GitLab 上创建 Pull Request (PR)
场景 2:正在开发,同事已经合了代码
# 方法一:rebase(保持线性历史,推荐)
git fetch origin
git rebase origin/main
# 方法二:merge(保留合并记录)
git fetch origin
git merge origin/main
场景 3:写了一半突然要修紧急 bug
# 方案一:stash(临时存放)
git stash # 保存当前修改
git switch -c hotfix/bug-123 # 切到新分支修 bug
# ...修完...
git commit -am "修复 #123"
git switch feature/my-feature # 回来继续
git stash pop # 恢复之前的修改
# 方案二:worktree(另一个目录工作)
git worktree add ../hotfix hotfix/bug-123
cd ../hotfix
# ...修完...
git commit -am "修复 #123"
场景 4:提交信息写错了
# 改最近一条
git commit --amend -m "正确的提交信息"
# 已经 push 了?需要强制推送(慎用)
git push --force-with-lease
场景 5:不小心把不该提交的文件 push 了
# 从仓库删除但保留本地文件
git rm --cached secret.key
git commit -m "移除敏感文件"
git push
# ⚠️ 敏感信息(密码、密钥)已推送到远程的,必须立即轮换!
# Git 历史中仍可看到,彻底清理需用 git filter-branch 或 BFG
场景 6:合并冲突
git merge feature-login
# 出现冲突时:
# 1. 打开冲突文件,找到 <<<<<<< ======= >>>>>>> 标记
# 2. 手动选择保留哪部分代码
# 3. 保存后
git add .
git commit -m "解决合并冲突"
冲突标记示例:
# <<<<<<< HEAD (当前分支)
name = "Alice"
# =======
name = "Bob"
# >>>>>>> feature-login (要合并的分支)
场景 7:回退到某个历史版本
# 查看历史
git log --oneline
# a1b2c3d 修复登录bug
# e4f5g6h 添加注册功能
# i7j8k9l 初始提交
# 回退(保留修改在工作区)
git reset --soft a1b2c3d
# 回退(彻底丢弃)⚠️
git reset --hard a1b2c3d
# 更安全的做法:用 revert 创建一个反向提交
git revert e4f5g6h
五、团队分工模式
模式 1:集中式(Centralized Workflow)
最简单,适合小团队(2-5人)。
所有人 → main 分支 → push/pull
规则:
- 只有一个 main 分支
- pull → 改代码 → push
- 冲突时先 pull 再 push
问题: 容易互相覆盖,不推荐超过 3 人使用。
模式 2:Feature Branch(功能分支模式)⭐ 最常用
main ────────────────────────────── merge ──
└── feature-A ── merge ──┘
└── feature-B ──────────── merge ──┘
规则:
- main 分支永远可部署
- 每个功能/任务开新分支
- 完成后通过 PR/MR 合入 main
- 合并前需要 Code Review
命名规范:
feature/用户注册
feature/payment
bugfix/登录失败
hotfix/生产环境崩溃
chore/更新依赖
模式 3:Git Flow
适合有明确发布周期的项目(如 App 发版)。
main ────────────────────── v1.0 ──── v2.0 ──
develop ────────────────────────────────────────
└── feature/A ── merge to develop ──┘
└── release/1.0 ── merge to main + develop ─┘
└── hotfix/xxx ── merge to main + develop ─┘
分支说明:
| 分支 | 用途 | 合并到 |
|---|---|---|
| main | 生产版本 | - |
| develop | 开发集成分支 | main(通过 release) |
| feature/* | 新功能 | develop |
| release/* | 准备发版 | main + develop |
| hotfix/* | 紧急修复 | main + develop |
模式 4:GitHub Flow / Trunk-Based
适合持续部署的 Web 项目,最轻量。
main ─────────────────────────────────
└── feature ── PR + review ── merge ── 立即部署
规则:
- main 始终可部署
- 功能分支开发 → PR → Review → 合并 → 自动部署
- 没有 release 分支,持续集成
模式 5:Forking Workflow
适合开源项目,贡献者没有主仓库写权限。
主仓库 (upstream)
↑ PR
贡献者的 Fork (origin)
└── feature ── push to origin ── PR to upstream
# 1. Fork 仓库(GitHub 上点按钮)
# 2. 克隆自己的 fork
git clone https://github.com/你/repo.git
# 3. 添加上游仓库
git remote add upstream https://github.com/原作者/repo.git
# 4. 同步上游更新
git fetch upstream
git merge upstream/main
# 5. 推送到自己的 fork
git push origin feature/xxx
# 6. 在 GitHub 上创建 PR
六、工作中常见情况
1. 代码审查 (Code Review)
# 提交 PR 前先同步最新代码
git fetch origin
git rebase origin/main
# 如果 PR 评审后需要修改
# 在原分支继续改,然后
git add .
git commit -m "根据 review 修改"
git push
# 或者用 amend 追加到上一个提交(保持 PR 干净)
git add .
git commit --amend --no-edit
git push --force-with-lease
2. CI/CD 流水线
push → 触发 CI → 跑测试 → 通过才能 merge
常见 CI:GitHub Actions、GitLab CI、Jenkins
3. .gitignore 文件
# 忽略不需要跟踪的文件
node_modules/
dist/
.env
*.log
.DS_Store
__pycache__/
4. SSH Key 配置(免密码推送)
# 生成 SSH Key
ssh-keygen -t ed25519 -C "your@email.com"
# 复制公钥
cat ~/.ssh/id_ed25519.pub
# 粘贴到 GitHub → Settings → SSH Keys
# 测试连接
ssh -T git@github.com
# 仓库使用 SSH URL
git remote set-url origin git@github.com:user/repo.git
5. 多人协作的礼仪
| 做 ✅ | 不做 ❌ |
|---|---|
| 频繁 pull 最新代码 | 长时间不同步然后大冲突 |
| 小步提交,信息清晰 | 一次提交堆一堆改动 |
| 写有意义的 commit message | "fix"、"update"、"wip" |
| 合并前跑测试 | 直接 push 到 main |
| 及时删除已合并的分支 | 分支堆积如山 |
6. Commit Message 规范(Angular 规范)
<type>(<scope>): <subject>
<body>
<footer>
type 类型:
| type | 说明 |
|---|---|
| feat | 新功能 |
| fix | 修复 bug |
| docs | 文档 |
| style | 格式(不影响逻辑) |
| refactor | 重构 |
| test | 测试 |
| chore | 构建/工具 |
示例:
feat(auth): 添加 OAuth2 登录支持
实现 GitHub 和 Google OAuth2 登录流程,
支持自动创建账号和关联已有账号。
Closes #123
七、速查脑图
git init / clone
│
├── git add . ─── git commit -m "msg" ─── git push
│ │
│ git pull ←────────────┘
│
├── git branch / switch / merge
│
├── git stash ─── git stash pop
│
├── git log / diff / status
│
├── git restore / reset / revert
│
└── git remote / fetch / pull
八、推荐资源
- 交互式学习:Learn Git Branching(可视化理解分支)
- 官方文档:git-scm.com
- 速查表:GitHub Git Cheat Sheet
评论
评论功能即将上线,敬请期待。