刚入行那会儿我最怕听到的词就是“Git”。写代码写得好好的突然要提交、合并、拉分支每个命令后面都跟着一堆没见过的报错。后来带过好几个实习生发现大家刚开始的心理活动几乎一模一样这是什么怎么用怎么又报错了其实Git这套东西真正常用的命令就十几个把它核心的流程跑通以后剩下的都是查命令的事。这篇学习笔记是我自己从零跑通Git的完整实战记录覆盖环境安装、本地提交、远程仓库、分支合并、误操作补救以及新手高频踩坑的报错处理。适合那种完全没接触过版本控制或者只在别人指挥下敲过一两条命令的人。看完你不需要记住所有参数只需要理解Git每一步到底在干嘛以后遇到问题也能够自己推理出解决方案。1. 从零开始安装Git并搞定终端环境1.1 下载安装时最关键的其实是那两个不显眼的选项Windows用户安装Git最直接的方式是去Git官网下载Git for Windows的安装包。官网速度如果不太理想可以找国内高校或者云厂商的镜像下载但务必要注意核对版本号和安装包哈希值别下到被篡改的文件。安装过程基本都是“Next”,但有两个配置项我建议你认真看一眼第一个是“Adjusting your PATH”,务必选择中间那个“Git from the command line and also from 3rd-party software”,否则后面在终端里输git命令可能会提示找不到第二个是“Configuring the line ending conversions”,新手直接保持默认即可它关系的是Windows和Linux之间换行符的转换默认选项已经是最稳妥的。装完之后别急着关窗口马上打开一个终端输命令验证环境。这里有个容易翻车的地方你如果用的还是刚安装前打开的那个终端窗口可能会提示git不是内部或外部命令。不是环境变量没配好而是终端不会自动刷新环境变量把窗口关掉重开一个就好。1.2 安装后立刻要做的基础配置Git装好了但不配置用户信息你连git commit都做不了。原因在于Git需要知道每次提交是哪个人提交的所以有两项是必须的git config --global user.name Your Name git config --global user.email youremailexample.com这个--global表示全局生效意思是这台机器上所有的Git仓库都会默认用这套身份信息。如果你有多台电脑或者在帮公司项目提交也可以去掉--global,在某个具体仓库里指定一个不一样的用户名和邮箱。还有一个配置我强烈建议新手做那就是把默认编辑器换成VS Codegit config --global core.editor code --wait为什么要换因为Git在有些操作下比如后面要说的commit --amend会自动打开一个文本编辑器让你填写内容。如果不改默认打开的是Vim。Vim对新手非常不友好进去之后不知道按什么键退出我至少见过十几个新人被卡在编辑界面里。换成VS Code之后填完信息直接关窗口就行体验完全不一样。1.3 Git Bash到底是什么要不要先装小乌龟Windows上安装Git之后开始菜单里会出现一个叫Git Bash的东西。它是专门给Windows用户准备的类Linux命令行环境很多人在这一步就懵了为什么有了cmd、有了PowerShell还要用这个黑窗口原因很简单Git Bash不仅能运行git命令还支持Linux那一套文件操作命令比如ls、cd、touch、rm对用过Mac或者Linux的人来说非常亲切。新手用Git Bash做练习绕开了Windows下路径格式带来的各种奇怪问题是最省心的选择。另一个经常被问到的工具是TortoiseGit圈内习惯叫它“小乌龟”。它是一个图形化界面工具装好之后鼠标右键菜单里会出现一堆Git操作选项确实降低了上手门槛。但我个人建议新手别急着装小乌龟。原因是市面上的教程、博客、AI工具给的例子几乎都是命令行一旦你习惯了右键菜单遇到问题想搜索解决方案往往会变得非常抽象。先用命令行把逻辑搞明白之后再换小乌龟只是为了提升效率而不是因为看不懂命令。2. 本地版本管理的核心循环init、add、commit到底在做什么2.1 第一次submit从一个文件夹到一个Git仓库在你已有的项目目录里打开Git BashWindows上可以直接在文件夹右键选择“Git Bash Here”输入git init执行之后Git会在当前目录下生成一个隐藏的.git文件夹。这个文件夹就是Git仓库的核心里面保存着你整个项目的版本快照和提交记录。一旦删了它项目的Git历史就全没了。此时你的项目还处于“未被Git管理”的状态。接下来创建或放一个文件进去比如新建一个README.md,然后运行git status,就能看到类似这样的输出On branch master No commits yet Untracked files: (use git add file... to include in what will be committed) README.md这里的“Untracked files”是新手遇到的第一个术语翻译成人话就是“Git注意到这个文件了但它还不知道要不要管它”。想要让Git真正开始管这个文件得把它加入暂存区git add README.md此时再执行git status,文件状态就会从“Untracked”变成“Changes to be committed”。紧接着执行提交git commit -m docs: init readme-m的意思是本次提交的描述信息。到这里你的项目才真正有了第一个Git提交记录。2.2 暂存区背后到底是怎么设计的很多新人对git add这一步特别不理解我明明已经把文件存盘了为什么还非要执行add再commit这不脱裤子放屁吗这个设计其实挺像超市购物。你的购物车就是暂存区你可以从货架上工作区往里挑东西git add,全部挑完之后再去收银台结算git commit。如果没有购物车你每拿一个商品就得结一次账效率低且容易乱。更重要的是暂存区让你可以一次提交只包含部分改动。比如你改了三个文件其中两个是完成了一个功能的另一个是调试过程中写的临时代码那你完全可以只把前两个add进来第三个先不提交。这种精细控制是Git作为专业版本管理工具的魅力所在。2.3 提交信息的质量决定你一个月后能不能看懂我不太喜欢跟新人讲一堆提交规范因为那是团队协作层面的约束。但有一条底线必须说提交信息至少要能让“一周后的自己”看明白这条提交干了什么。最常见的坏写法是update、fix、修改这种信息没有任何信息量。稍微好一点的写法是一条动宾短语比如fix: 修复登录模块token过期问题。如果改动比较多还可以提交多行信息第一行当标题空一行之后写具体内容git commit -m feat: 增加用户注册功能 -m - 新增注册接口 - 增加邮箱格式校验 - 修复密码长度判断错误实际工作中提交信息写得好受益的不仅是别人更是未来的自己。尤其当你需要从历史记录里回查某个改动时一条清晰的提交信息能帮你省下大量时间。3. 连接远程仓库配置SSH密钥搞懂clone、push、pull3.1 HTTPS还是SSH新手不用纠结太久本地仓库玩明白之后接下来就要跟远程仓库打交道了。常见的托管平台有GitHub、Gitee、GitLab不管用哪家连接方式主要就两种HTTPS和SSH。HTTPS的优点是省事clone或者push的时候输入账号密码或者个人访问令牌就行。缺点是每次都要输密码虽然Windows凭据管理器会帮你记住但遇到密码失效或者电脑重装又是一通折腾。SSH的优点是配置好之后不用再输密码而且对开发者来说更“正统”。缺点是需要手动生成密钥、配置公钥做好之后本地跟远程之间建立信任关系。我的建议是如果你想长期做开发直接配SSH一次配置长期受益。3.2 SSH密钥生成与配置保姆级流程在本地打开Git Bash执行ssh-keygen -t ed25519 -C youremailexample.com这里-t ed25519指定的是加密算法比老的RSA更安全更快。随后会问你保存位置和passphrase新手通常直接回车确认默认位置、不设passphrase即可。生成完成后查看公钥内容cat ~/.ssh/id_ed25519.pub这串内容就是你需要放到远程平台上的公钥。以Gitee为例进入“设置”→“SSH公钥”,把内容粘贴进去保存。GitHub和GitLab也都有类似的入口。配置完成后验证一下ssh -T gitgitee.com如果是Gitee会返回一串欢迎信息说明SSH密钥已生效。这里有个小坑如果你是按照博客教程一步步做发现一直permission denied,先检查公钥是不是复制全了文件末尾的“你的邮箱”部分也要复制。3.3 clone、pull、push的主干流程远程仓库分两种情况。第一种是你已经有一个现成的远程仓库想把它下载到本地直接git clone gitgitee.com:yourname/your-repo.gitclone会拉取远程仓库里的所有代码和历史记录并在本地自动生成一个和仓库同名的文件夹比起进文件夹再git init、再git remote add方便得多。第二种情况是你在远程平台建了一个空仓库而本地已经有代码了。这时候需要先关联远程地址git remote add origin gitgitee.com:yourname/your-repo.git然后推送git branch -M main git push -u origin main-u参数很关键它的作用是把本地的main分支和远程的main分支建立关联。建立关联之后以后直接敲git push和git pull就行不用每次都带参数。日常开发最常用的其实是pull和push这两个命令。git pull是把远程的新提交拉到本地git push是把本地的新提交推到远程。很多人把这两条命令当成了对称操作但实际上git pull在背后做了两件事先git fetch把远程提交拿下来再做一次合并。理解了这一点后面遇到的“冲突”问题就很好解释了。3.4 push被拒别慌先处理“分叉”再推新手第一次用Git协作时几乎都会遇到这个报错! [rejected] main - main (fetch first) error: failed to push some refs to gitgitee.com:yourname/your-repo.git hint: Updates were rejected because the remote contains work that you do not hint: have locally. This is usually caused by another repository pushing to hint: the same ref. You may want to first integrate the remote changes hint: (e.g., git pull ...) before pushing again.意思是远程分支上有你本地没有的提交Git不敢直接用你的提交覆盖掉它们。此时最安全的做法是先把远程的提交拉下来合并git pull origin main如果远程和本地各自改的是不同文件pull会自动合并成功然后你就能正常push了。如果两个提交改了同一个文件的同一行那就进入了下一个环节合并冲突。还有一种情况比较特殊就是本地仓库和远程仓库的历史完全没有任何交集叫“unrelated histories”。这通常是因为你在空仓库里手动创建了README文件然后又在本地git init后生成了不同的初始提交。解决办法是在git pull时加上一句git pull origin main --allow-unrelated-histories这个参数的意思是“允许两个没有共同祖先的历史合并”。按经验说这个报错最多出现于刚接触Git时跟远程空仓库的第一次“亲密接触”。4. 分支与合并只有两条规则就不会乱4.1 分支不是文件夹的副本而是一张书签很多新手会把分支想得很复杂觉得是不是把代码复制了好几份。其实Git的分支本质上就是一个指针指向某一次提交。你可以把它理解成书签一本书可以夹好几张书签你不用把书抄好几遍只需要记录每一张书签夹在哪一页。创建并切换到新分支git switch -c feature/login-c是create的缩写意思是创建并切换。老一点的教程会让你用git checkout -b feature/login,但Git 2.23版本之后git switch这个命令更直观也更难误操作。切到新分支后你在这个分支上的提交完全不影响其他分支。等你的功能开发完了再把它合并回主干分支。4.2 合并用merge就好rebse先放一边分支开发完合并操作非常简单git switch main git merge feature/loginmerge会把feature/login分支上的提交以一个新的“合并提交”形式接到main分支上。它保留了两个分支各自的历史看起来是“分叉之后又汇合”安全性最高。另一个命令git rebase也能合代码而且历史更线性、更好看。但rebase的问题是它会改写提交历史如果操作不当可能在推送到远程时产生一堆麻烦。对新手而言我还是建议默认用merge,只有当你充分理解rebase在做什么之后再去尝试。4.3 遇到冲突怎么办解决冲突其实是“手工合代码”合并冲突听起来很吓人但你只需要记住一条前提Git无法自动决定保留哪些改动需要你来拍板。当冲突发生打开相关的文件你会看到类似这样的内容 HEAD 这是当前分支的代码 这是被合并分支的代码 feature/login到之间是当前分支的代码到之间是被合并分支的代码。你需要做的就是人工判断该保留谁、该删掉谁把冲突标记全部清理干净然后重新git add这个文件git add src/xxx.java git commit注意冲突解决完成后Git通常不会自动帮你创建提交你需要手动执行git commit。这里提交信息一般已经帮你填好了直接退出编辑器即可。我要提醒的是冲突不是灾难而是版本控制的正常行为。两个人同时改了同一处代码说明这里可能就是业务逻辑的核心区域解决冲突的过程反而是理解项目结构的好机会。4.4 一个比想象中好用的冷门命令git worktree这是我在带过几个项目之后才彻底爱上的命令。git worktree可以让你在同一个仓库目录下同时检出多个分支到不同文件夹。场景非常常见你在main分支上改代码改到一半临时需要去修复一个线上bug。按老办法你得先把当前改动stash起来再切分支修完bug提交、切回来、再恢复stash。中间任何一步忘了都是一顿折腾。用worktree你可以直接在另一个目录里开新档案git worktree add ../hotfix-fixbug hotfix这会创建一个新的工作目录../hotfix-fixbug,里面是hotfix分支的最新代码而且和原目录互不影响。修完bug提交推送后再把这个worktree移除git worktree remove ../hotfix-fixbug新手可能暂时用不到但提前了解这个命令的底层逻辑能帮你更好地理解Git工作目录和分支之间的关系。5. 误操作补救手册amend、stash、reset怎么选5.1 commit --amend想改最近一次提交的看这里写错提交信息、提交后才发现漏了一个文件、提交后发现有个低级语法错误——这些问题都可以用git commit --amend解决。git commit --amend -m feat: 增加用户注册功能这条命令会把上一次提交给替换掉新的提交哈希会变。有个原则必须记住amend只能用于还没有推送到远程的提交。如果已经push了强行amend之后再次push会被拒绝哪怕加了--force也会给队友带来不小的麻烦。如果你只是想往最近一次提交里追加漏掉的文件可以先git add 漏掉的文件 git commit --amend --no-edit--no-edit的意思是沿用原来的提交信息不改信息、只补内容。5.2 stash临时藏起没做完的工作git stash的行为像是一个临时储物柜。当你手头的工作没做完又必须切走分支时可以把手头这些未提交的改动“存起来”git stash push -m 登录模块还没写完存完之后工作区会回到干净的状态你可以放心切换分支干别的活。需要使用这些改动时再把它弹出来git stash pop这里有一个很常见的问题如果你在另外的分支上已经出现了和stash内容冲突的改动pop的时候会跟你报冲突。不用太紧张按冲突处理的方式解决掉就行。还有一个冷门但很多人问过的场景我改到一半的代码被自己误删了怎么办如果这份代码之前从未add或commit过那基本找不回来。这也是为什么老手会说重要改动尽早提交哪怕提交信息写得丑一点也比丢了强。5.3 reset三种模式你知道自己在做什么再去按git reset有三个关键字--soft、--mixed、--hard代表回退提交时的三种“清扫程度”。模式移动HEAD指针重置暂存区重置工作区适用场景--soft是否否刚才提交错了想重新提交但保留所有改动--mixed默认是是否不想要那个提交但保留文件改动重新组织暂存--hard是是是完全丢弃改动切回指定提交的状态比如你刚才提交了一个重大错误想回到上一个提交但保留现在的改动以便重新处理git reset --soft HEAD~1HEAD~1的意思是“当前提交的前一个提交”。但如果这个错误提交已经push到远程了而且团队成员已经拉取过那就别再reset了优先考虑用git revert commit生成一个反提交这样更安全。5.4 误丢提交的抢救reflog给你后悔药有一次一个同事在自己分支上执行了git reset --hard把前两天写的一个大功能全丢了。大家都很绝望以为只能重写。其实Git有个“备份日志”机制叫git reflog。git reflog它会显示出所有分支头部的历史移动记录包括你reset掉的那些提交的哈希。只要找到你想要的提交id就可以用git reset --hard 那个提交id把分支指针拉回之前的位置丢掉的东西又回来了。注意reflog只记录本地操作如果你提交过又清理了远端那又是另一种情况。但至少这条命令给所有手滑的新手留了一条生路。6. 新手高频报错与排查思路别怕Git翻脸6.1 fatal: not a git repository (or any of the parent directories): .git这个报错大概是新手遇得最多的一个几乎每天都要被问一次。原因极其简单你在当前目录里执行了Git命令但当前目录根本不是一个Git仓库往上找父目录也找不到.git文件夹。很多人的习惯是打开终端就直接敲git status但终端默认目录可能停在用户主目录或者其他不相干的地方。解决办法是确认当前路径然后进到仓库目录里再执行cd /path/to/your/repo git status如果要做一个项目最开始的初始化则要确认路径之后才执行git init否则这个仓库会被建在错误的目录里。6.2 中文文件名变成八进制乱码在Windows上提交中文文件名比如“测试文档.md”git status里显示的是\346\265\213\350\257\225\346\226\207\346\241\243.md看起来像乱码其实这是Git的八进制转义显示。它不算错误但特别影响体验。解决方法是设置git config --global core.quotepath false配置之后再看中文文件名就正常显示了。这个命令在很多IDE集成的Git插件里也会被自动带上这就能解释为什么你在IDE里看文件名是正常的曾在命令行里却是乱码。理解了原理下次再遇到这种“显示问题”你就能判断出它不是文件坏了。6.3 卡在Vim编辑器里出不来了很多新手第一次提交时习惯了git commit -m xxx这种方式。有一天他们敲了git commit忘了加-m或者执行了git commit --amend结果界面突然变成了一个满屏波浪号的奇怪编辑器按什么键都没反应。这是进入了Vim编辑界面有点像掉进了一个没有UI提示的黑屋里。解决办法记住三条命令就好按 Esc # 进入命令模式 输入 :q! # 不保存退出 或者输入 :wq # 保存并退出如果你实在不想再经历这种情况就按照第一节的内容把默认编辑器换成VS Code。那样在需要写提交信息时Git会自动打开VS Code窗口你写完后直接关掉窗口就行。6.4 push的时候提示Login failed/API token问题用HTTPS方式连接远程仓库时Windows会调用凭据管理器帮你记住账号密码这也是很多人觉得HTTPS方便的原因。但当你换了密码、换了令牌或者同时使用GitLab、Gitee、GitHub多个平台时凭据管理器里的缓存可能还是旧口令就会报出类似“Login failed. Check API token or GitLab version...”的错误。排查思路是先把凭据管理器里关于远程仓库的旧账号信息删掉。在Windows搜索“凭据管理器”→“Windows凭据”找到和git地址相关的条目删除后重新push系统会弹出窗口要求输入新的账号密码或令牌。如果是GitLab用户大概率是在生成个人访问令牌Personal Access Token时忘了选权限范围或者令牌过期了。重新生成一个带write_repository权限的令牌再试一次基本就通了。6.5 误把远程地址关联错怎么看怎么改还有一种情况很常见git remote add origin的时候复制错了地址push一直失败。这时候不要去删掉整个仓库重新clone可以简单查看远程地址git remote -v然后修改origin的地址git remote set-url origin gitgitee.com:yourname/your-repo.git如果手误添加了一个不需要的远程仓库也可以删掉多余的那个git remote remove origin这几个命令在换仓库托管平台、从A平台迁移到B平台时是必备操作。很多人一遇到这个问题就急着把整个文件夹删掉重新弄其实完全没必要。写到这里基本上把新手从零上路需要的Git知识和真实踩坑场景都过了一遍。我自己带项目的时候发现学Git最快的方式不是背命令而是出错之后去理解这个错误到底在抱怨什么然后顺着报错信息一步步排查。配置好的Git环境、一条合理的提交信息比记住十个命令的准确拼写更能体现一个开发者的工程素养。最后的建议只有一条挽起袖子建个空目录把今天看到的命令全部亲自敲一遍。