Git 常用命令实战指南:从开发到合并的完整工作流

Git 常用命令实战指南:从开发到合并的完整工作流

引言

很多人学 Git 的方式是:遇到问题 → 搜命令 → 复制粘贴 → 下次继续搜。这当然能干活,但当你面对一个混乱的提交历史、一场惨烈的合并冲突、或是一个"我刚刚到底做了什么"的时刻,零散的命令记忆就捉襟见肘了。

本文不打算罗列 Git 的所有命令,而是沿着一个开发者的真实工作流,把最常用的命令串联起来。读完你会有一个清晰的心智模型——知道每一步在做什么、为什么这样做、踩坑了怎么回退。


一、开始新功能:从仓库到分支

场景

早上领到一个新需求,你需要从团队仓库拉取最新代码,然后创建自己的开发分支。

核心命令

1. 克隆仓库

git clone git@github.com:team/project.git

如果你是第一次接触这个项目,clone 会把整个仓库(含完整历史)拉到本地。如果项目很大,可以只克隆最近一次提交:

git clone --depth 1 git@github.com:team/project.git

2. 拉取最新代码

如果你已经克隆过,先同步远程的最新状态:

git fetch origin

fetch 只下载远程更新,不会动你的工作区。想看看远程有什么新东西?

git log origin/main ^main   # 远程比本地多了哪些提交

3. 创建特性分支

永远不要在 main 分支上直接开发,这是团队协作的第一条纪律。

git checkout -b feature/user-login

从 Git 2.23 开始,switchrestore 拆分了一部分 checkout 的职责,语义更清晰:

git switch -c feature/user-login   # 创建并切换到新分支

分支命名建议遵循团队约定,常见模式:feature/xxxbugfix/xxxhotfix/xxx

常见坑点

  • git pull = git fetch + git merge,它会在你不知道的时候自动产生一个合并提交。推荐使用 git pull --rebase(详见第三节),保持历史线性。
  • 忘记切分支就开始写代码?用 git stash 救回来(详见第三节)。

二、日常开发:写代码与提交

场景

你在特性分支上写代码,时不时需要查看改了什么、暂存文件、提交变更。

核心命令

1. 查看状态

git status          # 完整状态
git status -s       # 简短模式,适合截图/分享

这是 Git 中使用频率最高的命令。养成习惯:做任何操作前先 git status

2. 查看差异

git diff                    # 工作区 vs 暂存区(还没 add 的改动)
git diff --staged           # 暂存区 vs 上次提交(已经 add 但还没 commit 的改动)
git diff HEAD               # 工作区 + 暂存区 vs 上次提交(全部未提交的改动)
git diff main..feature      # 两个分支之间的差异

git diff 的输出有时候不太直观,推荐配合 GUI 工具(VS Code 内置的 diff 就很好用)或者加 --name-only 只看文件名:

git diff --name-only HEAD   # 只列出改动的文件

3. 暂存文件

git add filename.py             # 暂存单个文件
git add -p filename.py          # 交互式暂存,逐块选择(强烈推荐)
git add -A                      # 暂存所有改动(谨慎使用)

git add -p 是进阶利器——它会逐块展示改动并让你选择是否暂存。这样你可以把一次改动的不同部分分开提交,每个提交只做一件事。

4. 提交

git commit -m "feat: 添加用户登录接口"

提交信息值得认真写。 推荐 Conventional Commits 规范:

前缀 用途 示例
feat 新功能 feat: 添加短信验证码登录
fix Bug 修复 fix: 修复 token 过期后不刷新的问题
refactor 重构 refactor: 提取公共的权限校验逻辑
docs 文档 docs: 更新 API 接口文档
chore 杂项 chore: 升级依赖版本

如果漏了文件或写错了提交信息:

git add forgotten_file.py
git commit --amend --no-edit   # 把漏掉的文件追加到上一次提交,不改信息

git commit --amend -m "新的提交信息"   # 修改上一次提交的信息

注意: --amend 会改写历史,只用于还没推送的提交。

5. 查看提交历史

git log                     # 完整日志
git log --oneline           # 每行一条,适合快速浏览
git log --oneline --graph   # 带分支图的简洁日志(推荐设为别名)
git log -3                  # 只看最近 3 条
git log --since="2026-05-01" --until="2026-05-31"   # 按日期范围筛选

建议设一个别名:

git config --global alias.lg "log --oneline --graph --all"

之后 git lg 就能看到漂亮的分支图了。

常见坑点

  • 提交完发现 git status 还有红色文件?那是因为这些文件从来没被 git add 过(untracked)。用 git add 添加它们。
  • git add -A 会把所有改动(包括不想提交的调试代码)都暂存,日常开发用 git add -p 更安全。

三、同步协作:拉取、冲突与暂存

场景

同事推送了新的提交到远程,你需要同步过来。更糟的是,你可能本地还有一些没写完的代码不想提交。

核心命令

1. 拉取远程更新(推荐 rebase 方式)

git pull --rebase origin main

为什么用 --rebase 而不是默认的 pull

# 默认 pull(merge 方式):
# A---B---C  (main)
#      \
#       D---E  (你的分支)
# 结果会产生一个合并提交 M,历史分叉复杂

# pull --rebase 方式:
# A---B---C---D'---E'  (你的分支)
# 把你的提交"接"在远程最新提交后面,历史保持线性

建议设为默认行为:

git config --global pull.rebase true

2. 解决合并冲突

当两个人的改动碰巧在同一个文件的同一区域时,Git 无法自动合并,就会产生冲突。你会在文件里看到:

<<<<<<< HEAD
你的改动
=======
同事的改动
>>>>>>> main

解决步骤:

# 1. 手动编辑文件,删除冲突标记,保留正确的代码

# 2. 标记为已解决
git add conflicted_file.py

# 3. 如果是在 rebase 过程中,继续
git rebase --continue

# 如果想放弃这次合并/变基
git merge --abort       # 放弃 merge
git rebase --abort      # 放弃 rebase

减少冲突的技巧:

  • 经常 pull --rebase,不要攒一周才拉一次
  • 多人改同一个文件时,提前沟通分工

3. 暂存临时工作

写到一半需要切分支处理紧急 bug,但又不想提交半成品?

git stash                   # 暂存所有未提交的改动
git stash list              # 查看暂存列表
git stash pop               # 恢复最近一次暂存,并从列表中删除
git stash apply             # 恢复最近一次暂存,但保留在列表中
git stash drop stash@{0}    # 删除指定的暂存

更实用的方式——给 stash 加个描述:

git stash push -m "用户登录写到一半"

常见坑点

  • git stash pop 后有冲突不会自动清理 stash,需要手动 git stash drop
  • 永远不要 rebase 已经推送到远程的公共分支,这会破坏其他人的工作基础。

四、提交整理:让历史干净如初

场景

你的分支上有 10 个提交,其中 3 个是 "fix typo"、2 个是 "WIP"、还有几个来回调整的。在提 PR 之前,你希望把它们整理成逻辑清晰的几个提交。

核心命令

1. 交互式变基

这是整理提交历史最强大的工具:

git rebase -i HEAD~5    # 整理最近 5 个提交
git rebase -i main       # 整理从与 main 分叉以来的所有提交

会打开编辑器,列出你的提交:

pick a1b2c3d feat: 添加登录页面
pick e4f5g6h fix typo
pick i7j8k9l WIP: 接口联调
pick m0n1o2p feat: 完成登录接口
pick q3r4s5t fix: 修正返回值格式

你可以修改每行前面的命令:

命令 作用
pick 保留这个提交
reword 修改提交信息
squash 合并到上一个提交,保留信息
fixup 合并到上一个提交,丢弃信息(最常用)
drop 删除这个提交
edit 暂停在这里,让你手动修改

整理后可能是这样:

pick a1b2c3d feat: 添加用户登录功能
fixup e4f5g6h fix typo
fixup i7j8k9l WIP: 接口联调
fixup m0n1o2p feat: 完成登录接口
fixup q3r4s5t fix: 修正返回值格式

最终变成 1 个干净的提交。

2. 软重置

如果还没推送,想要重新组织最近几次提交:

git reset --soft HEAD~3   # 撤销最近 3 次提交,改动保留在暂存区
# 然后重新提交
git commit -m "feat: 完整的功能描述"

三种 reset 模式的区别:

模式 提交历史 暂存区 工作区
--soft 回退 保留 保留
--mixed(默认) 回退 清空 保留
--hard 回退 清空 清空(危险!)

3. 拣选提交

只想把另一个分支的某个提交拿过来用,而不是合并整个分支:

git cherry-pick a1b2c3d           # 拿一个
git cherry-pick a1b2c3d..e4f5g6h  # 拿一段(不包含 a1b2c3d)

典型场景:你在 feature/A 修了一个 bug,feature/B 也需要同样的修复。

常见坑点

  • git reset --hard永久丢失未提交的改动。执行前确保 git status 是干净的。
  • 已经推送过的提交不要用 rebase -i 整理,除非你确定只有你一个人在用这个分支(用 git push --force-with-lease 替代 --force,更安全)。
  • 如果不小心做错了什么,git reflog 是你的时光机:
git reflog              # 查看所有 HEAD 的移动记录
git reset --hard HEAD@{3}   # 回到 3 步之前的状态

五、代码合并:提 PR 与推送

场景

代码写好、提交整理完毕,现在推送到远程、发起 Pull Request。

核心命令

1. 推送到远程

git push origin feature/user-login             # 首次推送
git push                                       # 如果已经设置了上游跟踪
git push --force-with-lease                    # 如果本地整理过历史(比 --force 安全)

--force-with-lease--force 的区别:前者在推送前会检查远程分支是否有你不知道的新提交,如果有就拒绝推送,避免覆盖同事的工作。

2. 变基到最新 main

在提 PR 之前,最好先把最新的 main 分支内容合并进来,确保没有冲突:

git fetch origin
git rebase origin/main
git push --force-with-lease

3. 合并到主分支

这部分通常在 GitHub/GitLab 的网页界面上操作,两种策略:

策略 效果 适用场景
Merge Commit 保留完整的分支历史,生成一个合并提交 多人协作的大型特性
Squash and Merge 把一个分支的所有提交压成一个 小型修复,保持主分支干净
Rebase and Merge 线性历史,无合并提交 追求整洁历史的团队

具体哪种由团队决定,不必纠结——重要的是保持一致。

常见坑点

  • 第一次推送新分支需要用 git push -u origin feature/xxx-u 设置上游跟踪),之后才能直接用 git push
  • 推送被拒绝(rejected)通常是因为远程有新的提交,先 git pull --rebase 再推送。

附录:四道"救命"命令

当你觉得搞砸了的时候,这些命令能救命:

# 1. 时光机:查看 HEAD 移动记录,找回"丢失"的提交
git reflog

# 2. 撤销工作区的所有改动(回到上次提交的状态)
git restore .

# 3. 撤销某个提交(产生一个新的反向提交,不改写历史)
git revert a1b2c3d

# 4. 找出哪次提交引入了一个 bug(二分查找)
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
# Git 会自动 checkout 到中间点让你测试,重复标记 good/bad 直到定位

总结

Git 是一个强大但复杂的工具。记住下面这张心智地图,大部分场景你都能应对:

git fetch → git switch -c xxx → 写代码
    → git add -p → git commit → 循环...
    → git stash(临时切换任务)
    → git pull --rebase(同步远程)
    → git rebase -i(整理历史)
    → git push → 提 PR
    → 搞砸了? git reflog 永远在

最后一条建议:不用记住所有命令,但要知道什么命令能解决什么问题。 当你遇到一个陌生场景时,先停下来想清楚"我现在想做什么",再去找对应的命令,而不是盲目复制粘贴。


本文由 Claude Code + cnblogs MCP Server 协作发布。

posted @ 2026-06-01 10:56  松鼠航  阅读(2)  评论(0)    收藏  举报