我一直觉得,git 是那种"不学觉得没必要,学了就回不去"的工具。
尤其当你开始正经写代码、和多人协作、需要回溯版本的时候,git 不是"可选技能",而是吃饭的家伙。但 git 的学习曲线又确实劝退不少人——命令一堆、概念抽象、动不动就冲突,网上教程要么太长,要么只教命令不讲为什么,看完还是懵。
这篇文章我想换个讲法:不堆砌命令,而是按照一个新手真正会经历的路径来走一遍——从安装、第一份配置,到提交、回滚、分支协作、远程推送,把每一环背后的逻辑和实际工作中一定会踩的坑讲透。目标是你看完能直接上手,遇到问题也大致知道往哪个方向排查。
1. 装好 Git 只是开始:安装细节和 Git Bash 为什么重要
很多人以为装 Git 就是一路 Next,装完就完事。实际上安装环节有几步选错,后面会一直别别扭扭。
1.1 Windows 安装时最容易忽略的三个选项
如果你用的是 Windows,去官网下载安装包后,有几个关键界面需要留意。
第一个是 "Adjusting your PATH environment" 这一步,一定要选中间项 "Git from the command line and also from 3rd-party software"。这个选项会把 git 命令注册到系统的 PATH 里,意味着以后你在 CMD、PowerShell、或者 VS Code 的终端里都能直接敲 git。如果选了默认的第一项或者第三项,scope 就受限了,可能出现"在 Git Bash 里能用,在编辑器终端里报 command not found"的情况。
第二个是 "Choosing the default editor",这里会默认选 Vim。对于没用过 Vim 的新手来说,某次执行 git commit 不带 -m 参数时,会直接掉进 Vim 的黑洞界面——键盘敲什么都没反应,按了回车又退不出去,最后只能强制关终端,还可能导致提交信息写了一半。你可以在这一步把编辑器切换成其他编辑器(比如 VS Code 或 Notepad++),也可以安装时保持默认,之后手动改全局配置。
第三个是 "Adjusting the name of the initial branch in new repositories",现在新版 Git 会问你默认分支名用 master 还是 main。这个不影响学习,新项目建议选 main,更符合当下主流托管平台的默认习惯。
对于 macOS 用户,最省心的方式其实是安装 Xcode Command Line Tools,系统会自带 git;Linux 用户则通过包管理器安装,比如 Ubuntu 的 sudo apt install git。核实安装是否成功,统一用一条命令:
bash复制git --version
能回显出版本号,说明装好了。
1.2 为什么不建议只依赖图形界面工具
现在很多 IDE 内置了 git 面板,Sourcetree、Fork 这类图形客户端也很好用,不少新手觉得"我点按钮就行,不用学命令行"。
我的看法是:图形工具可以用,但你不应该把它当成唯一的操作方式。原因是图形工具封装了太多细节,它展示给你的永远是"结果",而不是"过程"。你点了一个 commit 按钮,但你不知道这背后发生了什么——工作区、暂存区、本地仓库到底哪里发生了变动,一旦操作不符合预期,你会完全找不到排查入口。而命令行的价值恰恰在于过程透明:每敲一条命令,你能清楚看到 git 在执行什么、改变了什么状态。
另一个原因是几乎所有报错信息首先出现在命令行里。哪天你遇到冲突、遇到推送被拒绝,图形工具往往只给一句很笼统的提示,而命令行会给出一整段完整的提示信息,它还告诉你怎么处理。会看命令行输出,本质上就拥有了独立的排错能力。
所以我的建议很直接:日常简单操作用命令行过一遍,理解了每个动作的含义,再去用图形工具效率会很高,也不会被封装的黑盒子坑到。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 装完先别急着提交:三件必须马上做的事
安装完成后的第一次配置,决定了你后面所有提交记录的"署名"和跨平台协作时是否会出现莫名其妙的文件变更。这一步建议认真做完,别跳过。
2.1 设置用户名和邮箱,这关系到提交记录署名
git 的每一次提交都会记录作者信息,这个信息来自本机的全局配置,而不是托管平台的账号。所以你需要显式告诉 git"我是谁":
bash复制git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
这里有个很容易误导新手的细节:用户名和邮箱不一定需要和 GitHub/GitLab 账号一致。它只是提交记录上的一段作者标识。不过从实际协作角度,最好保持一致,这样你在远程仓库上的提交能正确关联到你的账号头像,显示为真实的提交人。
查看当前配置可以用:
bash复制git config --global --list
如果哪天换了机器或者想针对某个特定项目使用不同的身份,可以进入该项目目录后去掉 --global 重新设置,项目级配置会覆盖全局配置。
2.2 行尾符配置,跨平台协作的第一道坎
新手第一次和不同系统的同事协作时,经常会遇到一种诡异的情况:明明自己什么都没改,git status 却显示一堆文件被修改。打开一看,内容原封不动。
罪魁祸首通常是行尾符(Line Ending)。Windows 默认用 CRLF(回车+换行)表示一行结束,macOS/Linux 用 LF(仅换行)。当核心算法在做文件对比时,把整行的行尾差异判定为了"整行修改"。
针对这个问题,git 提供了 core.autocrlf 配置,推荐按系统来设:
- Windows 上,执行
git config --global core.autocrlf true,git 会在提交时把 CRLF 转成 LF 存入仓库,签出时再转回 CRLF。 - macOS/Linux 上,执行
git config --global core.autocrlf input,提交时转成 LF,签出时不转换。
这样无论项目成员用什么系统,仓库内保存的始终是统一的行尾符,就能避免这种"幽灵改动"。
2.3 配置 SSH 免密,省掉每次推送都要输账号密码的烦恼
如果你打算和 GitHub/GitLab/Gitee 这类托管平台配合使用,强烈建议在开始阶段就把 SSH 密钥配好。配好之后,push/pull 走 SSH 协议就不再需要反复输入账号密码。这一节把流程完整走一遍。
先检查本机是否已有密钥:
bash复制ls -al ~/.ssh
如果看到 id_rsa 和 id_rsa.pub 这类文件(新版默认可能是 id_ed25519),说明之前生成过。没有的话执行:
bash复制ssh-keygen -t ed25519 -C "你的邮箱"
一路回车即可。然后查看公钥内容:
bash复制cat ~/.ssh/id_ed25519.pub
把输出的整段内容复制到托管平台的 SSH Keys 设置页里,保存后本地验证:
bash复制ssh -T git@github.com
如果看到类似 "Hi 用户名! You've successfully authenticated" 的提示,就说明通了。
当时我自己踩过一个坑:第一次配完 SSH 后,推送时依然提示要输密码。排查了半天发现是远程仓库地址用的还是 HTTPS 协议,SSH 密钥对它根本不生效。解决办法是把远程地址改成 SSH 格式:
bash复制git remote set-url origin git@github.com:用户名/仓库名.git
注意:如果你有多个托管平台账号,想在同一台机器上分别管理不同平台的密钥,那就不能只用默认文件名。需要生成密钥时指定不同文件名,并在
~/.ssh/config文件里给不同 Host 做映射。这个属于进阶用法,初期阶段只要一把密钥配一个主用平台即可。
做完这三件事,git 最基础的环境准备工作才算真正完成。别小看这一节,配置不规范导致的协作问题,比命令不熟悉更让人崩溃,而且往往难以排查。
3. 提交这件事,远比你想象的讲究:工作区、暂存区、本地仓库的思维模型
git 的命令说多不多,但新手最容易卡住的地方,其实是没搞懂文件的几种状态。状态不理解,后面的 add、commit、branch 全是死记命令,稍微换个场景就不知道怎么操作了。
3.1 三区模型:用"草稿-打包-存档"来理解
git 管理文件的方式,可以简化为三个区域:
- 工作区(Working Directory):就是你电脑上肉眼可见的目录,你在这里创建、编辑文件。
- 暂存区(Staging Area / Index):可以理解成一个"打包台"。你对文件做了修改后,这些改动并不会自动进入版本记录,而是需要先"放上打包台"。
- 本地仓库(Repository):文件被打包好后,再"存档入库",形成一个不可变的版本历史快照。
对应到命令上,就是这三条主线:
bash复制# 工作区 -> 暂存区
git add 文件名
# 暂存区 -> 本地仓库
git commit -m "提交说明"
# 查看当前状态
git status
打个比方:你写了一份文档,改了几版,最终想留个备份。工作区是你的桌面,暂存区是你决定"这版暂存下来"的动作,而 commit 相当于给这个版本拍了张照片,之后任何时候都能找回这个时刻的内容。
这个比喻能解释很多新手的困惑:为什么我改了文件之后直接 commit 没反应?因为 git commit 只提交暂存区里的内容,你还没 git add,git 根本不知道你要提交哪些改动。
3.2 add、commit、status、diff 的日常配合
git status 是使用频率最高的命令,没有之一。运行之后会分两块展示信息:Changes not staged for commit(已修改但未放入暂存区)和 Changes to be committed(已放入暂存区待提交)。看懂了这两块的差异,你就掌握了 git 当前的状态。
至于 git add,常见有三种用法:
bash复制git add 文件名 # 添加单个文件
git add . # 添加当前目录所有变动(含新增、修改、删除)
git add -p # 交互式逐块确认,适合只提交部分改动
第三种 -p 属于进阶技巧了——当你一个文件里改了多处,但只想把其中一部分改动提交到当前 commit 时,可以用它来精细控制,避免把还没完成的半成品代码混进提交记录。
提交时我一直很强调写清楚 commit message。一个规范的信息格式通常是:用一句简短的话说明"这个提交做了什么改变",而不是写"更新"或"修改"这种没营养的描述。你可以按自己的风格调整,但至少要做到:过一个月后再看这条提交记录,能一眼明白当时的意图。
查看历史提交用:
bash复制git log --oneline --graph --all
--oneline 让每次提交只显示一行摘要,--graph 用字符画出分支拓扑图,--all 显示所有分支的提交。这条命令能让你对整个项目的历史脉络一目了然。
3.3 一个实操上的坏习惯,我劝你改掉
很多新手会学会一个"快捷方式":
bash复制git commit -am "提交信息"
这条命令等于对所有已跟踪的文件执行 git add 再加 git commit。看起来少敲一步,但对新文件无效——你新建的文件还没被 git 跟踪,-a 不会自动加进去。更关键的是,它绕过了"先看暂存区里到底有什么"这个确认环节,容易把不想提交的文件带进去。
我自己现在的习惯是:每次提交前先 git status 看一眼清单,再 git diff 确认具体改动内容(如果想看已暂存部分的差异就加 --cached),最后才 commit。步骤多了一点,但能避免不少"把密钥文件提交到仓库""把临时调试代码提交上去"这类社死现场。
4. 回滚没那么可怕:reset、revert 与后悔药的正确吃法
新手对 git 最大的恐惧,其实来自"把东西改坏了怎么恢复"。好在 git 的核心优势之一就是版本可回溯。这一节把常见的后悔场景逐个拆开讲,并说明不同场景分别适合用哪颗后悔药。
4.1 后悔药分级:从"改乱了想还原"到"提交错了想反悔"
先按改动位置从轻到重梳理一下场景。
场景一:工作区文件改乱了,还没 add
bash复制git restore 文件名
这条命令会把工作区文件还原到最近一次提交的状态。注意它会丢弃你对这个文件的未暂存修改,如果没有备份,改动就真的没了。所以执行前最好确认一下是否真的不想要这些改动了。
场景二:已经 add 了,想撤出暂存区
bash复制git restore --staged 文件名
它只是把文件从暂存区挪回工作区,文件内容本身不受影响。这个操作非常常用,比如手滑把不想提交的文件 add 进去了,就可以这样撤出来。
场景三:已经 commit 了,想撤销这次提交
这时候要根据提交是否已经推送到远程分支来选择方案。
如果还没推送,可以用 git reset 来移动 HEAD 指针。它有几种模式,区别在于要不要保留工作区和暂存区的改动:
bash复制git reset --soft HEAD~1 # 撤销提交,但保留改动在暂存区
git reset --mixed HEAD~1 # 撤销提交,改动回到工作区(默认行为)
git reset --hard HEAD~1 # 彻底撤销提交和改动,危险操作
HEAD~1 表示上一次提交。如果提交写错了信息、或者少加了文件,--soft 模式最合适,改完重新提交即可。--hard 是核弹级操作,它会丢弃指定提交之后的所有改动,使用时务必三思。
如果提交已经推送到了远程分支,并且是多人协作的分支,就不建议再用 reset 了——因为你本地把历史改了,远程的历史还在,下一次 push 会因为历史分叉而被拒绝,强行推送可能把队友的提交弄丢。这种场景的正确姿势是用 git revert:
bash复制git revert HEAD
revert 不是删除历史,而是创建一个反向提交来抵消掉目标提交的改动。它不会改写历史,对协作者最友好,是所有已推送改动回滚的首选方案。
4.2 用 reflog 找回"被删掉"的提交
有一个很反直觉但让很多人获救的知识点:git 里很多看似"彻底删除"的操作,其实并没有真正把对象从仓库里抹掉。即使你执行了 git reset --hard 回到了旧版本,被跳过的提交在一段时间内仍然可以通过 git reflog 找到。
bash复制git reflog
这条命令会显示 HEAD 指针所有的历史移动记录,包括你每次 reset、checkout、commit 的操作日志。哪怕你误删了一个分支,只要知道那个分支最近指向的提交哈希值,就能通过 git branch 分支名 哈希值 把它恢复出来。
我自己实际遇到过这种情况:在功能分支上写了两天的代码,某次想回退一个小改动,结果误用了 reset --hard,一口气丢掉了好几个提交,当时冷汗都下来了。后来冷静下来用 git reflog 找到了被丢弃提交的哈希,把分支救了回来。所以有一点可以放心:git 的多数操作是"可抢救"的,前提是别急着关终端、别急着乱敲新命令,先去 reflog 里找找看。
提示:
git reflog是本地命令,仅对本地仓库有效。如果提交已经推送到远程、又从远程被强制删除,那恢复的难度就直接上了一个数量级了。所以对已推送内容做重大操作前,备份和确认永远值得多做一次。
5. 分支和合并:平行世界是怎样握手言和的
分支是 git 最强大的能力之一,也是新手从"单机操作"迈向"团队协作"的关键门槛。很多人学到这里开始迷糊,是因为把分支想象得太抽象。其实把分支理解成"平行世界"就很直观:每个分支上进行的提交互不干扰,最终可以通过合并把不同世界的工作成果汇聚到一起。
5.1 日常开发分支操作流
以实际工作举例:项目在 main 分支上稳定运行,你现在要加一个新功能,不想直接污染主分支,就可以开一条功能分支:
bash复制git branch feature-login # 创建分支
git checkout feature-login # 切换到该分支
# 以上两步可以直接合并为:
git switch -c feature-login
现在你在 feature-login 分支上正常修改、提交,main 分支完全不受影响。等这个功能开发完、测试通过,切回主分支并把功能分支合并进来:
bash复制git switch main
git merge feature-login
合完确认没问题后,功能分支就可以删除了:
bash复制git branch -d feature-login
这套"开分支-开发-合并-删除"的循环,是 git 协作中最标准的日常动作,也是保护主分支不被碎片化提交干扰的关键手段。
5.2 合并背后发生了什么:三方合并与 merge commit
很多人以为 merge 就是把两边的代码叠在一起,其实没那么简单。git 合并采用的是三方合并机制:它会对比"当前分支"、"被合并分支"和"两个分支最近共同祖先"这三份内容。只有被合并双方都修改了同一处地方但改成不同结果时,才需要人类介入解决冲突。
所以大多数合并其实可以自动完成。比如你在一个分支上改了文件 A,另一个人在另一个分支上改了文件 B,合并时 git 能自己处理,不会冲突。
但有一种情况一定会冲突:两个分支改了同一文件的同一行,且改动不同。这种冲突无法靠算法裁决,只能由人来判断保留哪个版本。
5.3 亲手解决一次冲突,你就不再怕它
比如 main 分支和 feature-login 分支都修改了 README.md 的第一行:
bash复制git switch main
git merge feature-login
如果冲突发生,终端会提示 CONFLICT (content): Merge conflict in README.md。这时打开文件,你会看到类似这样的内容:
code复制<<<<<<< HEAD
# 项目主分支版本
=======
# 功能分支版本
>>>>>>> feature-login
<<<<<<< HEAD 和 ======= 之间是当前分支的内容,======= 和 >>>>>>> feature-login 之间是被合并分支的内容。你需要做的就是手工编辑这个文件,决定最终保留哪些内容:可以只留其中一方,也可以两边内容都整合进去。编辑完成后删除那些特殊标记行,然后:
bash复制git add README.md
git commit
合并就完成了。注意这次 commit 不需要再写 -m,因为 git 已经替你准备好了默认的合并提交信息。
第一次解冲突容易手忙脚乱,我的建议是:看到标记行不要慌,先把冲突文件完整读一遍,理解两个版本各自想表达什么,再决定保留谁。最忌讳的是全选或全删,那等于放弃了争议内容的决策权。
5.4 merge 和 rebase 怎么选
git rebase 是另一个很常见的分支整合方式。两者核心差别在于提交历史的整理方式:
- merge 保留各分支的真实分叉记录,会生成合并节点,历史看起来是"网状"的但完整真实。
- rebase 会把当前分支的提交"变基"到目标分支的最新提交之后,让历史变成一条直线,更清晰,但会改写提交哈希。
对于新手,我的建议是:在共享的分支上永远不要做 rebase,只使用 merge,因为它会改写历史,容易导致协作者的本地分支和远程分支对不上。如果只是在自己还没推送的本地分支上想整理提交,让历史更干净,rebase 可以作为一个优化工具。
6. 远程协作的日常节奏:clone、push、pull 与一次真实提交流程
本地玩得再六,最终要落到和远程仓库打交道。远程协作环节的很多问题,本质上不是命令记不住,而是对"本地和远程是两个独立的仓库"这个事实缺乏体感。把这一点刻在脑子里,协作中的大部分报错都能看懂是怎么回事。
6.1 clone 之后先看 remote,别盲操作
从远程仓库拿项目到本地,用的命令是:
bash复制git clone git@github.com:用户名/仓库名.git
执行完后,git 会自动帮你把远程地址记录在名为 origin 的远程仓库引用上。你可以随时查看:
bash复制git remote -v
看到输出里的 fetch 和 push 两行,说明本地仓库已经和远程建立了联系。有个新手经常犯的错:自己从零开始写代码,中途想推到远程一个新仓库,却从头到尾忘了执行 git remote add origin 地址,结果 git push 一直报错。这里的逻辑是:clone 会帮你自动关联远程仓库,但本地 git init 创建的项目,不会自动知道远程仓库的地址,必须手动添加。
6.2 推代码之前,先养成 pull 的习惯
当你和他人协作同一个分支时,本地和你 clone 时的远程状态可能已经完全不一样了——别人已经推送了新提交。如果你不在自己 push 之前把远程的新提交拉到本地,推送时大概率会被拒绝,提示类似:
text复制! [rejected] main -> main (fetch first)
根本原因是:git 默认不允许把本地落后的历史直接覆盖到远程。正确的做法是先拉取远程的更新,在本地完成整合,再推送:
bash复制git pull
这里有个细节想多讲一点:git pull 其实是 git fetch(把远程的最新提交下载到本地)和 git merge(把远程提交合并进当前分支)的合体命令。理解这一点对排查问题极其关键——有时候 pull 失败,不是网络问题,而是本地存在未提交的改动,和远程拉下来的新提交产生了冲突。
建议在项目里设置默认 pull 行为为 rebase 的方式吗?这是一个很容易引发争论的话题。我的实际感受是:对新手来说,早期阶段就用默认的 merge 行为即可,冲突少、更直观;等熟练之后,如果你希望自己的提交永远整整齐齐地排列在远程提交之后,再把 pull 行为切换成 rebase,也会舒服很多。但坦白说,只要提交频率不高、协作人数不多,merge 风格完全够用,不必强求。
6.3 一次完整的"功能开发-远程提交"流程,串起全文知识
前面讲了很多零散的命令,这里把它们串成一个完整的小型工作流,你可以照着走一遍:
- 同步远程状态:
bash复制git switch main
git pull
- 创建功能分支(避免直接在 main 上开发):
bash复制git switch -c feature/user-profile
- 在功能分支上正常开发,做了若干次本地提交:
bash复制git add .
git commit -m "feat: 新增用户资料编辑入口"
git add .
git commit -m "fix: 修复资料页头像加载失败问题"
- 功能完成,切回主分支并合并:
bash复制git switch main
git merge feature/user-profile
- 推送主分支到远程:
bash复制git push
- 删除已经合并完成的本地分支和远程分支(远程分支删除可选用 Web 平台操作):
bash复制git branch -d feature/user-profile
在这个流程里,你实际用到了 status、add、commit、branch、switch、merge、pull、push 这堆最高频命令,而且是一个相当贴近真实工作的节奏。
6.4 临时要切分支,手头改动还没写完?用 stash
实际开发中经常有一种尴尬场景:你在功能分支上写了一半代码,突然被告知 main 分支有个紧急问题要马上修复。这时候直接切分支,git 会提示当前有未提交的改动,可能带不过去或者阻止切换。
处理办法是先把当前现场临时保存起来:
bash复制git stash
stash 会把工作区和暂存区的改动暂时收起来,让工作目录回到干净状态。然后你可以放心切到其他分支去修复急事。等处理完回到功能分支,再把现场取回来:
bash复制git stash pop
这个命令非常实用,可以说是分支切换场景下的"暂停键",能帮你省掉很多"先随便提交一版再说"的尴尬——那种临时提交会污染历史,后续还得 reset,不如从一开始就养成用 stash 暂存现场的习惯。
值得一提的是,git stash 也可以带 -u 参数,把未跟踪的新文件一并暂存起来,适合你新建了文件但还没 add 过的场景。
7. 日常使用中最容易翻车的三个细节,替你提前踩过
讲到这里,git 的主干知识已经覆盖得差不多。剩下的部分,我挑三个自己真实翻过车、也看同事频繁踩的细节,展开聊一聊。这三个问题都不算难,但一旦出现就很耗时间。
7.1 误把敏感文件提交进仓库,怎么办
很多人第一次栽跟头,就是把 .env 文件(里面可能含有数据库密码、私钥、Token)提交进了仓库,甚至已经推送到了远程。
如果还想保留文件在本地使用,但希望 git 不再跟踪它,需要做两件事:
bash复制# 把文件从 git 跟踪中移除,但保留在本地磁盘
git rm --cached .env
# 添加到 .gitignore,避免以后再次误加
echo ".env" >> .gitignore
git add .gitignore
git commit -m "chore: 停止跟踪 .env 文件"
但必须说明:这只能阻止它继续被跟踪。如果文件已经推送到远程,它已经存在于历史提交里,任何能访问仓库的人依然能从历史中翻出来。要对已推送的历史做彻底清理,需要借助 git filter-repo 这类工具重写历史,而且如果涉及泄露,最稳妥的做法是立即去对应平台吊销已泄露的密钥、重新生成,而不是只删文件。
这个教训我印象太深了,后来我用一个约定杜绝此类问题:项目初始化第一件事就是写 .gitignore,把 .env、密钥文件、IDE 配置目录、依赖目录全部提前列进去。这个习惯成本极低,收益极高。
7.2 commit message 写得像废话,过一个月自己都看不懂
我看到不少人的提交记录是这样的:"update"、"修改"、"aaa"、"111"。这种提交信息在当下只有自己知道什么意思,过一个月再看,完全不知道那一次提交到底改了什么,更别说同事要基于历史记录做排查了。
我自己现在偏向用约定式提交的格式:
text复制feat: 新增登录页面
fix: 修复支付金额精度丢失问题
docs: 更新 README 部署说明
refactor: 重构用户模块的校验逻辑
test: 补充订单模块单元测试
前缀表达"改动类型",冒号后简要说明"改了什么"。这不需要额外安装任何工具,只是一种书写习惯,但对历史可读性的提升是质变级的。
也许有人觉得这是形式主义,但做协作项目时,提交信息实际上是给"未来的自己"和"其他协作者"看的文档。多花十秒钟写清楚,能替未来省下按小时计的对账时间。
7.3 不要直接在主分支上开发,哪怕是你自己的个人项目
这一点技术门槛不高,但属于纪律问题。
即使是你一个人维护的小项目,我也建议至少维持一条干净的 main 分支,所有开发在功能分支上进行,验证通过后合并回主分支。这么做不是故作正经,而是为了保住主分支"随时可发布、始终可运行"的属性。一旦你养成了在 main 上随手提交的习惯,哪天项目规模变大、需要多人协作时,你会发现已经堆积了一堆半成品改动在主分支上,既不好发布,也不好回溯。
开头图省事,后面必然加倍偿还。git 的分支成本极低,创建一个分支只是增加一个指针,几乎没有开销,所以不要吝啬使用分支。
8. 写在最后的几句实在话
如果你完整读到这里,应该有信心开始用 git 做实际项目了。这篇内容没有追求面面俱到,刻意略过了 submodule、cherry-pick、bisect 这类进阶话题,因为在我看来,先把主干工作流跑顺、建立对三区模型和历史机制的体感,远比囤积一箩筐冷门命令更重要。git 的知识结构是树状的,主干扎稳了,枝叶随时可以按需生长。
最后分享两个我在实践里很受益的小习惯。
第一,高频使用 git status 和 git log,让"当前在哪、历史是什么样"时刻保持可见。遇到任何不确定的状态,先别急着执行修改类命令,先看这两条的输出,弄清楚当前所处的位置再动手。
第二,对拿不准的命令,先在临时分支或测试仓库里验证,而不是在生产仓库上试错。git 虽然多数操作可恢复,但恢复过程本身往往需要不少时间。
如果你把 git 当成一门需要系统啃的学科,可能会觉得它门槛略高;但如果你把它当成一位随时帮你存档、随时可以读档的游戏伙伴,你会发现,它其实是你最靠谱的安全网。
