做了这么多年开发,如果要我从所有工具里挑一个“最值得花时间搞懂”的,那一定是 Git。这不是因为它流行,而是因为它背后那套分布式协作体系,几乎成了现代软件工程的地基。你去看任何一个招聘 JD,不管后端、前端、算法还是测试,都逃不开“熟练使用 Git”这几个字。可现实是,大多数人只是把 Git 当成一个“上传下载代码”的工具,记住了十来条命令就开始干活,一出问题就慌,只能去网上搜“git 回滚”“git 冲突怎么解决”,搜到的答案五花八门,运气好用上,运气不好反而把仓库搞得更乱。
今天这篇内容,我想换个讲法:先把 Git 这套版本管理系统的核心理论和设计逻辑拆清楚,再把它落到日常开发的具体操作上。文章会覆盖安装配置、日常提交推送、分支协作、高频报错排查,以及我这两年实际踩过的坑和经验总结。不管你是刚接触 Git 的新人,还是用了很久但总觉得没完全吃透的老手,这篇应该都能给你一些新的收获。Git 这东西,理解到哪一层,你就能把它用到哪一层。
1. 分布式协作体系的核心逻辑与设计思路
1.1 为什么版本管理是协作的地基
先回到底层问题:为什么一定要有版本管理系统?你可能会说,不就是一个“代码备份”吗?如果只是备份,那我每隔一小时复制一份文件夹不就行了?这个想法在单人、小项目里勉强能撑住,但一旦涉及三人以上的协作,就会立刻暴露问题——你怎么知道某个文件是谁改的?两个人同时改了同一个文件怎么办?线上出了 bug,怎么知道是哪个版本引入的?
这些问题其实对应了版本管理系统需要解决的四个核心能力:历史追溯、并行协作、冲突处理、安全回滚。“复制文件夹”的方案在这四个维度上几乎全都无法胜任——它没有增量记录,无法准确定位变化,更不可能自动合并多人同时修改的内容。
Git 之所以能成为事实标准,是因为它在架构层面把这些问题考虑得非常彻底。它采用的是分布式架构,每一个开发者的本地仓库都是完整的历史副本,不像早期集中式版本管理那样,所有操作都必须依赖中央服务器。这种设计带来了两个直接好处:一是离线也能完整工作,提交、查看历史、创建分支都不需要网络;二是容灾能力极强,任何一个人的本地仓库都是一个完整备份,中央仓库挂了也能从任意一个克隆恢复。
1.2 Git 的快照机制而非差异存储
很多人对 Git 有一个误解,以为它存储的是文件的“差异”。实际上,Git 保存的是快照——每次 commit 时,它会把所有文件的状态记录下来,而不仅仅是变化的部分。只不过为了节省空间,如果文件没有变化,Git 不会再次保存文件内容,而是直接复用上一个版本的引用。所以从逻辑上讲,每一次 commit 都对应一个完整的项目状态。
这个设计跟早期的 SVN 形成鲜明对比。SVN 保存的是文件差异,要还原某个版本,你得把初始版本和一系列补丁逐个应用。Git 因为是快照式的,切换分支、回滚版本都非常快,代价则是仓库体积会更大一些。不过现代磁盘和网络都不差,这个取舍非常值得,换来的是一整套高效的本地操作能力和分支管理体验。
1.3 一次提交背后发生了什么
理解 Git 的最佳路径,我觉得是看一次 git commit 背后到底发生了哪些事。整个流程可以拆成几个阶段:
- 工作区:你正在编辑的普通文件夹,这里面的文件是给人看的,也是给编辑器用的。
- 暂存区:也叫 Index,是你用 git add 把文件放进去的地方,相当于一个“待提交清单”。
- 本地仓库:git commit 之后,暂存区的内容被打成一个快照,写入 .git 目录,这个动作就是一次提交。
- 远程仓库:通过 git push 把本地提交推送到远端,其他人才能看到你的代码。
这个四个区域的划分,是理解后续所有命令的基础。比如 git reset 里的 --soft、--mixed、--hard 三档参数,本质就是控制指针和内容在“仓库、暂存区、工作区”之间怎么移动。理解了这些,你就不会再把命令当咒语背了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Git 环境准备:安装、配置与初始化实操
2.1 不同平台的安装方式与命令行环境选择
先把环境搞定。不同操作系统安装 Git 的方式不太一样,我分别说一下我自己试过比较稳妥的方案。
Windows 平台:直接去 Git 官网下载 Git for Windows,安装包一路 Next 即可。需要注意的是,安装过程中会让你选择“调整 PATH 环境变量”,建议选默认的“Git from the command line and also from 3rd-party software”,这样 Git 命令能在 CMD 和 PowerShell 里直接用,也方便后续 IDE 集成。安装完会自动带一个 Git Bash 工具,这个工具模拟了 Linux 终端环境,你在 Windows 上跑 Git 命令基本不会遇到兼容问题。
Windows 上还有一款叫 TortoiseGit 的可视化工具,中文社区习惯叫“小乌龟”,安装后会集成到右键菜单,用图标状态直观显示文件是否被修改。对刚接触 Git 的人来说它能降低上手门槛,但我个人不推荐长期依赖它——Git 是高频操作,把核心命令练熟以后效率会高得多。
macOS 平台:最省事的方式是安装 Xcode Command Line Tools,在终端执行 xcode-select --install,系统会弹出安装器。装完之后 Git 就有了。如果你需要更新的版本,推荐用 Homebrew 执行 brew install git。另外,macOS 自带的 Git 版本可能比较老,我建议用 brew 装新版,避免之后遇到一些老版本才有的兼容性问题。
Linux 平台:Debian/Ubuntu 系用 sudo apt install git,CentOS/RHEL 系用 sudo yum install git 或 sudo dnf install git。装完用 git --version 验证一下,如果输出了版本号就说明成功了。
注意:Windows 环境下安装 Git 时,如果之前装过旧版本,可能遇到 PATH 没刷新的情况。解决办法是重开一个终端窗口,或者手动检查环境变量里是否已经加入 Git 的 bin 目录。
2.2 全局配置:提交者信息与换行符设置
安装完成后的第一件事,是配置你的身份信息。这个信息会写进每一次提交里,代码评审、问题追溯全靠它:
bash复制git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
这两条配置会写入用户目录下的 .gitconfig 文件。特别提醒一句:user.email 最好填写能够关联到你代码托管平台账号的邮箱,否则你在平台上提交的代码可能不会被识别到用户名下。
除了身份信息,还有两个配置我建议你提前设置好:
- 默认分支名:新一点的 Git 版本默认分支是 master,但 GitHub、Gitee 等平台默认是 main。执行 git config --global init.defaultBranch main,可以让本地新建仓库时也默认使用 main。
- 换行符处理:Windows 和 Linux/macOS 的换行符不同,跨平台协作时经常出现整个文件被标记为已修改的情况。建议在 Windows 上执行 git config --global core.autocrlf true,在 macOS/Linux 上执行 git config --global core.autocrlf input,让 Git 自动处理换行符的转换。
这些配置属于“一次设置,长期受益”的类型,值得在第一天就弄好。
2.3 远程仓库认证:SSH 密钥的生成与配置
日常开发中,连接远程仓库有 HTTPS 和 SSH 两种协议。HTTPS 的优点是不用额外配置,缺点是每次 push 都要输账号密码,就算用凭据管理器记住密码,在公司电脑上也不太安全。我个人的建议是:能配 SSH 就配 SSH,一劳永逸。
生成 SSH 密钥的命令是:
bash复制ssh-keygen -t rsa -b 4096 -C "你的邮箱"
执行后会让你选择保存路径和输入密码,默认路径就行,密码可以直接留空(如果你不想要每次连远端都输一遍的话)。生成的密钥默认在 ~/.ssh/id_rsa.pub,这是公钥,可以给别人看;对应的 id_rsa 是私钥,绝对不能泄露。
拿到公钥之后,登录你的代码托管平台(这里以 Gitee 为例),进入“设置 -> SSH 公钥”,把 id_rsa.pub 里的内容复制粘贴保存。GitHub 和 GitLab 也都有类似的入口,操作逻辑完全一样。配置完成后,用 ssh -T git@gitee.com 测试,如果看到欢迎信息就说明通了。
如果你同时使用多个平台,比如公司 GitLab 和个人 Gitee,可以通过修改 ~/.ssh/config 文件为不同的 Host 指定不同的密钥:
ini复制Host gitee.com
HostName gitee.com
User git
IdentityFile ~/.ssh/id_rsa_gitee
Host gitlab.company.com
HostName gitlab.company.com
User git
IdentityFile ~/.ssh/id_rsa_company
2.4 初始化项目:git init 与 .gitignore
配置好环境,就可以正式创建仓库了。在项目根目录执行 git init,当前目录就会被初始化为一个 Git 仓库。执行后生成的 .git 目录是整个仓库的“数据库”,所有提交历史、分支指针、配置信息都存在这里。这个目录不要手动去改,也不需要提交到远端,它只是你本地工具的一部分。
紧接着要做的是创建 .gitignore 文件。它的作用是把不需要纳入版本管理的文件类型或目录列出来,比如编译产物 node_modules、虚拟环境 venv、IDE 个性化的配置 .idea、临时文件 *.tmp、敏感配置文件 .env 等。之所以必须做这一步,是因为如果不把这些排除掉,它们会被误提交进仓库,导致仓库体积膨胀、泄露敏感信息,还容易造成 merge 冲突。
不同语言生态的 .gitignore 模板,GitHub 上有官方整理,可以直接按项目类型挑一份改改。我自己通常会至少写进这几项:
text复制node_modules/
dist/
build/
*.log
.DS_Store
.env
.idea/
.vscode/
重要:.gitignore 只对未跟踪的文件生效。如果一个文件已经被提交进仓库,再在 .gitignore 里忽略它是没用的。遇到这种情况,需要先执行 git rm --cached
把它从跟踪列表中移除,再提交。
3. 日常开发链路:从拉取代码到合入分支
3.1 远程仓库克隆与协议选择
要参与一个已有的项目,第一步是把它克隆到本地:
bash复制git clone <仓库地址>
仓库地址分 HTTPS 和 SSH 两种。如果刚才已经配好 SSH 密钥,建议直接用 SSH 地址,形如 git@gitee.com:xxx/project.git。clone 命令有几个常用参数值得记一下:
- --depth 1:只克隆最近一次提交,适合大型项目快速拉取,但会丢失历史,后续操作受限。
- --branch <分支名>:克隆指定分支,而不是默认分支。
- -o 自定义远程名:默认远程名是 origin,一般不用改。
clone 完成之后,本地会自动生成一个 origin 远程引用,指向原来的仓库地址。后续 push、pull、fetch 都默认与它通信。
3.2 提交信息的规范写法与推送流程
日常开发的循环其实就三板斧:add、commit、push。
bash复制git add .
git commit -m "feat: 完成用户登录模块"
git push
这里我想重点说说 commit message 的写法。很多人觉得这是小事,写什么都行,但等到你翻历史日志、做代码回滚、出事故定位的时候,就会意识到一份清晰的提交记录有多重要。业界比较通行的是 Conventional Commits 规范,格式大概是:
text复制类型(可选范围): 描述
feat: 新增功能
fix: 修复 bug
docs: 文档变更
refactor: 重构代码
style: 格式调整
test: 增加测试
chore: 构建或工具变更
举几个实际例子:
- git commit -m "fix: 修复登录接口在空密码时返回 500 的问题"
- git commit -m "feat(user): 新增用户资料编辑页面"
- git commit -m "refactor: 抽取订单状态机为独立模块"
这样写的好处是,git log --oneline 扫一眼就能知道每个提交是做什么的。配合一些代码托管平台的自动生成 changelog 功能,效率会非常高。
commit 之后要把代码推到远端:git push。第一次推新分支时,Git 会提示你没有上游分支,需要执行:
bash复制git push --set-upstream origin 分支名
这条命令的意思是在远程创建同名分支,并建立本地分支与远程分支的跟踪关系。以后在这个分支上直接 git push 就可以了。
3.3 撤销与修复的正确姿势
Git 之所以让新人害怕,很大程度上是因为不知道做错了怎么“后悔”。其实 Git 内部机制决定了大多数操作都可以撤销,关键是要知道不同场景该用哪个命令。
修改最近一次提交:如果你想修改“最近一次提交”的提交信息,或者漏了一个文件想补进去,用:
bash复制git add missed-file.txt
git commit --amend --no-edit
加了 --no-edit 表示保留原来的提交信息,只是把新文件补进这个提交。如果想同时修改提交信息,去掉 --no-edit 或者在 commit --amend 时直接写 -m "新的提交信息"。注意,amend 会生成一个新的提交 ID,如果这个提交已经被推到远端,并且是多人共享的分支,就不要用 amend,否则会跟队友的记录冲突。
撤销某个文件的改动:想放弃工作区某个文件的修改:
bash复制git restore <file>
这个命令会用当前 HEAD 的文件内容覆盖工作区文件,属于不可恢复操作,执行前想清楚。
把文件从暂存区撤出:如果你 git add 多了,想取消暂存:
bash复制git restore --staged <file>
这个只动暂存区,文件内容不会变。
回滚整个提交:如果提交已经做了,但想撤销它的改动,有两种思路。一是 reset,它会让 HEAD 指针退回到某个历史版本,工作区可能会被动修改甚至丢代码,适合还没有推送的本地提交。二是 revert,它会生成一个新的提交来反做之前那次提交的改动,保留完整历史,适合已经推送到远端的分支。这三档 reset 非常容易混淆,我用一个表格把它们的区别列出来:
| 命令 | HEAD 指针 | 暂存区 | 工作区 | 适用场景 |
|---|---|---|---|---|
| git reset --soft |
移动 | 不变 | 不变 | 想重新组织多个提交 |
| git reset --mixed |
移动 | 重置 | 不变 | 撤销 add,保留文件修改 |
| git reset --hard |
移动 | 重置 | 重置 | 彻底放弃所有本地改动 |
我自己最常遇到的情况是提交信息写错了、遗漏了文件、刚提交完发现一个大 bug。只要还没 push,用 amend 或者 mixed reset 都能轻松解决。一旦 push 到远端,就老老实实用 revert,安全第一。
3.4 分支的创建、切换与删除
分支是 Git 协作体系里最核心的概念,本质上它只是一个指向某次提交的可移动指针。创建、切换、合并分支的成本都极低,这是 Git 分布式设计带来的天然优势。
bash复制git branch feature-login # 创建分支
git checkout feature-login # 切换分支
新版本的 Git 推荐用 git switch 来切换分支:
bash复制git switch -c feature-login # 创建并切换到新分支
删除分支的命令是:
bash复制git branch -d feature-login # 已合入的分支用 -d 删除
git branch -D feature-login # 没合入但坚持要删,用 -D 强制删除
删除远端分支:
bash复制git push origin --delete feature-login
我自己在工作流上有一条底线:主分支永远保持可发布状态,所有开发都在功能分支上进行。分支命名建议跟需求或缺陷编号挂钩,比如 feature/order-export、fix/issue-2314,这样看分支名就知道这一串提交在干嘛。
4. 分支策略与并行协作范式
4.1 两种主流分支模型的选型思考
团队协作光有 Git 还不够,还需要定一套分支管理规则。目前行业里最常见的有两种范式:
Git Flow:分支种类多,包括 main(主分支)、develop(开发分支)、feature/(功能分支)、release/(发布分支)、hotfix/*(热修复分支)。它的优点是流程严密,适合有固定发布节奏、需要同时维护多个版本的团队,比如传统企业或大型成熟产品。缺点是流程重,所有改动都要经过多层合入,小团队用起来会觉得繁琐。
GitHub Flow:只保留 main 和一个(或多个)功能分支。所有改动都从 main 拉分支,完成后提 Pull Request 合并回 main,合并即发布。它的优点是极简、快,非常适合持续部署的互联网团队。缺点是对测试和代码评审的要求高,否则很容易把坏代码合并进主分支。
我的观点是:不要为了流程而流程。两三个人的小项目用 GitHub Flow 就很好,十几个人做多版本交付,Git Flow 能帮你减少很多手忙脚乱。关键是把规则定清楚,并且保持一致。
4.2 合并三件套:merge 与 rebase 的选择
合并分支最常用的命令是 git merge,这个命令的优点是保留了真实的合并历史,适合团队协作时追溯“这个改动到底是谁、在什么时候合进来的”。缺点是会产生分叉的提交图,看多了会觉得乱。
git rebase 则会把当前分支的提交“搬”到目标分支最新的提交之后,让提交历史变成一条干净的直线。它的好处是历史非常清晰,适合在推送之前整理自己的提交。缺点是一旦 rebase 已经推送到远端的提交,就会造成两边的历史不一致,队友 push 时会被强制拒绝,处理起来很麻烦。
我的经验是这么区分的:本地提交还没推远端,就大胆用 rebase,把多个杂乱的提交整理成几个有意义的提交再推上去;如果是多人共享的分支,永远用 merge。
另外,cherry-pick 也是一个非常实用的命令。它可以把任意一个分支上的某个提交按原样应用到当前分支上,用来应急修 bug、移植功能特别方便:
bash复制git cherry-pick <commit-id>
4.3 冲突的本质与解决流程
冲突应该是开发者遇到最多的 Git 报错之一。冲突的本质是:两个人同时修改了同一文件的同一区域,Git 不知道哪一份才是你想要的,只能把决定权交给你。
解决冲突的流程是固定的:
- 打开冲突文件,找到类似 <<<<<<< HEAD 和 >>>>>>> 分支名的标记。
- 中间的内容是被冲突的两份代码,手动选择保留哪一份,或者把两者整合成一个合理版本。
- 删掉所有冲突标记。
- 重新 git add 该文件,再 git commit 完成合并。
这里分享一个习惯:提交前先拉取最新代码,减少冲突发生概率。我一般是每天早上一到工位,先把当前功能分支 rebase 一下最新的 main,确保自己在最近的基础上开发。拉取完成后的冲突解决,心态上不要慌,冲突是协作的正常产物,解决它就是一个把双方代码都看一遍的过程,很多时候还能顺带发现一些隐性 bug。
4.4 git worktree:单仓库多分支并行开发
如果手头任务比较杂,经常需要同时兼顾多个分支,比如一个分支在写新需求,另一个分支要紧急修线上 bug,那就得反复 stash、切换、再切换。每次切换分支,Git 会更新工作区文件,编译缓存、IDE 索引也跟着失效,非常磨人。
git worktree 解决的就是这个问题。它允许你从同一个仓库中创建出多个工作目录,每个目录对应一个分支,互不干扰:
bash复制git worktree add ../hotfix-2314 fix/issue-2314
命令执行后,会在上级目录创建一个 hotfix-2314 文件夹,里面 checkout 的是 fix/issue-2314 分支。你可以在主工作区继续写新功能,在 hotfix 目录里修线上问题,两个目录共用同一个 Git 仓库的历史,互不阻塞。
用完可以删除工作树:
bash复制git worktree remove ../hotfix-2314
这个功能我用过之后基本离不开了,特别是在值班修 bug 的日子,它比来回切换分支的效率高出一大截。
5. 高频报错与疑难杂症的实战排查
5.1 本地仓库与远程引用的常见 fatal 错误
Git 的报错信息其实写得相对清晰,但很多人一看到 fatal 就慌了,没仔细看就到处搜答案。我挑了日常工作中出现频率极高的几类,结合原因和解决方法列个速查表:
| 报错信息 | 原因分析 | 解决方法 |
|---|---|---|
| fatal: not a git repository (or any of the parent directories): .git | 当前目录不是 Git 仓库,或没有 .git 目录 | 确认是否在项目根目录;若在子目录且确实是仓库,检查 .git 是否被删除,必要时重新 git init 或 git clone |
| fatal: 'origin' does not appear to be a git repository | 本地仓库没有配置名为 origin 的远程仓库 | 执行 git remote add origin <仓库地址>,或 git remote -v 检查远程配置 |
| fatal: refusing to merge unrelated histories | 两个分支的历史没有共同祖先,通常是新仓库和已有仓库强行合并 | 如果确认要合并,加 --allow-unrelated-histories |
| fatal: Authentication failed | 账号密码错误或认证信息过期 | 检查凭据管理器,更新账号密码;或改用 SSH 方式推送 |
| fatal: unable to access 'https://...': Could not resolve host | DNS 解析失败或网络问题 | 检查网络、DNS 设置,确认仓库地址没有拼写错误 |
这里面最典型的是第一种。很多新手在项目子目录里执行 git status,立刻收到“not a git repository”的报错,其实只是因为当前目录不是仓库根目录。Git 会一层层向上找 .git 目录,如果找不到就报这个错。遇到它先 pwd 看看自己在哪,再往上走一层试试,多半就解决了。
5.2 认证与密钥相关的配置问题
每次配置新电脑,最容易卡住的就是 SSH 认证。常见的表现是:密钥生成成功了、也传到托管平台了,但执行 git push 还是弹出密码输入框,或者提示 Permission denied (publickey)。
排查流程按顺序来:
- 确认 ssh 代理有没有运行:在终端执行 eval "$(ssh-agent -s)",然后 ssh-add ~/.ssh/id_rsa。
- 确认 git 使用的是 SSH 而不是 HTTPS:git remote -v 查看远程地址,如果是 https:// 开头,改成 SSH 格式。
- 测试 SSH 连接:ssh -T git@gitee.com,看返回结果。如果输出“You've successfully authenticated”,说明认证没问题,问题就在远程地址上。
- 检查密钥权限:私钥文件的权限不能太宽松,在 Linux/macOS 下执行 chmod 600 ~/.ssh/id_rsa。
还有个跟 IDE 相关的报错:login failed. check api token or gitlab version. log in via git if the version is old。这类问题常见于 IDEA 集成 GitLab 时,原因是 IDE 的 GitLab API Token 失效,或者 GitLab 版本太旧、IDE 插件不支持。解决办法是先确认你到底用的是账号密码还是 Token 登录,Token 失效就重新生成一个;GitLab 版本过老就优先用 git 命令行方式操作,IDE 里只保留基础的 Git 配置。
5.3 IDE 集成 Git 的配置要点
现在主流的开发环境基本都内置或支持 Git 插件,比如 IDEA、VSCode、Android Studio。它们的配置思路大都一致:先指定 Git 可执行文件路径,再配置 SSH 密钥或凭据,最后在 VCS 菜单里操作。
IDEA 里配置 Git 的路径是:File -> Settings -> Version Control -> Git,右边 Path to Git executable 选到 git.exe 或者系统 Git 的安装路径。IDE 里提交代码时,它会调用类似这样一个命令:
bash复制git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks ...
这三个参数很多人不理解,其实解释起来很简单:
- diff.mnemonicprefix=false:关闭差异显示中相对路径前缀的助记符,让文件路径显示更直观。
- core.quotepath=false:让 Git 在终端里输出中文路径时不转义成八进制编码,这也是为什么你复制代码里的中文文件名到 Git 命令里会看到一堆转义字符的原因。
- --no-optional-locks:禁止 Git 在 IDE 操作时获取一些可选的内部锁,避免影响其他进程的读写。
VSCode 用户装上官方 Git 插件后,最实用的功能就是左侧“源代码管理”面板里的图形化 diff、暂存和气点提交。但如果遇到插件解决不了的问题,我还是建议切到终端按命令行排查,可诊断的信息多得多。
5.4 安全防范:警惕 .git 目录泄露
聊一个可能很多人没注意过的安全问题。前面提到过,.git 目录里保存着仓库的完整历史,包括所有提交内容、分支信息、配置信息。如果你不小心把这个目录直接暴露到公网服务器上,就等于把自己的源代码拱手送人。这个动作的技术原理很简单,但我不想展开讲“怎么下载”,更重要的是怎么防。
我的几条经验:
- Web 服务器配置里显式禁止访问 .git 目录,这在 Nginx 里加一条 deny 规则就行。
- 部署上线前,确认打包产物里不包含 .git 目录。
- 定期检查代码里有没有把 .env、配置文件这类敏感信息提交进仓库,发现就立刻轮换密钥。
- 给代码仓库开启分支保护,要求合并必须经过评审。
安全这根弦,任何时候都不能松。
6. 进阶技巧与我的真实使用体会
想再写几个平时能明显提升效率的小操作,然后用我实际的经验收尾。
git log 的更好用法:默认的 git log 输出非常长,推荐记住这两个:
bash复制git log --oneline --graph --decorate --all
这条命令会把分支图和提交记录并列展示,一眼看清仓库全貌。我自己一般会配个别名,输入 git tree 就能执行。
git stash 的临时保存:做到一半的活被紧急插单打断,又不想为了切分支而提交半成品,用:
bash复制git stash push -m "订单模块开发中"
git stash list # 查看暂存列表
git stash pop # 恢复最近一次暂存
git reflog 后悔药:这是我最想安利给所有人的命令。它记录了 HEAD 指针每次移动的历史,连被 reset --hard 弄丢的提交也能找回来。只要你没清理本地仓库,git reflog 里就有痕迹,然后可以用 git reset --hard
说回经验。我见过很多同事在 Git 上踩坑,总结下来无非三种:一是对命令不熟,凭印象乱试;二是提交太频繁,导致历史一片混乱;三是没有理解“本地分支”和“远程分支”的对应关系,推错分支或者被迫 force push。我的建议很简单:每天花十分钟维护你的 Git 习惯,提交前看一次 git status,提交时写清楚 message,推送前再 diff 一遍。听起来麻烦,但长期下来的收益远超这些成本。
Git 真正厉害的,不是某条命令能解决特定问题,而是它那套“对象模型”放之四海而皆准——只要你理解了提交、分支、引用这些底层概念,不管以后换什么工具、换什么平台,都能很快上手。这也是我为什么愿意花一整篇的篇幅,从理论讲到实践,从头到尾过一遍的原因:这个工具值得你认真对待。
