Git 从入门到"装逼":让同事刮目相看的操作
不只是 add、commit、push,掌握这些 Git 技巧,让你在团队中脱颖而出
Git 从入门到"装逼":让同事刮目相看的操作
你是不是也经历过这些场景?
场景1:代码写残了
$ git add .
$ git commit -m "fix bug"
$ git push
# 完蛋,改错文件了...
场景2:提交信息写错了
$ git commit -m "修复了 bug"
$ git push
# 糟糕,应该是"修复了登录 bug"...
场景3:合并冲突
$ git pull
Auto-merging index.js
CONFLICT (content): Merge conflict in index.js
Automatic merge failed; fix conflicts and then commit the result.
# 懵了,咋办?
别慌。今天小明手把手教你,从 Git 入门到进阶,最后再教几招"装逼"技能。
看完这篇,你会成为团队里的 Git 大神。
一、Git 基础:别只会三板斧
1.1 初始化仓库
创建新仓库:
$ git init
这会在当前目录创建一个 .git 文件夹,里面存放所有版本信息。
克隆远程仓库:
$ git clone https://github.com/xiaoming/awesome-project.git
1.2 Git 的三个区域
理解 Git,首先要理解它的三个工作区域:
工作区 (Working Directory)
↓ git add
暂存区 (Staging Area)
↓ git commit
本地仓库 (Local Repository)
↓ git push
远程仓库 (Remote Repository)
工作区:你正在编辑的文件
暂存区:准备提交的文件快照
本地仓库:已提交的历史记录
远程仓库:GitHub/GitLab 上的代码
1.3 基本操作
# 查看状态
$ git status
# 添加文件到暂存区
$ git add index.js # 添加单个文件
$ git add . # 添加所有文件
# 提交到本地仓库
$ git commit -m "提交信息"
# 推送到远程仓库
$ git push origin main
# 拉取远程更新
$ git pull origin main
这些你应该都会了。接下来是进阶技巧。
二、进阶技巧:让代码更优雅
2.1 优雅的提交信息
❌ 糟糕的提交信息:
修复了 bug
更新
aaa
✅ 优秀的提交信息:
fix: 修复登录页面验证码不刷新的问题
- 添加验证码过期时间判断
- 优化图片加载逻辑
Closes #123
约定式提交(Conventional Commits):
<类型>(<范围>): <简短描述>
<详细描述>
<关联 Issue>
常用类型:
| 类型 | 说明 | 示例 |
|---|---|---|
| feat | 新功能 | feat: 添加用户注册功能 |
| fix | 修复 Bug | fix: 修复支付回调失败 |
| docs | 文档 | docs: 更新 API 文档 |
| style | 格式 | style: 统一缩进为 2 空格 |
| refactor | 重构 | refactor: 重构登录模块 |
| test | 测试 | test: 添加用户模块单元测试 |
| chore | 构建/工具 | chore: 升级 webpack 到 5.0 |
2.2 修改最后一次提交
场景:提交信息写错了,或者忘记加文件了。
# 修改提交信息
$ git commit --amend -m "新的提交信息"
# 追加文件到上次提交
$ git add forgot-file.js
$ git commit --amend --no-edit # --no-edit 表示不修改信息
注意:只能修改最后一次提交,且不要修改已推送的提交!
2.3 撤销操作
场景1:文件还在工作区,没 add
# 撤销单个文件的修改
$ git checkout -- index.js
# 撤销所有修改
$ git checkout -- .
场景2:文件已 add,在暂存区
# 从暂存区移除,但保留工作区的修改
$ git reset HEAD index.js
# 移除所有文件
$ git reset HEAD .
场景3:已 commit,想撤销提交
# 撤销最后一次提交,但保留修改
$ git reset --soft HEAD~1
# 撤销提交,并丢弃修改(危险!)
$ git reset --hard HEAD~1
# 撤销到指定提交
$ git reset --soft abc123
reset 的三种模式:
| 模式 | 工作区 | 暂存区 | 本地仓库 |
|---|---|---|---|
--soft | 保留 | 保留 | 撤销 |
--mixed(默认) | 保留 | 撤销 | 撤销 |
--hard | 撤销 | 撤销 | 撤销 |
2.4 查看历史
# 查看提交历史
$ git log
# 简洁格式
$ git log --oneline
# 图形化显示分支
$ git log --graph --oneline --all
# 查看某个文件的历史
$ git log -- index.js
# 查看某次提交的详情
$ git show abc123
小技巧:给 git log 设置别名
$ git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
# 使用
$ git lg
效果:
* a3b2c1d - (HEAD -> main) fix: 修复登录 bug (2 hours ago) <xiaoming>
* f4e5d6c - feat: 添加用户注册 (1 day ago) <xiaoming>
* 7g8h9i0 - docs: 更新 README (3 days ago) <xiaoming>
三、分支管理:团队协作的核心
3.1 分支基础
# 查看所有分支
$ git branch -a
# 创建分支
$ git branch feature/login
# 切换分支
$ git checkout feature/login
# 创建并切换(推荐)
$ git checkout -b feature/login
# 删除分支
$ git branch -d feature/login
# 强制删除(未合并的分支)
$ git branch -D feature/login
Git 2.23+ 新命令:
# 切换分支
$ git switch feature/login
# 创建并切换
$ git switch -c feature/login
switch 比 checkout 语义更清晰。
3.2 合并分支
场景:把 feature/login 合并到 main
$ git checkout main
$ git merge feature/login
两种合并方式:
1. Fast-forward(快进合并)
main: A---B
\
feature: C---D
合并后:
main: A---B---C---D
没有新的提交,只是移动指针。
2. 3-way merge(三方合并)
main: A---B-------E
\ /
feature: C---D
E 是合并提交
有新的合并提交。
禁止快进合并:
$ git merge --no-ff feature/login
这样会强制创建合并提交,保留分支历史。
3.3 变基(Rebase)
Rebase 是 Git 中最强大也最危险的功能。
场景:你在 feature 分支开发,但 main 分支有新提交。
main: A---B---C
\
feature: D---E
合并方式1:Merge
$ git checkout feature
$ git merge main
结果:
main: A---B---C
\ \
feature: D---E---F (merge commit)
合并方式2:Rebase
$ git checkout feature
$ git rebase main
结果:
main: A---B---C
\
feature: D'---E' (重新应用提交)
Rebase 的优点:
- 历史线性,更清晰
- 没有多余的合并提交
Rebase 的缺点:
- 改变了提交历史
- 如果别人也在用这个分支,会出问题
黄金法则:
永远不要 rebase 已经推送到远程的公共分支!
3.4 解决冲突
什么时候会冲突?
两个分支修改了同一个文件的同一行。
冲突文件示例:
<<<<<<< HEAD
const user = 'xiaoming'
=======
const user = 'xiaohong'
>>>>>>> feature/login
解决步骤:
- 手动编辑文件,删除标记,保留正确内容
git add标记为已解决git commit完成合并
# 1. 编辑文件,保留 xiaoming
const user = 'xiaoming'
# 2. 标记已解决
$ git add index.js
# 3. 完成合并
$ git commit
取消合并:
$ git merge --abort
四、远程协作:多人开发不踩坑
4.1 远程仓库管理
# 查看远程仓库
$ git remote -v
# 添加远程仓库
$ git remote add origin https://github.com/xiaoming/project.git
# 修改远程地址
$ git remote set-url origin https://new-url.git
# 删除远程仓库
$ git remote remove origin
4.2 推送和拉取
# 推送到远程
$ git push origin main
# 第一次推送,设置上游分支
$ git push -u origin main
# 强制推送(危险!)
$ git push -f origin main
# 拉取远程更新
$ git pull origin main
# 拉取所有远程分支
$ git fetch --all
pull vs fetch:
# pull = fetch + merge
$ git pull origin main
# 等价于
$ git fetch origin main
$ git merge origin/main
4.3 Pull Request 工作流
完整流程:
# 1. Fork 项目到自己账号
# 2. 克隆到本地
$ git clone https://github.com/你的用户名/project.git
# 3. 添加上游仓库
$ git remote add upstream https://github.com/原作者/project.git
# 4. 创建功能分支
$ git checkout -b feature/awesome-feature
# 5. 开发、提交
$ git add .
$ git commit -m "feat: 添加新功能"
# 6. 推送到自己的仓库
$ git push origin feature/awesome-feature
# 7. 在 GitHub 上创建 Pull Request
# 8. 保持分支更新
$ git fetch upstream
$ git rebase upstream/main
$ git push -f origin feature/awesome-feature
五、高级技巧:装逼时刻到了
5.1 Stash:临时保存修改
场景:改到一半,突然要切换分支修 bug。
# 保存当前修改
$ git stash
# 查看 stash 列表
$ git stash list
# 恢复最新的 stash
$ git stash pop
# 恢复指定 stash
$ git stash apply stash@{1}
# 删除 stash
$ git stash drop stash@{0}
# 清空所有 stash
$ git stash clear
带描述的 stash:
$ git stash save "修改登录页面样式"
5.2 Cherry-pick:精准合并
场景:只想合并某个分支的某次提交。
# 把 abc123 这个提交应用到当前分支
$ git cherry-pick abc123
# 合并多个提交
$ git cherry-pick abc123 def456
# 合并一个范围的提交
$ git cherry-pick abc123^..def456
5.3 Rebase -i:交互式变基
场景:优化提交历史,合并、删除、修改提交。
# 修改最近 3 次提交
$ git rebase -i HEAD~3
会打开编辑器:
pick f7f3f6d feat: 添加登录功能
pick 310154e fix: 修复验证bug
pick a5f4a0d docs: 更新文档
# Rebase commands:
# p, pick = 使用提交
# r, reword = 使用提交,但修改提交信息
# e, edit = 使用提交,但停下来修改
# s, squash = 使用提交,但合并到前一个提交
# f, fixup = 类似 squash,但丢弃提交信息
# d, drop = 删除提交
常用操作:
1. 合并提交:
pick f7f3f6d feat: 添加登录功能
squash 310154e fix: 修复验证bug
squash a5f4a0d docs: 更新文档
三个提交会合并成一个。
2. 修改提交信息:
pick f7f3f6d feat: 添加登录功能
reword 310154e fix: 修复验证bug
pick a5f4a0d docs: 更新文档
3. 删除提交:
pick f7f3f6d feat: 添加登录功能
drop 310154e fix: 修复验证bug
pick a5f4a0d docs: 更新文档
5.4 Reflog:后悔药
场景:误操作删除了提交,想找回来。
# 查看所有操作记录
$ git reflog
# 输出类似:
# a5f4a0d HEAD@{0}: commit: 更新文档
# 310154e HEAD@{1}: commit: 修复bug
# f7f3f6d HEAD@{2}: commit: 添加功能
# abc123d HEAD@{3}: reset: moving to HEAD~1
# 恢复到某个状态
$ git reset --hard HEAD@{3}
Reflog 是 Git 的时光机,能找回几乎所有"丢失"的提交。
5.5 Bisect:二分查找 Bug
场景:代码在某次提交后出bug,但不知道是哪次。
# 开始二分查找
$ git bisect start
# 标记当前版本有问题
$ git bisect bad
# 标记某个版本没问题
$ git bisect good abc123
# Git 会自动切换到中间的提交
# 测试,然后标记
$ git bisect good # 或 git bisect bad
# 重复,直到找到问题提交
# 结束
$ git bisect reset
5.6 Worktree:多个工作目录
场景:需要同时在多个分支工作。
# 创建新工作目录
$ git worktree add ../project-hotfix hotfix/urgent-fix
# 查看所有工作目录
$ git worktree list
# 删除工作目录
$ git worktree remove ../project-hotfix
六、最佳实践
6.1 提交原则
1. 小步快跑
每个提交只做一件事,别一次提交改 20 个文件。
2. 提交前检查
# 查看改动
$ git diff
# 查看将要提交的内容
$ git diff --cached
3. 写好提交信息
参考前面的"约定式提交"。
6.2 分支策略
Git Flow(适合大项目):
main 生产分支
develop 开发分支
feature/* 功能分支
hotfix/* 紧急修复
release/* 发布分支
GitHub Flow(适合小团队):
main 主分支
feature/* 功能分支
6.3 配置优化
# 设置用户信息
$ git config --global user.name "小明"
$ git config --global user.email "xiaoming@example.com"
# 设置默认编辑器
$ git config --global core.editor vim
# 彩色输出
$ git config --global color.ui auto
# 设置默认分支名
$ git config --global init.defaultBranch main
# 推送时自动设置上游分支
$ git config --global push.autoSetupRemote true
# 拉取时使用 rebase 而不是 merge
$ git config --global pull.rebase true
# 查看所有配置
$ git config --list
6.4 .gitignore 文件
# Node.js
node_modules/
npm-debug.log
.env
# 编辑器
.vscode/
.idea/
*.swp
# 操作系统
.DS_Store
Thumbs.db
# 构建产物
dist/
build/
*.log
七、常见问题
Q1: 如何撤销已推送的提交?
# 方法1:Revert(推荐)
$ git revert abc123 # 创建一个新提交来撤销
$ git push
# 方法2:Reset + 强制推送(危险!)
$ git reset --hard HEAD~1
$ git push -f
Revert 更安全,因为不会改变历史。
Q2: 如何合并多个提交?
# 交互式 rebase
$ git rebase -i HEAD~3
# 然后把后面的提交改成 squash
Q3: 如何删除远程分支?
$ git push origin --delete feature/old-feature
Q4: 如何修改已推送的提交信息?
**不要这样做!**除非确定只有你在用这个分支。
$ git commit --amend -m "新信息"
$ git push -f
Q5: 如何同步 Fork 的仓库?
# 添加上游仓库
$ git remote add upstream https://github.com/原作者/project.git
# 拉取上游更新
$ git fetch upstream
# 合并到本地main
$ git checkout main
$ git merge upstream/main
# 推送到自己的仓库
$ git push origin main
八、小明的 Git 技巧清单
入门必会:
- ✅ add, commit, push, pull
- ✅ branch, checkout, merge
- ✅ status, log, diff
进阶技能:
- ✅ commit --amend
- ✅ reset, revert
- ✅ stash
- ✅ rebase
装逼技能:
- ✅ cherry-pick
- ✅ rebase -i
- ✅ reflog
- ✅ bisect
- ✅ worktree
团队协作:
- ✅ 规范的提交信息
- ✅ Pull Request 流程
- ✅ 分支管理策略
- ✅ Code Review
总结
Git 看起来简单,但要用好并不容易。
三个建议:
- 多练习
自己建个项目,把每个命令都试一遍。 - 看历史
经常用git log --graph看分支历史,理解分支合并的原理。 - 敢于试错
有 reflog 这个后悔药,别怕误操作。
掌握这些技巧,你就能从"只会三板斧"的小白,进阶到让同事刮目相看的 Git 大神。
下次团队协作时,当别人还在纠结冲突,你已经优雅地 rebase 完毕了。
相关文章:
- 单例模式:最简单也最容易用错
- CI/CD 入门:让代码自动飞(即将发布)
有问题?欢迎评论区留言!
冷笑话时间 🎭
程序员 A:"你知道为什么 Git 的 logo 是三个分叉吗?"
程序员 B:"因为代表三个分支?"
程序员 A:"不,因为作者看到合并冲突时,头发叉成了三股。"
程序员 B:"......有道理。"
(完)