但凡用 Git 超过一年的开发者,基本都经历过这种场面:平时敲 git 常用命令感觉挺顺手,真到了合并冲突、被 push 拒绝、一不小心把 dev 分支代码覆盖了的时候,大脑才一片空白。Git 的奇怪之处就在于,你死记硬背下来的命令越多,越容易忽略它真正的工作方式;可你要是真的理解了它的几个核心模型,绝大多数命令根本不用背,现场就能推出来。
这篇东西我打算按“为什么要这样设计 → 命令怎么落在实际场景里 → 哪些坑我替你先踩过了”的逻辑来写,覆盖从安装配置、日常提交、分支管理、远程协作到后悔药操作的一整条链路。无论你是刚把 Git 装好还没搞懂工作区是什么的新手,还是已经用了一两年但全靠查命令应付的进阶用户,都有对应的内容可看。文里所有命令我都按真实使用习惯加了说明,不是照着官方文档誊一遍,而是告诉你这些参数在什么场景下才会用到。
1. 先用一个新手的视角问清楚:Git 到底帮你解决了什么麻烦
很多人第一次接触 Git,是从“代码总要留个版本备份”这个朴素需求开始的。最早的粗暴做法是复制目录存成压缩包,名字从 project_v1.zip 一路编号到 project_final_最终版2.zip。这种做法应付单人作业勉强能撑一阵,一旦两个人同时改同一个文件,或者一个月后想看看某个功能是哪次改动引入的,就完全崩盘了。
Git 解决的正是这堆问题:它给整个项目拍快照,所有历史版本都能翻出来;它让多人并行开发而不互相踩踏;它还能记录每次改动是谁、在什么时候、基于哪个版本做的。这些能力在生产环境里直接对应两个非常现实的需求:出问题能回滚,出功劳能追溯。
这里必须先破除一个常见误解:Git 不是网盘。网盘同步的是“最新状态”,Git 维护的是“一串有先后顺序、彼此有关联的快照”。你在本地每一次 commit,都是往这串快照链条上加了一个永久节点。这个区别解释了后文几乎所有命令的设计逻辑,比如为什么 push 之前要先 pull,为什么改完历史(rebase)会影响团队协作。
还有一个值得新人提前建立的概念:Git 是分布式的。每个人本地都有一份完整仓库,不只是代码文件,还包括全部历史记录。所以就算远程服务器挂了,只要任何一个人的本地仓库还在,整个项目的来龙去脉都能恢复。这也是 Git 相比老一代集中式版本控制系统(比如 SVN)最本质的优势。
说句大白话收个尾:命令行才是理解 Git 的最佳入口。图形化工具(小乌龟、VS Code 插件、IDE 内置面板)在大部分操作上确实更友好,但它们把底层逻辑隐藏得太干净了,很多人在界面里点来点去,出了问题只能干瞪眼。把命令行这套逻辑摸清楚了,再用图形工具就是降维打击。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 装好 Git 只是开始:安装、环境变量和身份配置一次弄明白
2.1 三个平台的安装方式
Windows 用户建议直接去 Git 官网下安装包,一路 Next 装完。安装过程中有两个选项值得留意:
- 调整 PATH 环境变量的选项,选默认的 “Git from the command line and also from 3rd-party software” 就够用。
- 换行符转换选项,默认的 “Checkout Windows-style, commit Unix-style line endings” 是多数项目推荐做法,但如果你参与的是纯 Windows 团队且项目里全是 CRLF,就换成不转换。
macOS 上最简单的方式是安装 Xcode Command Line Tools,它自带 Git。执行 xcode-select --install 弹窗装完即可。也可以 brew install git 装最新版,因为系统自带版本往往偏旧。
Linux(Debian/Ubuntu 系)就是一行:
bash复制sudo apt update && sudo apt install git -y
CentOS/RHEL 系把包管理器换成 yum install git -y 即可。
装完统一用 git --version 验证。能看到版本号,说明命令已经可用了。
2.2 最常碰到的第一个报错:git 无法被识别
Windows 上经常遇到这种提示:
code复制git : 无法将“git”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。
如果你明明装好了 Git,却在 cmd 或 PowerShell 里敲 git 提示找不到,原因几乎可以锁定为 PATH 环境变量没有把 Git 的安装目录加进去。Git 的安装目录里能找到 cmd 子目录(类似 C:\Program Files\Git\cmd),把它加进系统 Path 变量后重开终端就好。
第三步是身份配置。Git 每次提交都会把 “作者信息” 写进历史,这个信息如果没配,提交时会报 Please tell me who you are。配置方式是:
bash复制git config --global user.name "你的名字"
git config --global user.email "你的邮箱"
--global 表示对当前用户所有仓库生效。个别项目如果需要不同的身份,可以在仓库目录里去 --global 重新配置,项目级配置会覆盖全局配置。
2.3 顺手把这两个配置也改掉
第一,把默认分支名从 master 改成 main。这不是强制要求,但现在国内外主流托管平台默认分支都叫 main,本地早改早一致:
bash复制git config --global init.defaultBranch main
第二,检查一下个人换行符策略。Windows 和 Linux/macOS 的换行符一个是 CRLF 一个是 LF,稍不留神就会出现 warning: LF will be replaced by CRLF 之类的提示,虽然大多时候无害,但会污染输出。Windows 用户推荐保持默认,纯 Unix 开发环境可以这样确认:
bash复制git config --global core.autocrlf input
这里有个容易忽略的点:core.autocrlf 改的是 “checkout 和 commit 时是否做换行符自动转换”,不是文件内容的展示。理解这一点后,你看到网络上关于 git config core.autocrlf false 的各种争论,就能自己判断哪个方案适合你的团队了。
3. 每天重复最多的核心流:add、commit、status、diff、log 该怎么配合
3.1 先建立三个区的心智模型:工作区、暂存区、版本库
Git 的文件状态模型,用做饭来类比最直观:
- 工作区就是你电脑上的项目文件夹。你在这张“菜板”上切菜、改菜谱。
- 暂存区(Staging Area / Index)是菜板旁边的备菜盘。你把哪些食材准备好、准备端上桌,就
git add到那个盘子里。 - 版本库是冰箱。你把配好的菜放进去冻起来(
git commit),以后随时能解冻回来看。
很多新手最大的困惑来自 “为什么 add 之后还要 commit”。答案是:暂存区允许你分批次组织提交。你可以一次性改 10 个文件,但只把其中 3 个跟 “修复登录 bug” 相关的文件放入暂存区,提交一次;剩下 7 个关于 “调整样式” 的改动,留到下一次提交。这样历史记录保持着 “一次提交只做一件事” 的干净状态,用 git log 复盘时省力太多。
3.2 status 输出怎么看
git status 是提醒你对仓库改动了多少的命令,它的输出本身就是一份很好的状态说明:
bash复制# 工作区有新文件或改动的文件(未 add)
Changes not staged for commit:
modified: src/app.js
# 已经 add 但还没 commit
Changes to be committed:
new file: README.md
红色区域是 “工作区有变动但没进暂存区”,绿色区域是 “已经在暂存区待命”。建议有事没事就敲一下 git status,它不会改变任何东西,但能帮你始终保持清醒:现在项目处于什么阶段、下一步该干什么。
3.3 add 的几个实用变体
git add . 是绝大多数人的默认操作,它的含义是 “把当前目录下的所有改动加入暂存区”。但有几个场景必须用其他用法:
- 只添加特定文件:
git add src/utils/calendar.js - 添加所有已跟踪的改动文件,但不添加新文件:
git add -u - 交互式挑选改动块(把同一个文件的不同片段拆分到不同提交):
git add -p
git add -p 是个被低估的利器。比如你调试时顺手加了几个 console.log,又顺手修了个真正的 bug,两个改动混在同一个文件里,想拆两次提交时,-p 会让你逐个 hunk 决定是否暂存,非常顺手。
3.4 commit 的写法建议
最简单的提交命令:
bash复制git commit -m "修复登录接口空指针异常"
-m 后面跟的是提交信息。很多人图省事写 fixed bug、update 这种信息,等三个月后回看历史时,git log 里一排 “update” 完全无法还原当时的意图。我个人的习惯是:提交信息按 “动词 + 时态 + 一句话背景” 的格式来写,比如 fix: 空数组边界未处理导致首页白屏。团队如果已经有提交信息规范(比如 Conventional Commits),就按规矩来。
补充一个实用细节:git commit -am "信息" 能跳过 add 直接提交所有已跟踪文件的改动。它只对 “已跟踪文件” 生效,新文件必须手动 add。所以你如果创建一个新文件,又直接 git commit -am,会发现提交记录里根本没有这个文件,这不是命令坏了,而是新文件还没被 Git 认识。
3.5 diff 和 log:提交前看清变化,提交后看清脉络
提交之前检查下自己到底改了啥,是一个能帮你避免很多社会性死亡的职业素养:
bash复制# 暂存区与版本库的差异(已 add 未 commit)
git diff --cached
# 工作区与暂存区的差异(改完未 add)
git diff
# 只看哪些文件被改,不展示具体内容
git diff --stat
git log 则负责看历史。几个常用形态:
bash复制# 简洁版历史,一行一条
git log --oneline
# 带分支图和合并情况
git log --graph --oneline --all
# 按作者过滤
git log --author="名字"
# 查看某次历史提交的完整改动内容
git show <commit-id>
我这里特别推荐 git log --oneline --graph --all,它能把所有分支的走向画成一个字符拓扑图,比在 GUI 里点来点去直观得多。还用 --stat 看一眼提交涉及的文件范围,能快速判断一次提交的颗粒度是否合理。
4. 分支不是魔法:branch、checkout、merge 背后的指针原理
4.1 分支的本质:一个会移动的指针
初学阶段最容易被误导的概念就是分支。很多教程会画出分叉图,把分支想成一条代码的平行线,但严格来说不对。Git 里的分支只是一个指向某个提交对象的 “可移动指针”。
所有提交串起来像条链子,main 这个分支名本身只是一个指针,指向链子顶端那个 commit。执行 git branch feature/login 时,你只是复制了一个新指针叫 feature/login,它初始化时也指向当前 commit。随着你在新分支上继续提交,这个指针才逐步往前移动。
理解这个机制,很多操作就有了解释:
- 创建新分支的成本几乎为零,所以你尽管大胆开分支。
git branch -d删除分支时删的是指针,不是提交记录。要用git branch -D强删时,才需要担心那些 “孤儿提交” 是否还有保留价值。- 切换分支时,工作区文件会跟着变,因为 Git 要让工作区内容与指针所指向的提交保持一致。
4.2 分支的日常操作组合
假设你在 main 分支上要到 dev 分支开发新功能:
bash复制# 基于当前分支创建并切换到新分支
git checkout -b dev
# 等价于
git branch dev
git checkout dev
新版 Git 提供了 git switch 和 git restore 来分离 “切换分支” 和 “恢复文件” 两个职责,我建议新人直接学新命令,语义更清晰:
bash复制git switch -c dev # 创建并切换
git switch main # 切换已有分支
git branch -a # 查看所有本地+远程分支
合并分支用的 git merge 也很直观:把另一个分支的历史并入当前分支。
bash复制git switch main
git merge dev
如果 dev 是基于当前的 main 最新提交直接延展的,Git 会执行 “快进式合并”(fast-forward),不会生成额外的合并提交。如果 main 在 dev 分出去之后又有过新提交,就会产生三方合并,此时可能冒出冲突。这两种合并场景在 git log --graph 里的形态完全不同,前者是一条直线,后者会有一个分叉再聚合的节点。
4.3 冲突处理的完整过程
冲突是 Git 使用中无法回避的真实痛点,场景通常是:你和同事同时改了同一个文件的同一块区域。合并时 Git 会告诉你 CONFLICT (content): Merge conflict in package.json,并在冲突文件里插入标记:
code复制<<<<<<< HEAD
当前分支的版本
=======
被合并分支的版本
>>>>>>> dev
处理步骤没有捷径,必须逐个人工决定保留哪边:
- 打开冲突文件,看看
<<<<<<<到>>>>>>>中间的内容,确认两边改动的意图。 - 手动编辑成你想要的结果,把三组标记行全部删掉。
- 编辑好后执行
git add <文件>,把解决结果放入暂存区。 - 全部冲突处理完后执行
git commit,完成这次合并提交。
我踩过的最深刻的一个坑是:看到只有一部分文件冲突,就直接改完那几个文件然后执行 git commit 一口气提交。这样会把未完成的冲突标记也提交进去。正确做法是先 git status 确认没有处于 “Unmerged paths” 状态的文件,再提交。
如果你合并合并着发现完全乱了,别硬抗,直接中止:
bash复制git merge --abort
该命令会把仓库恢复到 merge 之前的状态。
5. 连接远程仓库:clone、push、pull 协作流程的正确打开方式
5.1 本地、远程和 origin 的关系
远程仓库(remote)可以理解为项目的一台公共服务器,它也是一个完整 Git 仓库,你们两个仓库通过网线交换各自的提交。origin 只是默认给这台远程仓库起的名字,你可以按喜好改,但大部分场景沿用习惯就好。
建立一个项目的远程链路,常见两条路:
场景 A:先在本地建好仓库,再推到远程空仓库。
bash复制git init
git add .
git commit -m "initial commit"
git remote add origin git@example.com:user/project.git
git push -u origin main
场景 B:从远程拉一个已有项目。
bash复制git clone git@example.com:user/project.git
cd project
clone 用起来省事,它同时完成了三件事:下载仓库文件、下载完整历史、自动配置远程别名 origin。
5.2 SSH 免密配置
如果你用的是 HTTPS 地址,推代码时需要反复输入用户名密码或 token,麻烦且容易被安全策略卡住。生产环境更推荐用 SSH key。
bash复制# 生成密钥(一路回车即可)
ssh-keygen -t ed25519 -C "你的邮箱"
# 查看公钥内容
cat ~/.ssh/id_ed25519.pub
把公钥内容添加到你的代码托管平台(GitHub / GitLab / Gitee)的 SSH Keys 设置里。本地验证一下:
bash复制ssh -T git@github.com
看到一条 “successfully authenticated” 的回显,说明链路打通。之后把仓库地址换成 SSH 格式(git@github.com:user/project.git),就能免密推送了。
实际上这个步骤值得你专门花十分钟配置好,因为它一劳永逸,尤其当你在服务器上操作时,没有图形界面、没有凭据管理器,SSH 是最稳的方案。
5.3 push 的正确流程与 -u 参数
第一次把一个本地分支推到远程时,需要加 -u 建立关联:
bash复制git push -u origin dev
-u 全称 --set-upstream,作用是让本地分支记住跟踪对象。之后同一分支就可以直接 git push 和 git pull,不需要再敲远程名和分支名。
日常改动推远程的循环是:
bash复制git add .
git commit -m "描述"
git pull --rebase # 先把远程新提交拉下来并把自己的提交垫在它上面
git push
很多团队会在 push 前强制走一次 pull,就是为了避免出现 “远程在我本地提交之后又有了新提交,导致我的 push 被拒绝” 的冲突状态。如果你被拒绝推送了,先别乱硬推,下一步看下面。
5.4 push 被拒后怎么办:pull --rebase 的价值
推送被拒绝时的报错通常长这样:
code复制! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to ...
hint: Updates were rejected because the tip of your current branch is behind
这表示远程分支上有你本地没有的新提交。此时如果你盲目 git pull 后再 push,就会产生一个多余的 merge 提交,历史混乱,看着也别扭。推荐做法:
bash复制git pull --rebase origin main
--rebase 的意思是:把我本地的提交取下来,先临时存放,然后以远程最新状态为基底,把我的改动重新播放上去。好处是历史保持线性;代价是如果你本地已经做完了不少提交,rebase 时有可能出现多次冲突处理。
如果你不确定 rebase 和 merge 的取舍,我给一条实用建议:对于你还没推送出去的个人开发分支,放心用 rebase;对于已经推送到远程的共有分支,永远不要用无谓的 rebase 去改写历史,否则会让同期协作的同事一头雾水。
5.5 拉远程更新的其他姿势
git pull 等价于 git fetch + git merge。fetch 只做一件事:把远程的最新提交下载到本地某个远程跟踪分支(比如 origin/main),但不动你的工作区。如果你只想看看远程有什么新内容、避免自动合并带来的意外,可以先 fetch 再观察:
bash复制git fetch origin
git log --oneline main..origin/main
这样你能看到 “本地 main 没有但远程 main 有” 的所有提交,确认无误后再决定 merge 或 rebase。这个操作组合在手头修剪项目文件时尤其好用,因为它完全不会打扰你的工作区状态。
6. 后悔药专区:reset、revert、stash、clean 的正确打开姿势
写代码这件事没法保证不犯错,Git 的价值也体现在它预留了多层后悔药。但要命的是,很多人的 “悔药” 一吃就歪,等你意识到问题的时候,可能灾难已经扩大了。
6.1 场景一:工作区文件改乱了,想放弃改动
如果你只是改了文件但还没有 add,用:
bash复制git restore <文件>
这会把你工作区的文件恢复成最后一次提交的状态。被恢复的文件,其修改将完全消失,操作不可逆,所以确定自己没搞错再执行。
新版命令对应的老写法是 git checkout -- <文件>,两种都行,但 git restore 的命令名更加直白,推荐学新式。
另外有个更常用的安全版本:只想把文件恢复到暂存区或某个历史版本,可以加 --source 参数,例如:
bash复制git restore --source=HEAD~2 src/config.js
6.2 场景二:add 错了文件,想撤出暂存区
如果你把不该提交的文件执行了 git add,但还没有 commit,撤掉暂存:
bash复制git restore --staged <文件>
输出会提示你这个文件回到 “Changes not staged for commit” 状态,改动本身还在工作区,不会丢内容。
6.3 场景三:提交了坏东西,想删掉最近几次提交
git reset 会移动分支指针,有三种模式,危险级别递增:
| 模式 | 对暂存区的影响 | 对工作区的影响 | 适用场景 |
|---|---|---|---|
--soft |
重置到目标提交,暂存区保持 | 工作区不变 | 想只要 “重新提交一次总结” 时 |
--mixed(默认) |
重置到目标提交,暂存区清空 | 工作区不变 | 把最近提交拆散回 “未暂存” 状态,重新组织提交 |
--hard |
重置到目标提交,清空暂存区 | 工作区恢复到目标提交 | 彻底抛弃最近改动,危险程度最高 |
举个例子,最近三次提交全是废的,想彻底重来但保留当前所有工作区改动:
bash复制git reset --soft HEAD~3
# 之后重新 add、commit
如果连工作区里那些改动也要一起扔掉:
bash复制git reset --hard HEAD~3
这里我必须强调:--hard 会让工作区文件立刻变成旧版,任何没提交的修改都会永久消失。用前先执行 git status 和 git stash list 确认没有未保存的改动,这是我在生产环境踩过雷之后总结出的血泪教训。
还有一个关键规则:已经 push 到远程的提交,不要用 reset 去删。因为历史被改写后,下个 push 必然被拒,还会让同事本地仓库失去共同基线。这种情况要用 6.4 的 revert。
6.4 场景四:改动已推远程,想回退但不破坏历史
git revert 不是移动指针,而是生成一个 “反向提交”,把之前某个提交的改动反向应用,从而抵消它:
bash复制git revert <commit-id>
它推荐的地方在于:历史保持线性往前追加,远程协作者 pull 之后依然能正常同步,不会有任何 “历史被改写” 的冲突。这也就让它成为线上分支回滚的首选方案。
6.5 场景五:干了一半想切分支,又不想丢进度
你正在 dev 分支调某段逻辑,突然线上出问题了得切到 main 修 bug,但工作区改到一半,切不走。这时候 stash 就该登场了:
bash复制git stash # 把当前未提交的改动保存起来,工作区变干净
git switch main # 安心切分支
# 修完 bug 切回来
git switch dev
git stash pop # 把之前保存的改动还回来
stash 本质是把你未提交的改动保存到一个 “临时仓库” 里。常用变体:
git stash list:查看所有保存git stash apply stash@{1}:恢复但不删除git stash drop stash@{2}:删除某个保存
6.6 终极后悔药:reflog
如果你真的脑子一热执行了 git reset --hard,还顺手把重要的提交搞丢了,先别慌。Git 在本地有一个 reflog 日志,记录了你所有 “HEAD 指针曾经指向过的地方”:
bash复制git reflog
输出里能看到你每一次 checkout、commit、reset、merge 的痕迹,以及对应的 commit-id。确认哪一个是你想要恢复的节点后:
bash复制git reset --hard <commit-id>
reflog 并非永久保存,默认 90 天,但它给大多数误操作留了一扇逃生的门。这也是分布式版本控制系统对比集中式系统的一个巨大优势:只要本地仓库还存在,历史基本不会真正消失。
7. 高频报错和疑难场景:这些错误信息我都替你踩过
Git 的报错信息对新手不够友好,但这恰恰是有经验的人能给出直接参考答案的地方。下面是我列的几张速查表,全是我实际工作中碰过的,不是从文档里抄的。
7.1 常见报错对照表
| 报错信息 | 原因 | 处理方案 |
|---|---|---|
fatal: not a git repository |
当前目录不是 Git 仓库 | 检查是否在项目根目录,或执行 git init 初始化 |
Please tell me who you are |
未配置 user.name / user.email | 执行 git config 配置身份 |
Updates were rejected (non-fast-forward) |
本地落后于远程 | git pull --rebase 再 git push |
Your branch is ahead of 'origin/main' by 2 commits |
本地有提交未推送 | 执行 git push |
warning: LF will be replaced by CRLF |
换行符配置与仓库不一致 | 配置 core.autocrlf 后重新提交换行符规范 |
fatal: refusing to merge unrelated histories |
两个没有共同祖先的仓库要合并 | 确认意图后加 --allow-unrelated-histories |
7.2 提交了不该提交的文件怎么办
比如你误把 node_modules/ 或 .env 文件提交进了历史:
bash复制# 把文件从 Git 跟踪中移除,但保留本地文件
git rm --cached node_modules -r
echo "node_modules/" >> .gitignore
git add .gitignore
git commit -m "chore: 停止跟踪 node_modules"
这里有个新手容易忽略的点:git rm --cached 只影响将来,历史里依然能看到这个文件,一旦远程仓库已经公开,等同于文件内容泄露。当前仓库无论如何补救,历史已经被污染了。这种情况要么换一个思路接受它(只把新版本之后做对),要么花代价咨询团队做历史改写,或直接重启远程仓库。
至于 .gitignore 的写法:它支持通配符、目录层级、取反规则。一个安全的初始模板最好包含系统垃圾文件(.DS_Store、Thumbs.db)、依赖目录(node_modules/、vendor/、target/)、本地配置(.env*)和日志文件。
7.3 误删分支或误删 stash 的恢复
如果你执行了 git branch -D feature/login 才发现里面还有没合并的提交,可以用 reflog 找到那个分支原来指向的提交:
bash复制git reflog | grep feature/login
git branch feature/login <commit-id>
类似地,git stash drop 后如果反悔了,同样能通过 reflog 找到 stash 对应的提交并恢复。我建议任何需要在 Git 中执行删除动作的操作,都先执行 git reflog 看一眼备份,再动手。
7.4 大文件问题:为什么仓库越用越膨胀
一旦某天你把一个几百 MB 的安装包、数据库备份或视频误提交进历史,就算后来 git rm 删掉了,仓库体积也不会变小,因为历史记录里还留着这个对象。这种情况有专门的解决方案:
- 推动团队在仓库根目录维护一个
.gitignore黑名单,从入口拦截大文件。 - 已经有历史包袱的,评估是否值得引入 Git LFS(Large File Storage)来托管大文件。
- 如果只是本地仓库膨胀且确定无历史价值,直接重建仓库或者执行 GC 指令前必须先搞清楚对象为什么存在。
这类问题最常见的发生时间点是在项目初期,团队还没建立起提交纪律的时候,所以规章制度比工具更能起预防作用。
8. 我个人的一份 Git 实操体会,写在这里供你参考
最后分享几条我从接手大量二手项目、带过新人之后总结出来的心得,不涉及任何高级理论,就是一些让工作顺手的习惯。
第一条,提交信息是最便宜的项目文档。每次 commit 前问问自己:三个月后的我,看到这行信息能不能知道当时为什么这么改?如果答案是模糊的,就把它写清楚。许多大型项目对提交信息有严格规范(比如 Conventional Commits),即使没有,保持一致、有意义的风格也非常重要。
第二条,不要害怕多开分支。分支的创建成本几乎为零,我见过太多人从头到尾只在一个 master/main 分支上开发,嫌麻烦,结果最后合并时一塌糊涂。哪怕是一个人开发的项目,我也推荐至少开一个 dev 分支,在 main 保留可发布的稳定版本。这个过程不仅是习惯问题,更是给未来的自己留了回旋余地。
第三条,多跟 git log --graph 做朋友。它能把项目历史以一种 “时间线拓扑图” 的形式展示出来,一眼看清哪里分叉了、哪里合并过、哪些提交是这条线的起点。很多新人只顾着敲命令,从不看历史结构,最后吃亏在没有培养出 “时间线思维”。
第四条,命令行的技能,永远值得花时间沉淀。图形工具会帮你做很多自动操作,但只有当你亲自用命令行跑通 rebase、reset、stash 这些操作后,才会真正理解那些 “自动” 背后做了什么。这套理解一旦建立,以后无论切到什么平台、什么 GUI,都不会慌。
