Git 常用操作与使用场景手册
按"日常开发会遇到的真实场景"组织命令,而非简单罗列参数。每个操作都附带典型使用场景,便于遇到问题时快速定位。
一、初始化与配置
1. 安装后首次配置
场景:新机器装好 Git 后,设置全局用户名和邮箱,确保提交记录正确归属。
git config --global user.name "你的名字"git config --global user.email "you@example.com"# 查看所有配置git config --list# 设置默认分支名为 maingit config --global init.defaultBranch main# 让 Git 记住账号密码,避免每次输入git config --global credential.helper store2. 项目级配置
场景:公司项目用企业邮箱,个人项目用私人邮箱,需要按仓库单独设置。
# 进入项目目录后执行(去掉 --global)git config user.name "工作名"git config user.email "work@company.com"3. 配置别名提升效率
场景:常用命令太长,想用简写。
git config --global alias.st statusgit config --global alias.co checkoutgit config --global alias.br branchgit config --global alias.ci commitgit config --global alias.lg "log --graph --oneline --all"# 之后可用 git lg 查看漂亮的提交树二、仓库初始化
1. 把本地目录变成 Git 仓库
场景:本地已有一个项目文件夹,想开始用 Git 管理。
cd your-projectgit initgit add .git commit -m "init: 初始化项目"2. 克隆远程仓库
场景:加入新团队,需要把远程代码拉到本地。
# HTTPS 方式(简单,适合新人)git clone https://github.com/user/repo.git# SSH 方式(免密,推荐长期使用)git clone git@github.com:user/repo.git# 克隆到指定目录git clone git@github.com:user/repo.git my-folder# 只克隆最近一次提交(大仓库加速)git clone --depth 1 git@github.com:user/repo.git3. 关联本地仓库到远程
场景:本地已有 Git 仓库,想推到 GitHub/GitLab 新建的空仓库。
git remote add origin git@github.com:user/repo.gitgit branch -M maingit push -u origin main三、日常开发四件套
场景:每天写代码最常用的循环——改文件 → 查看状态 → 暂存 → 提交。
1. 查看状态
git status # 查看哪些文件改了git status -s # 简短模式git diff # 查看未暂存的具体改动git diff --staged # 查看已暂存但未提交的改动git diff HEAD # 查看所有未提交的改动2. 暂存文件
git add index.html # 暂存单个文件git add src/ # 暂存整个目录git add . # 暂存所有改动(含新增)git add -u # 只暂存已跟踪文件的修改(不含新文件)git add -p # 交互式选择部分改动暂存(同一文件可拆分提交)关键场景:git add -p 适合把一个大改动拆成多个语义清晰的提交,比如同时修了 bug 和加了功能,应该分两次提交。
3. 提交
git commit -m "feat: 新增用户登录功能"git commit -m "标题" -m "详细描述" # 标题 + 正文git commit --amend # 修改最近一次提交(未 push 时用)git commit --amend --no-edit # 把新改动并入上次提交,不改 message4. 推送
git push # 推到默认远程的默认分支git push origin main # 明确指定git push -u origin feature/login # 首次推送新分支并建立跟踪git push --force-with-lease # 安全的强推(见下方说明)警告:不要对公共分支(main/develop)使用 git push --force,会覆盖他人提交。用 --force-with-lease 更安全,它会在远程有新提交时拒绝推送。
四、提交信息规范
场景:团队协作时,规范的 commit message 让历史可读、可自动生成 changelog。
推荐使用 Conventional Commits:
| 前缀 | 含义 | 示例 |
|---|---|---|
feat |
新功能 | feat: 新增微信支付 |
fix |
Bug 修复 | fix: 修复登录超时问题 |
docs |
文档变更 | docs: 更新 README |
style |
代码格式(不影响逻辑) | style: 统一缩进 |
refactor |
重构(非新功能非修 bug) | refactor: 抽离用户服务 |
perf |
性能优化 | perf: 列表接口加索引 |
test |
测试相关 | test: 补充订单单测 |
chore |
构建/工具/依赖 | chore: 升级 Vue 到 3.4 |
build |
构建系统或外部依赖 | build: 修改 webpack 配置 |
ci |
CI 配置 | ci: 添加 GitHub Actions |
格式:
<type>(<scope>): <subject><body><footer>示例:
feat(order): 新增订单导出功能- 支持 Excel 与 CSV 两种格式- 后端走异步任务,避免超时- 关联需求 #1234五、分支管理
1. 查看/创建/切换分支
git branch # 查看本地分支git branch -a # 查看所有分支(含远程)git branch -vv # 查看分支跟踪关系git branch feature/login # 创建分支但不切换git switch feature/login # 切换分支(新命令,推荐)git checkout feature/login # 切换分支(老命令)git switch -c feature/login # 创建并切换git checkout -b feature/login # 创建并切换(老写法)2. 基于远程分支创建本地分支
场景:同事在远程建了 feature/pay,你想本地拉下来接着开发。
git fetch origingit switch feature/pay # 自动跟踪同名远程分支3. 重命名分支
git branch -m new-name # 重命名当前分支git branch -m old-name new-name # 重命名指定分支# 已推送的分支重命名后,需要删除远程旧分支再推新分支git push origin :old-namegit push -u origin new-name4. 删除分支
git branch -d feature/login # 安全删除(未合并会提醒)git branch -D feature/login # 强制删除git push origin --delete feature/login # 删除远程分支5. 分支命名建议
| 前缀 | 场景 | 示例 |
|---|---|---|
feature/ |
新功能 | feature/user-export |
fix/ |
Bug 修复 | fix/login-timeout |
hotfix/ |
紧急线上修复 | hotfix/payment-crash |
refactor/ |
重构 | refactor/order-service |
chore/ |
杂项工程任务 | chore/upgrade-vue |
release/ |
发布准备 | release/v2.3.0 |
六、合并与变基
1. merge(保留分支历史)
场景:把 feature 分支合到 main,想保留"曾经有这个分支"的痕迹。
git switch maingit merge feature/login2. rebase(线性历史)
场景:feature 分支开发期间 main 又有新提交,想让我的提交"接"到最新 main 之后,历史更干净。
git switch feature/logingit rebase main# 如有冲突:解决后 git add,再 git rebase --continue3. merge vs rebase 怎么选
| 维度 | merge | rebase |
|---|---|---|
| 历史 | 保留分支拓扑 | 线性 |
| 冲突 | 一次解决 | 可能多次解决 |
| 安全性 | 不改写历史,公共分支安全 | 改写历史,公共分支危险 |
| 推荐场景 | 合并 feature 到 main | 同步 main 最新代码到 feature |
铁律:永远不要对已推送的公共分支执行 rebase。
4. squash merge(压缩合并)
场景:feature 分支有 20 个零碎提交,合并到 main 时只想留 1 条干净的记录。
git switch maingit merge --squash feature/logingit commit -m "feat: 新增登录功能"5. cherry-pick(摘樱桃)
场景:某个 bug 修复提交在 feature 分支,但 main 也急需这个修复,不想合并整个分支。
git switch maingit cherry-pick <commit-hash>6. 取消刚做的合并
git merge --abort # 合并冲突时放弃合并git reset --hard HEAD~1 # 合并完成后撤销七、撤销与回退
1. 撤销工作区改动
场景:刚改的代码不想要了,想恢复到上次提交的样子。
git restore index.html # 新命令,推荐git checkout -- index.html # 老写法2. 撤销已暂存的改动
场景:git add 错了,想从暂存区拿出来。
git restore --staged index.htmlgit reset HEAD index.html # 老写法3. 修改最近一次提交
场景:刚 commit 完发现 message 写错或有 typo 没改。
# 只改 messagegit commit --amend -m "新的 message"# 把新改动并入上次提交git add .git commit --amend --no-edit警告:已 push 的提交尽量别 amend,会让其他人冲突。
4. 回退到历史提交
场景:发现最近 3 次提交都有问题,想整体回到 3 次之前。
git reset --soft HEAD~3 # 保留改动在暂存区git reset --mixed HEAD~3 # 保留改动在工作区(默认)git reset --hard HEAD~3 # 完全丢弃改动(危险)| 模式 | 工作区 | 暂存区 | 提交历史 |
|---|---|---|---|
--soft |
保留 | 保留 | 回退 |
--mixed(默认) |
保留 | 清空 | 回退 |
--hard |
清空 | 清空 | 回退 |
5. revert(安全回退公共分支)
场景:已经推到远程的提交有问题,不能用 reset,需要"反向提交"撤销。
git revert <commit-hash> # 撤销单次提交git revert HEAD # 撤销最近一次git revert HEAD~2..HEAD # 撤销最近 3 次提交区别:reset 是"删除历史",revert 是"新增一次反向提交",公共分支只能用 revert。
6. 紧急处理:误删分支恢复
场景:误删了 feature 分支,想找回来。
git reflog # 查看所有 HEAD 移动记录git switch -c feature/recovered <reflog-hash>git reflog 是 Git 的"后悔药",几乎所有误操作都能从这里找回。
八、远程仓库操作
1. 查看与添加远程
git remote -v # 查看远程地址git remote add origin git@... # 添加远程git remote set-url origin git@... # 修改远程地址git remote remove origin # 删除远程2. 多远程协作
场景:fork 了开源项目,既想同步上游更新,又想推到自己 fork。
git remote add origin git@github.com:你/repo.git # 自己的 forkgit remote add upstream git@github.com:原作者/repo.git # 上游# 同步上游更新git fetch upstreamgit switch maingit merge upstream/maingit push origin main3. fetch vs pull
git fetch origin # 拉取远程更新但不合并(安全)git pull # = fetch + merge(可能产生冲突)git pull --rebase # = fetch + rebase(更干净)推荐:git pull --rebase 避免无意义的 merge commit。
九、暂存与切换(stash)
1. 临时保存当前改动
场景:正在 feature 分支写代码,老板说 main 有紧急 bug 要先修,但当前代码还不想提交。
git stash # 保存当前改动到栈git stash push -m "登录功能写一半" # 带说明git switch main# ...修 bug、提交、推送 ...git switch feature/logingit stash pop # 取出最近的 stash 并删除git stash list # 查看所有 stashgit stash apply stash@{1} # 取出指定 stash 但不删除git stash drop stash@{0} # 删除指定 stash2. 暂存部分文件
git stash push -m "仅暂存配置" -- config.yml3. 暂存时包含未跟踪文件
git stash -u十、查看历史
1. 提交日志
git log # 完整日志git log --oneline # 每行一条git log --oneline --graph --all # 图形化所有分支git log --author="张三" # 按作者过滤git log --since="2 weeks ago" # 按时间过滤git log -p index.html # 查看某文件的修改历史git log -S "loginUser" # 查看包含某字符串的提交2. 查看某次提交的详情
git show <commit-hash>git show HEAD # 最近一次git show HEAD~2 # 倒数第三次3. 查看某一行代码是谁写的
场景:线上出 bug,想知道这行代码谁加的。
git blame index.htmlgit blame -L 50,80 index.html # 只看 50-80 行4. 搜索提交
git log --grep="登录" # 按 message 搜索git log -- source/ # 只看某目录的提交十一、标签与版本发布
场景:发布 v1.0.0 时,想打个标签方便以后 checkout。
# 轻量标签git tag v1.0.0# 附注标签(推荐,带说明)git tag -a v1.0.0 -m "正式发布版本 1.0.0"# 推送标签到远程git push origin v1.0.0git push origin --tags # 推送所有标签# 查看标签git taggit show v1.0.0# 删除标签git tag -d v1.0.0 # 删本地git push origin --delete v1.0.0 # 删远程# checkout 到某个版本git checkout v1.0.0版本号建议(语义化版本):v<主版本>.<次版本>.<修订号>,如 v2.3.1。
十二、冲突解决
1. 典型冲突场景
合并或 rebase 时,Git 无法自动合并,会提示:
CONFLICT (content): Merge conflict in index.html2. 解决步骤
git status # 看哪些文件冲突# 打开文件,手动解决冲突标记# <<<<<<< HEAD# 我的代码# =======# 对方代码# >>>>>>> feature/logingit add index.html # 解决后标记为已解决git commit # merge 时完成合并提交# 或 rebase 时:git rebase --continue3. 放弃解决
git merge --abort # 取消 mergegit rebase --abort # 取消 rebase4. 减少冲突的策略
- 频繁同步 main:
git pull --rebase origin main - 拆分大 feature 为多个小 PR
- 团队约定文件责任人,减少多人同改
- 大改动用特性开关(feature flag)隔离
十三、典型工作流场景
场景 1:从零开发一个新功能
# 1. 同步最新主分支git switch maingit pull --rebase origin main# 2. 创建功能分支git switch -c feature/user-export# 3. 开发过程中频繁小提交git add .git commit -m "feat: 导出按钮 UI"# 4. 中途同步 main 更新git fetch origingit rebase origin/main# 5. 推送到远程git push -u origin feature/user-export# 6. 在 GitLab/GitHub 提 Merge Request / Pull Request# 7. Code Review 通过后合并到 main,删除功能分支场景 2:修复线上紧急 Bug
# 1. 从 main 拉出 hotfix 分支git switch maingit pullgit switch -c hotfix/payment-crash# 2. 修复并测试git commit -m "fix: 修复支付回调崩溃"# 3. 合并到 main 并打标签git switch maingit merge --no-ff hotfix/payment-crashgit tag -a v1.2.1 -m "修复支付崩溃"# 4. 推送git push origin main --tags# 5. 如果有 develop 分支,也要同步git switch developgit merge hotfix/payment-crash# 6. 清理git branch -d hotfix/payment-crashgit push origin --delete hotfix/payment-crash场景 3:多人协作同分支
# 拉取同事的提交git pull --rebase origin feature/login# 如有冲突:解决 → git add → git rebase --continue# 推送自己的提交git push origin feature/login# 如果同事在你 pull 后又 push 了,push 会失败git pull --rebase origin feature/logingit push origin feature/login场景 4:回滚已上线的版本
# 方案 A:用 revert 反向提交(推荐,安全)git switch maingit revert <有问题的 commit hash>git push origin main# 方案 B:回退到指定版本(需强推,慎用)git reset --hard v1.0.0git push --force-with-lease origin main场景 5:把误提交到 main 的代码移到 feature 分支
# 假设误提交了 2 次git switch -c feature/oops # 先把这些提交带到新分支git switch maingit reset --hard HEAD~2 # main 回退 2 次git switch feature/oops # 继续在 feature 上开发场景 6:只想合并某个文件
# 把 feature 分支的 utils.js 合到 main,不要其他改动git switch maingit checkout feature/xxx -- utils.jsgit commit -m "chore: 同步 utils.js"十四、子模块与大文件
1. 子模块 submodule
场景:项目依赖另一个独立仓库(如公共组件库)。
# 添加子模块git submodule add git@github.com:team/common-ui.git src/common-ui# 克隆含子模块的项目git clone --recurse-submodules git@github.com:user/repo.git# 已克隆项目后初始化子模块git submodule update --init --recursive# 更新子模块到最新git submodule update --remote2. 大文件用 LFS
场景:仓库里有视频、模型等大文件,普通 Git 会很慢。
git lfs installgit lfs track "*.psd"git lfs track "*.mp4"git add .gitattributes十五、二分查找定位 Bug
场景:某个功能本周突然坏了,不知道是哪次提交引入的。
git bisect startgit bisect bad # 标记当前是坏的git bisect good v1.0.0 # 标记 v1.0.0 是好的# Git 自动 checkout 中间提交,你测试后:git bisect good # 或 git bisect bad# 重复几次,Git 会定位到具体哪次提交引入的 buggit bisect reset # 结束十六、常用命令速查表
| 场景 | 命令 |
|---|---|
| 查看状态 | git status |
| 查看改动 | git diff |
| 暂存全部 | git add . |
| 暂存部分 | git add -p |
| 提交 | git commit -m "msg" |
| 修改上次提交 | git commit --amend |
| 推送 | git push |
| 拉取并 rebase | git pull --rebase |
| 新建并切换分支 | git switch -c name |
| 合并分支 | git merge name |
| 变基 | git rebase main |
| 撤销工作区改动 | git restore file |
| 取消暂存 | git restore --staged file |
| 回退提交(安全) | git revert <hash> |
| 回退历史(慎用) | git reset --hard HEAD~3 |
| 暂存工作 | git stash |
| 恢复暂存 | git stash pop |
| 查看历史 | git log --oneline --graph --all |
| 查看作者 | git blame file |
| 后悔药 | git reflog |
| 找回误删分支 | git switch -c name <reflog-hash> |
| 打标签 | git tag -a v1.0 -m "msg" |
| 摘单次提交 | git cherry-pick <hash> |
| 二分查 bug | git bisect start |
十七、常见问题 FAQ
Q1:push 被拒绝,提示 "non-fast-forward"
远程有你本地没有的提交。先 git pull --rebase origin main,解决冲突后再 push。
Q2:commit message 写错了,已 push
git commit --amend -m "正确的 message"git push --force-with-lease origin feature/xxx仅限自己独占的分支,公共分支不要这样改。
Q3:误执行了 git reset --hard,代码没了
git reflog # 找到误操作前的 hashgit reset --hard <hash>Q4:想把某次提交拆成两次
git rebase -i HEAD~3 # 交互式 rebase# 把要拆的提交标记为 edit# Git 停在该提交后:git reset HEAD~git add -p # 分批暂存git commit -m "第一部分"git add .git commit -m "第二部分"git rebase --continueQ5:clone 太慢怎么办
# 浅克隆git clone --depth 1 <url># 只克隆最近 N 次提交git clone --depth 10 <url># 只克隆指定分支git clone --branch main --single-branch <url>Q6:如何让 Git 忽略某些文件
在仓库根目录创建 .gitignore:
node_modules/*.log.envdist/.vscode/*.local已被跟踪的文件加入 .gitignore 后,还需 git rm --cached <file> 取消跟踪。
Q7:如何查看某个文件的历史版本
git log --oneline -- path/to/filegit show <commit-hash>:path/to/file # 查看历史版本内容Q8:merge 之后想撤销
git reset --hard ORIG_HEAD # 回到 merge 之前十八、推荐工作流模型
1. GitHub Flow(简单,适合小团队)
main(永远可部署) └── feature/xxx → PR → review → merge规则:main 永远可部署,所有改动通过 PR 合并。
2. Git Flow(规范,适合版本发布)
main ← 只放发布版本develop ← 日常集成分支feature/* ← 功能分支,合到 developrelease/* ← 发布准备分支hotfix/* ← 紧急修复,合到 main 和 develop3. Trunk-Based(主干开发,适合高频发布)
所有人直接往 main 提交(或短命 feature 分支),配合特性开关与持续集成。大厂主流模式。
总结
Git 是开发者最趁手的工具,也是最容易踩坑的地方。掌握核心原则:
- 小步提交:每次 commit 只做一件事,方便回溯与 review。
- 分支隔离:永远不要在 main 上直接开发。
- 公共分支不用 reset/amend:用 revert 安全回退。
- 勤同步:每天开始工作前
git pull --rebase。 - reflog 是后悔药:误操作第一时间看 reflog。
- 提交信息要可读:用规范前缀,团队历史才可追溯。
Git 不在于背多少命令,而在于理解每个操作改写了什么:工作区、暂存区、本地仓库,还是远程仓库。理清这四层,所有命令都有迹可循。
附:推荐资源
- 官方文档:https://git-scm.com/doc
- Pro Git Book(中文版):https://git-scm.com/book/zh/v2
- 交互式学习:https://learngitbranching.js.org/?locale=zh_CN
- Git Cheat Sheet(PDF):https://education.github.com/git-cheat-sheet-education.pdf
- 可视化练习:https://onlywei.github.io/explain-git-with-d3/