作为开发者日常工作中最核心的工具之一,Git 的重要性怎么强调都不为过。我在过去十年的开发经历中,见证过太多因为不熟悉 Git 而导致的项目灾难——代码丢失、版本混乱、团队协作冲突。Git 绝不仅仅是一个简单的代码备份工具,而是现代软件开发流程的基石。
Git 的分布式架构是其革命性的设计。与传统的集中式版本控制系统(如 SVN)不同,每个开发者的本地仓库都包含完整的项目历史。这意味着你可以:
重要提示:在开始使用 Git 前,请确保你理解以下三个核心概念:
- 工作区(Working Directory):你实际编辑文件的地方
- 暂存区(Staging Area):准备提交的文件快照
- 版本库(Repository):存储所有提交历史的数据库
首次使用 Git 必须设置用户身份,这个信息会嵌入到你的每次提交中:
bash复制git config --global user.name "你的真实姓名"
git config --global user.email "公司邮箱或个人主邮箱"
我强烈建议配置以下实用选项:
bash复制# 设置默认编辑器(VSCode用户替换为code --wait)
git config --global core.editor vim
# 开启颜色显示
git config --global color.ui auto
# 设置常用命令别名
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch
根据不同的使用场景,我们有多种初始化仓库的方式:
bash复制mkdir project && cd project
git init
bash复制# 完整克隆(推荐)
git clone https://github.com/user/repo.git
# 浅克隆(仅获取最新历史,适合CI环境)
git clone --depth=1 https://github.com/user/repo.git
bash复制git init --bare /path/to/repo.git
避坑指南:不要在已有项目的目录中嵌套执行
git init,这会导致子目录的Git仓库与父仓库冲突。如果意外执行了,删除子目录中的.git文件夹即可。
git status应该是你使用最频繁的命令。我习惯在每次操作前后都执行它来确认状态:
bash复制# 精简输出格式
git status -s
输出示例:
code复制 M README.md
A new-file.txt
D old-file.txt
?? untracked-file
文件状态标识:
:未修改M:已修改A:已添加D:已删除??:未跟踪比较差异时,根据需求选择不同模式:
bash复制# 工作区 vs 暂存区
git diff
# 暂存区 vs 最新提交
git diff --cached
# 工作区 vs 最新提交
git diff HEAD
# 比较两个分支
git diff main..feature
添加文件到暂存区有多种策略:
bash复制# 添加特定文件
git add filename.txt
# 添加所有变化(包括新文件和删除)
git add -A
# 交互式添加(推荐用于复杂修改)
git add -p
交互模式中你可以:
y 暂存当前块n 不暂存s 分割块e 手动编辑删除和移动文件也有Git专用命令:
bash复制# 删除文件并暂存删除操作
git rm obsolete.txt
# 仅从Git中删除但保留本地文件
git rm --cached sensitive-data.env
# 重命名文件(相当于mv + git rm + git add)
git mv old-name.txt new-name.txt
一个良好的提交应该:
bash复制git commit -m "feat: 实现用户登录功能
- 添加JWT认证中间件
- 创建用户模型和控制器
- 编写单元测试用例"
修正提交的几种方式:
bash复制# 修改最近一次提交(可改消息和内容)
git commit --amend
# 紧急修复时只改内容不改消息
git commit --amend --no-edit
# 重置提交(谨慎使用)
git reset --soft HEAD~1 # 保留修改在暂存区
git reset --mixed HEAD~1 # 修改回到工作区(默认)
git reset --hard HEAD~1 # 彻底丢弃修改(危险!)
基础日志查看:
bash复制git log
实用参数组合:
bash复制# 单行显示+图形化分支
git log --oneline --graph --all
# 显示最近2周某人的提交
git log --since="2 weeks ago" --author="Alice"
# 显示包含特定字符串的提交
git log -S"TODO" -p
# 显示某个文件的修改历史
git log -p -- path/to/file.js
查看特定提交的详细信息:
bash复制git show abc123
git show HEAD~3:src/main.js # 查看历史版本文件内容
现代Git(2.23+)推荐使用更语义化的命令:
bash复制# 创建并切换分支(替代checkout -b)
git switch -c new-feature
# 切换回主分支
git switch main
分支合并策略对比:
| 合并方式 | 命令 | 适用场景 | 历史记录 |
|---|---|---|---|
| 普通合并 | git merge feature |
功能分支合并 | 保留分支历史 |
| 非快进 | git merge --no-ff feature |
重要功能合并 | 明确合并点 |
| 变基 | git rebase main |
保持线性历史 | 重写提交历史 |
经验之谈:团队协作时,避免对已推送到远程的分支执行rebase,这会导致其他成员的历史混乱。变基只适用于本地未推送的提交。
查看分支关系图:
bash复制git log --graph --oneline --all
删除分支的注意事项:
bash复制# 安全删除已合并分支
git branch -d old-feature
# 强制删除未合并分支(可能丢失工作)
git branch -D experimental
# 删除远程分支(需要推送空引用)
git push origin --delete stale-branch
查看远程配置:
bash复制git remote -v
git remote show origin
添加多个远程仓库的典型场景:
bash复制# 添加公司内部仓库
git remote add upstream git@internal.com:project.git
# 添加开源项目上游
git remote add upstream https://github.com/opensource/project.git
获取远程更新的安全方式:
bash复制# 只下载不合并(推荐先fetch再决定)
git fetch origin
# 查看远程分支变化
git log origin/main..main
# 合并远程变更(等同于pull但更可控)
git merge origin/main
推送代码的注意事项:
bash复制# 首次推送建立跟踪关系
git push -u origin feature-x
# 强制推送(慎用!会覆盖他人工作)
git push -f
# 删除远程分支
git push origin --delete temp-branch
bash复制# 撤销单个文件的修改
git restore file.txt
# 撤销所有未暂存的修改
git restore .
# 彻底清除未跟踪文件
git clean -fd
三种reset模式对比:
| 模式 | 影响范围 | 常用场景 |
|---|---|---|
| --soft | 只移动HEAD | 修改提交消息 |
| --mixed | 重置暂存区(默认) | 重新组织提交 |
| --hard | 彻底丢弃修改 | 放弃实验性代码 |
安全回滚(推荐团队使用):
bash复制# 创建反向提交(不修改历史)
git revert abc123
# 回滚合并提交
git revert -m 1 merge-commit
临时保存工作进度:
bash复制# 储藏当前修改(包含未跟踪文件)
git stash push -u
# 查看储藏列表
git stash list
# 应用最新储藏(不删除)
git stash apply
# 应用并删除特定储藏
git stash pop stash@{1}
发布版本的标准做法:
bash复制# 创建带注释的标签
git tag -a v1.2.0 -m "Release version 1.2.0"
# 推送标签到远程
git push origin v1.2.0
# 删除远程标签
git push origin --delete tag v0.9.0
bash复制# 应用特定提交到当前分支
git cherry-pick abc123
# 解决冲突后继续
git cherry-pick --continue
# 放弃当前cherry-pick
git cherry-pick --abort
问题1:fatal: refusing to merge unrelated histories
解决方案:
bash复制git pull origin main --allow-unrelated-histories
问题2:error: failed to push some refs
原因:远程有本地没有的提交
解决方案:
bash复制git pull --rebase origin main
git push
问题3:误删未合并分支
恢复步骤:
bash复制# 查看最近的操作记录
git reflog
# 找到删除前的commit hash
git branch recovered-branch abc123
定位引入bug的提交:
bash复制git bisect start
git bisect bad # 当前版本有问题
git bisect good v1.0 # 这个版本正常
# 测试当前版本后执行:
git bisect good/bad # 根据测试结果标记
git bisect reset # 结束调试
经过多年实践,我总结出这些提高Git效率的方法:
git pull --rebase最后分享一个查看Git命令可视化效果的技巧:
bash复制# 安装git可视化工具
brew install tig # Mac
apt install tig # Linux
# 使用tig浏览历史
tig