1. 为什么每个开发者都应该好好掌握Git常用操作
Git这东西,刚接触的人觉得它是个麻烦,命令又多又抽象,稍不注意就把仓库搞得一团糟。可真用顺了之后,你会发现它几乎是日常开发里最离不开的工具。不管是自己一个人维护项目,还是几个人、几十个人一起协作,Git都能把代码版本管理得明明白白。如果说写代码是盖房子,那Git就是工地上那套监理系统——谁改了什么、什么时候改的、改坏了能不能回退,全部有据可查。
这篇内容不是我临时拼凑的命令清单,而是我这些年实际开发中反复使用、踩过不少坑之后总结出来的Git常见操作。从安装配置开始,到日常提交、分支管理、远程协作,再到撤销回滚、问题排查,基本覆盖了日常使用频率最高的场景。不管你是刚入行的新手,还是已经写了一段时间代码但一直对Git一知半解,这篇内容都能帮你把Git这块拼图补齐,而且每一步都可以直接照着操作。
围绕Git的话题,网上教程铺天盖地,但多数要么太零碎、要么太晦涩。我写这篇的出发点很朴素:把最常用、最核心的操作讲透,把那些藏在命令背后的原理讲明白,再把文档里一般不会写的坑标出来。学完这篇,你至少能独立管理自己的项目,遇到常见的Git问题也知道从哪儿下手排查。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Git安装与环境配置的完整细节
2.1 主流系统下的安装方式与验证
Git的安装本身不难,但不同操作系统的安装方式还是有讲究的,尤其要注意版本选择和后续环境变量的问题。
Windows用户最常见的是直接去官网下载安装包。官网下载页会自动识别系统位数并推荐对应版本,下载下来是个exe文件,双击安装。安装过程中有几个选项值得留意:安装路径建议保持默认;在选择调整PATH环境变量那一步,一定要选“Git from the command line and also from 3rd-party software”这个选项,否则后面在终端里敲git命令会提示找不到命令;行结束符转换那一步,默认的是Checkout Windows-style, commit Unix-style line endings,这个默认选项对绝大多数项目都适用,直接保留即可。装完之后打开命令行工具,输入git --version能看到版本号就说明安装成功了。
macOS用户推荐用Homebrew安装,命令是brew install git。如果你还没装Homebrew,也可以直接下载官方pkg安装包,或者通过Xcode Command Line Tools自带的Git来用。不过我个人建议还是用Homebrew,因为后续做版本升级非常方便,一条brew upgrade git就搞定。Linux发行版则用各自系统的包管理器,Ubuntu和Debian系是sudo apt install git,CentOS和Fedora是sudo yum install git或sudo dnf install git。
这里有一个细节很多人忽略:安装完Git之后,在Windows上一定要用管理员身份打开终端再测试git --version,否则可能因为权限问题导致环境变量没生效。macOS和Linux一般没有这个问题。实测下来,只要安装路径不含中文、安装时没手动改掉PATH选项,基本一次就能装好。
2.2 全局配置:这一步不做后期处处碰壁
Git装好后还不能直接开干,必须要做两件全局配置:设置用户名和邮箱。这个配置的作用是让每一次提交都能记录下“是谁”做的修改。很多人觉得这步无所谓,随便填一个,直到参与团队协作时才发现,提交记录里的名字和代码评审系统对不上,又得费劲去改历史。
配置命令非常简单:
bash复制git config --global user.name "你的姓名"
git config --global user.email "你的邮箱"
--global参数表示这台机器上的所有仓库都用这份配置,如果你想针对某个特定仓库使用不同的身份,就在那个仓库目录下不加--global再执行一次同样的命令。
验证配置是否生效,可以用git config --global --list查看全部全局配置项。这里还有几个高频配置值得一起设置。一个是默认分支名,目前主流都是把初始分支命名为main,可以通过git config --global init.defaultBranch main来设置;另一个是别名,我强烈建议把几个高频命令设置成短别名,敲起来效率高很多,比如git config --global alias.st status、git config --global alias.ci commit、git config --global alias.br branch、git config --global alias.co checkout。设置完别名后,git st就等价于git status,日常操作能省不少手指动作。
2.3 配置SSH Key:免密推送远程仓库的关键
如果你只打算在本地用Git,SSH Key可以跳过。但只要你需要往GitHub、码云或者公司内网的GitLab推送代码,我强烈建议把SSH Key配置好。用HTTPS方式推送代码每次都要输账号密码,而SSH方式配置好之后一劳永逸,而且很多公司的内网Git服务只开放SSH端口。
配置SSH Key分三步。第一步,检查本机是否已有密钥:
bash复制ls -al ~/.ssh
如果看到id_rsa和id_rsa.pub这两个文件,说明之前生成过。没有的话就执行第二步,生成新密钥:
bash复制ssh-keygen -t rsa -b 4096 -C "你的邮箱"
一路回车就能生成成功,默认存储在~/.ssh/目录下。第三步,把id_rsa.pub文件里的内容复制到Git服务平台的SSH Keys设置页面。不同平台的入口名称略有不同,GitHub是在Settings里的SSH and GPG keys,Gitee是在设置里的SSH公钥。
配置完成后可以执行ssh -T git@github.com测试连通性,看到“Hi xxx! You've successfully authenticated”这样的提示就说明成功了。实测下来这个配置是一次性的付出、长期的收益,非常值得花这几分钟搞定。
3. Git核心逻辑与本地仓库操作详解
3.1 三大区域概念:理解Git一切操作的基础
在开始敲命令之前,我强烈建议先花两分钟理解Git的三个核心区域,因为后面所有的命令本质上都是在这三个区域之间搬运数据。不了解这个,你连git add和git commit为什么要分开执行都理解不了,更别提理解git reset的各种参数了。
Git的三大区域分别是工作区、暂存区和版本库(本地仓库)。工作区就是你电脑上实际看到的项目文件夹,你新建、修改、删除文件的操作都发生在工作区。暂存区是一个临时存放区域,你可以把它理解成快递驿站——你的修改先放到驿站寄存,还没真正发出去。版本库则是Git替你保存的所有历史版本的数据库,每次提交就是把暂存区里的内容真正固化成一个快照,永久保存到版本库中。
用生活中的场景来类比,工作区是你写稿子的桌面,暂存区是抽屉,版本库是档案柜。你写完一段内容放在桌面上(工作区修改),觉得这段没问题了先放到抽屉里(git add),攒够一个阶段的修改后,统一归档进档案柜(git commit)。理解了这三个区域,后面所有命令都是在回答一个问题:把数据从哪个区搬到哪个区。
状态查看命令git status会明确告诉你当前哪些文件处于什么状态。Untracked表示新文件还没被跟踪;Changes not staged表示修改了还没放入暂存区;Changes to be committed表示文件已经在暂存区,等待提交。看到这些提示,对应到三大区域,你就能清楚地知道自己处于操作流程的哪一步。
3.2 初始化仓库与首次提交的完整流程
初始化仓库有两种方式:从零新建和克隆远程仓库。先讲从零新建的情况。
假设你新建了一个项目文件夹my-project,进入这个目录后执行:
bash复制cd my-project
git init
这条命令会创建一个隐藏的.git目录,这个目录就是仓库的版本库所在位置。执行成功后,Git开始跟踪这个目录下的所有文件变化。有一点要注意:git init执行后,仓库还是空的,没有任何提交记录。
接下来往里放一些项目文件,比如创建一个README.md,然后执行git status,你会看到README.md处于Untracked状态。这时候执行:
bash复制git add README.md
文件就进入了暂存区。再执行git commit -m "feat: 初始化项目,添加README文件",这次提交就完成了。commit命令后面的-m参数是提交信息,用来描述这次改了什么。提交信息看起来简单,但实际开发中非常重要,团队协作时一份清晰规范的提交信息能让历史记录变得非常有可读性。我惯用的格式是类型(scope): 描述,类型包括feat(新功能)、fix(修复bug)、docs(文档变更)、refactor(重构)、style(格式调整)、test(测试相关)等,scope是可选的影响范围。
如果同时新增了多个文件,不想一条条add,可以执行git add .,把当前目录下所有未跟踪和修改过的文件都加入暂存区。不过这个命令要谨慎使用,如果项目里有临时文件或不应该纳入版本控制的文件,git add .会把它们也一起加进来。建议配合.gitignore文件使用,下面会专门讲。
3.3 代码提交的正确姿势与提交信息规范
提交是Git里最高频的操作,但很多人并不清楚什么样的提交才算“好”。一个常见的问题是把大量不相关的改动混在一次提交里,比如同时改了登录逻辑、样式表和配置文件,提交信息却只写了“更新”。这样做的后果是,将来定位问题时你会非常痛苦——明明只是改了个样式,却不得不在一堆提交里翻找。
我的经验是:提交要够“小”够“专注”。每次提交最好只做一件事,对应一条清晰的描述。比如“修复用户登录时验证码不刷新的bug”就比“提交代码”有价值得多。如果一次性改了多个不相关的地方,就分多次提交,先用git add把不同文件分别加入暂存区,然后分别提交。
提交之后查看历史,用git log命令。默认输出包括提交哈希值、作者、日期和提交信息。加上--oneline参数可以把每次提交压缩成一行显示,加上--graph参数可以图形化展示分支合并历史,加上--author="用户名"可以按作者过滤,加上-n加数字可以限制显示条数,比如git log -5就只看最近5条。日常调试和审查代码时,这些参数组合起来非常实用。
3.4 .gitignore:避免把不该提交的文件提交上去
.gitignore这个文件是新手最容易忽略、老手最重视的文件。它的作用是声明哪些文件或目录不应该被Git跟踪。
Java项目里有target目录、Python项目里有__pycache__目录和.venv虚拟环境、Node项目里有node_modules目录、IDE项目里有.idea和.vscode目录,这些都不应该提交到仓库里。target、node_modules这类目录是可以随时通过构建或包管理工具重新生成的,提交进去只会让仓库变得臃肿。.idea和.vscode这类是个人开发环境的配置,不同人的配置不一样,提交进去容易产生干扰。
一个典型的Java项目.gitignore长这样:
gitignore复制target/
*.class
*.jar
.idea/
.vscode/
*.iml
.DS_Store
文件里一行一个规则,target/表示忽略整个目录,*.class表示忽略所有.class结尾的文件。GitHub上有很多现成的.gitignore模板,也可以直接在创建项目时选择语言让平台自动生成一份,然后根据自己的实际情况微调。
有一个坑很多人踩过:文件已经在仓库里了,然后才写进.gitignore,结果发现根本不生效。原因是.gitignore只对未被跟踪的文件生效,已经被Git跟踪的文件加进去也不会被忽略。解决办法是先执行git rm -r --cached 目录名把文件从版本控制中移除(但保留工作区文件),再提交一次,之后这个文件就会被正常忽略了。
4. 分支管理与合并:高效协作的核心能力
4.1 分支的本质与创建切换
可以说,没有分支的Git只用了它三成功力。分支是Git最强大的特性之一,它允许你在同一时间线之外开辟出独立的工作线,互不干扰。
分支的本质是给提交记录打的一个标签指针,创建分支几乎不消耗任何资源。你可以把分支理解成平行世界——你在A世界里按自己的计划开发功能,B世界保持稳定不受影响,两个世界可以随时合并。
创建和切换分支是最常用的两个操作:
bash复制git branch feature-login
git checkout feature-login
或者一条命令搞定:
bash复制git checkout -b feature-login
新版Git推荐用git switch命令,语义更清晰。git switch -c feature-login是创建并切换到新分支,git switch feature-login是切换到已存在的分支。查看当前仓库有哪些分支,执行git branch,当前所在分支前面会带星号。
4.2 分支合并的五种场景与冲突解决
合并是把一个分支的修改整合到另一个分支的操作,最常用的命令是git merge。假设你现在在main分支上,想把feature-login分支合并过来,执行:
bash复制git merge feature-login
Git会自动把feature-login分支上的提交记录嫁接到当前分支上。如果两个分支修改的文件没有重叠,合并会自动完成。但如果两个分支同时修改了同一个文件的同一行,Git就无法自动判断该保留哪个版本,这时候就产生了冲突。
冲突发生时会看到类似这样的提示:CONFLICT (content): Merge conflict in src/Login.java,然后通过git status可以确认哪些文件存在冲突。打开冲突文件,会看到类似下面的内容:
java复制<<<<<<< HEAD
用户登录逻辑的代码
=======
新改的登录逻辑代码
>>>>>>> feature-login
<<<<<<< HEAD到=======之间是当前分支(main)的内容,=======到>>>>>>> feature-login之间是合并进来的分支(feature-login)的内容。你需要人工判断保留哪边,或者把两边的代码合并成最终版本,然后删掉这些标记符号。
解决完所有冲突文件后,执行git add把文件标记为已解决,再执行git commit完成这次合并提交。这里我不建议用git merge --abort来回避冲突,因为冲突本身是正常的协作过程,特意制造冲突当然不好,但遇到冲突时耐心解决,会让你对代码的理解更深。
还有两种分支操作场景很常见。一个是变基git rebase,它可以把当前分支的提交“移动”到另一个分支的最新提交之上,让提交历史保持线性整洁。但rebase会改写提交历史,如果在已经推送过的公共分支上执行rebase,可能导致其他人本地仓库失同步,所以公共分支不要用rebase,这是铁律。另一个是临时切换到别的分支去处理紧急bug,本地修改还没完成,可以用git stash把当前修改暂时封存起来,切换到其他分支处理完紧急事务后,再切回来执行git stash pop恢复现场。
4.3 分支策略:单人项目到团队协作的推荐玩法
分支到底应该怎么建,其实没有绝对标准,但我可以分享几套经过验证的玩法。
自己一个人的项目,最简单的玩法是只有main分支,或者main加一个开发分支。小项目完全可以直接在main上提交,别把简单事搞复杂。
团队项目比较成熟的分支策略是Git Flow的轻量版。main分支始终保持可发布状态,每次发布打一个tag。develop分支是日常开发集成的分支。每个功能从develop拉一个feature分支,开发完成后合并回develop。线上出现紧急bug时,从main拉一个hotfix分支,修好直接合并回main和develop。这套流程不重,但能保证主线稳定。
更轻量的是Github Flow:main分支永远可用,每次开发从main拉分支,通过Pull Request(PR)方式来review和合并。这个方法对小型团队和开源项目非常合适,也是我目前的主力玩法。
5. 远程协作:连接与同步的完整方案
5.1 远程仓库添加与推送拉取
本地仓库和远程仓库(GitHub、GitLab、Gitee等)一旦关联,协作就真正展开了。
在远端平台新建一个空仓库后,本地仓库要关联到远程需要用:
bash复制git remote add origin git@github.com:你的用户名/项目名.git
这里的origin是远程仓库在本地的默认别名,可以理解为“远端主仓库”的代称。查看当前配置了哪些远程地址用git remote -v。
关联完成后,把本地代码推送到远程:
bash复制git push -u origin main
首次推送要加-u参数,它的作用是建立本地main分支和远程main分支的跟踪关系,之后就可以直接git push和git pull,不需要再指定分支名。如果远程仓库已经有代码,本地是从零新建的没有关联过,直接push会报错,因为两个仓库的提交历史没有共同祖先。这时候要么先git pull --rebase origin main把远程代码拉下来合并,再推送,要么就像很多平台提示的那样加--force强制覆盖——但我必须提醒一句:能不用force就别用force,远程仓库一旦被强制覆盖,其他人的本地历史就会出乱子。
还有一个高频场景是你参与了别人的开源项目,无法直接往原仓库推送。正确做法是先fork一份到自己的远程仓库,然后把本地仓库关联到两个远程地址——一个是fork后的地址(一般叫origin),一个是原项目地址(一般叫upstream)。平时基于自己的origin开发,需要同步原项目最新代码时执行:
bash复制git fetch upstream
git merge upstream/main
5.2 fetch、pull、push之间的关系
这三个命令是远程协作里最容易混淆的一组。简单说,fetch只负责把远程仓库的最新提交记录和文件下载到本地,但不会自动合并到你当前的工作分支;push负责把本地提交推送到远程;pull则等于fetch加merge两步合并为一步。
git pull虽然用起来方便,但它隐含了一个合并操作,自动产生一个merge提交,历史图上会多一个分叉节点。如果你希望历史更线性,用git pull --rebase,它会先把本地未推送的提交暂存起来,拉取远程最新代码后,再把你本地的提交依次“叠”上去。
这里有个很常见的坑:本地有未提交的修改时,git pull可能会因为文件冲突而报错。稳妥的做法是pull之前先确认当前工作区是干净的,要么git commit了、要么git stash暂存了,再执行pull操作。我在配置好一套全局alias之后,日常操作基本就是git fetch加git status看看落后了几个提交,再决定合并方式,很少直接用git pull。
5.3 团队协作中Pull Request的完整工作流
Pull Request(简称PR,国内有些平台叫Merge Request)是团队协作中做代码审查的核心机制。它的本质是:你把自己分支上的改动推送到远程,然后发起一个申请,请仓库维护者审核并合并你的改动。
PR的完整流程大致是:本地创建分支并开发;推送分支到远程;在平台上点击“New Pull Request”,选择目标分支和源分支;填写PR描述,写清楚改了什么、为什么改、影响范围是什么;邀请reviewer审查代码;根据review意见修改代码并重新推送,PR会自动更新;审核通过后由维护者合并。
有两点实际经验值得分享。一个是PR尽量保持小范围,一次性改动上百个文件的PR,review效率极低,容易导致审查者敷衍了事,出bug的风险因此升高。另一个是PR描述要用心写,我一般按“背景、改动内容、验证方式、影响范围”四段来写,Reviewer看着轻松,返工次数也会明显减少。
6. 撤销与回滚的几种姿势与适用场景
6.1 工作区、暂存区、本地提交的撤销操作
写代码总会写错,Git的好坏就体现在它给了你各种后悔药。但每种撤销操作的适用场景不同,选错了反而会让事情更糟。
修改还在工作区、还没执行add的时候,想撤销某个文件的修改,恢复到上一次提交的状态:
bash复制git checkout -- 文件名
或者用新版命令git restore 文件名。这个操作会把工作区这个文件的修改全部丢弃,且无法找回,执行前务必确认。
已经add进暂存区、还没commit的时候,想撤销暂存但保留工作区修改:
bash复制git reset HEAD 文件名
或者新版命令git restore --staged 文件名。这个操作会把这个文件从暂存区移回工作区,但不会动你的实际修改内容。
已经本地commit了,但还没push,想撤销这次提交并保留修改:
bash复制git reset --soft HEAD~1
HEAD~1表示最近一次提交,--soft参数只移动HEAD指针,保留所有修改内容在暂存区。如果你想彻底撤销这次提交和相关修改,用git reset --hard HEAD~1,这个命令会直接丢弃最后一次提交的所有内容,执行前要格外谨慎。
6.2 reset、revert的区别:什么时候绝不能用reset
git reset和git revert是撤销操作里最容易混淆的一对,但二者适用场景完全不同。
reset是“时光倒流”,它会移动分支的HEAD指针,让分支指向过去的某个提交。如果修改还没被推送过,用reset没问题。但如果修改已经推送到了远程仓库、其他同事可能已经基于你的提交做了新工作,这时候用reset强制回退,会打乱所有人的本地历史,直接后果就是别人的本地仓库和你远程的提交历史不一致,一pull就报出一堆冲突。
revert则是“生成一个反向提交”,它不会删除历史,而是在你当前提交的基础上,新生成一个提交,把之前的改动反着改回去。这样历史是追加的,其他同事拉取时不会有任何问题。
所以我给的判断标准很简单:只在自己本地还没push的提交上用reset,已经push到公共远程的提交或者公共分支上移动指针之前,一律用revert。这个准则帮我避免过很多次事故。
6.3 不小心commit错文件后的补救流程
场景:你想提交A和B两个文件,结果手滑把C文件也commit进去了,而且已经push了。此时千万不要急着跑路,按下面的流程处理:
先把C文件从当前提交中移除,git rm --cached C文件名,把这个变更提交一次。然后如果你需要完全逆转C文件在提交历史中的内容修改,用git revert <某次提交的哈希值>来生成反向提交。最后正常情况下,如果C本身就不该被跟踪,把它加进.gitignore,避免下次再犯。
如果是更极端的情况,你发现当时提交时把代码里的密钥或者敏感信息泄漏到了远程仓库,这时候只靠reset或者revert是不够的,因为提交历史里依然保留着旧内容。唯一的彻底办法是立刻去密钥管理平台把这把密钥全部作废重新生成,同时如果仓库是公开的,建议和平台方沟通清除相关缓存记录。不要幻想用delete历史来擦除信息,只要密钥出现过旧版本,就当它已经泄漏了。
7. 高频问题排查与实操避坑指南
7.1 常见报错对照表
我在实际教学和日常答疑中,整理了下面几个出现频率极高的Git报错,每条都附上了解法和背后的原因。
| 报错信息 | 含义 | 解决方法 |
|---|---|---|
fatal: not a git repository |
当前目录不是Git仓库 | 检查是否在项目目录下,或是否需要执行git init |
fatal: refusing to merge unrelated histories |
两个仓库没有共同提交历史 | 加上--allow-unrelated-histories参数执行合并,但要先确认两个仓库确实应该合并 |
error: failed to push some refs to |
本地分支落后于远程分支 | 先git pull --rebase拉取合并,再重新push |
fatal: Authentication failed |
认证失败 | 检查账号密码或SSH Key是否配置正确 |
Please tell me who you are |
没配置用户名和邮箱 | 按前面2.2节配置user.name和user.email |
hint: Updates were rejected because the remote contains work that you do not have locally |
同上,本地缺远程提交 | 先fetch再merge/rebase,或者pull后再push |
其中refusing to merge unrelated histories这个报错看起来挺吓人,实际场景多半是:你在GitHub新建了仓库,并勾选了生成README或license文件,然后把本地已有代码仓库关联上去直接push,两边提交历史没有共同祖先,Git就报警了。确认两边的确是同一个项目的历史衔接,加--allow-unrelated-histories即可。
7.2 让操作更高效的小技巧
最后分享几个我日常工作中非常受益的小技巧,不算高级,但确实能提升效率。
第一,配置提交模板。可以建一个.gitmessage文件,里面写清楚提交信息的格式要求,然后通过git config --global commit.template .gitmessage指定。之后再执行git commit时会自动打开这个模板,提醒你按规范写信息,对养成好习惯很有帮助。
第二,用git diff检查改动。git add之前养成看diff的习惯,执行git diff查看工作区改动,加--staged参数查看暂存区改动。很多时候bug就是改着改着改错位置了,提交前扫一眼diff能提前发现很多问题。
第三,善用git log的格式定制。git log --oneline --graph --all --decorate这个组合能在一屏范围内看到一个清晰的提交网络和所有分支的位置。我基本把它配成了一个别名git lg,每次打开仓库第一件事就是敲这行命令看整体状态。
第四,给重要提交打tag。发版本时执行git tag v1.0.0,后续需要查某个版本对应的代码状态时,直接git checkout v1.0.0就能切到那个时点。加上-a参数可以附带标注信息,推荐发布版本都用git tag -a v1.0.0 -m "首个正式版本"。
7.3 新老命令对照与踩坑记录
Git官方在2.23版本之后引入了一组新的命令,主要是git switch和git restore,目的是把“切换分支”和“恢复文件”这两个职责从git checkout里拆出来。老手可能习惯了git checkout,但新项目我建议新命令,因为它们语义更清晰,不容易误操作。
有个真实案例我印象很深。一位同事想丢弃某个文件的工作区修改,输入了git checkout .,原本只想撤销一个文件的改动,结果.匹配了整个当前目录,所有未提交的改动全部被丢弃了。如果他用的是git restore 文件名,误操作的概率会小很多,因为命令本身把操作对象限定得更清楚。
再说一个关于行结束符的坑。Windows和Linux换行符不同,Git在提交时会根据配置自动转换。如果项目里混用不同操作系统的开发者,又没有统一的换行符配置,会在pull时看到大量“文件被修改”的假象,实际内容根本没变。解决方法是给仓库根目录加一个.gitattributes文件,明确指定文本文件统一使用LF换行符,格式大致是* text=auto加上针对特定文件类型的规则。这个文件写好一次,之后就能从根上解决换行符导致的乱象。
还有一个细节是关于大文件。Git本身不适合存放大体积的二进制文件,如果一个仓库里放了几个几百MB的安装包、数据集或者视频,clone和pull的速度会变得非常慢,仓库体积也会快速膨胀。这时候应该用Git LFS(Large File Storage)来管理,或者干脆不用Git管理这类文件,改用对象存储之类的专门方案。这个原则越早做越好,等仓库已经膨胀到几百MB再收拾,重建历史是件非常折腾的事。
作为日常实用派,我始终坚持一条原则:Git是工具,不是目的,别把操作搞得太玄学。花时间理解了三大区域和分支本质,配合一套自己的常用命令习惯,然后剩下的就在实战中多碰、多解决,慢慢就会形成手感。说白了,我写下的这些所谓“经验”,绝大多数都是从一个个报错里逼出来的,你现在多踩一个坑,之后就能少踩一个。
