git教程

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

八、推荐资源

评论

评论功能即将上线,敬请期待。