Git入门到实践:环境搭建、SSH配置与高频命令详解
1. 装对Git环境比背命令重要得多先说个我在各种交流群里见过无数次的现象很多人不是因为Git命令难学才放弃而是卡在了最前面的安装配置上。打开官网下载慢、装完双击没反应、在终端里敲git提示不是内部或外部命令、SSH连不上远程仓库每一道坎都能劝退一批人。其实Git本身是一个设计得相当克制的工具核心命令翻来覆去就那么二十几个真正让人头疼的从来不是命令本身而是环境没搭好。1.1 安装方式选哪种官网安装包、包管理器还是镜像如果你的系统是Windows最常规的方式是去Git官网下载安装包。但国内直接访问官网下载速度经常让人怀疑人生所以很多人会选择镜像站下载。这里提个醒网上搜Git下载会出来一堆乱七八糟的站点尽量认准官方仓库的镜像地址或者用国内的软件源不要随便在第三方小站下安装包安全风险不值得赌。如果不想记下载地址还可以直接用包管理器。Windows 10以上系统可以用winget一行命令搞定winget install --id Git.Git -e --source wingetmacOS上则推荐用Homebrewbrew install gitLinux发行版一般自带没有的话用apt或yum装一下就行。安装过程中有一个选项值得单独说安装向导会问你要不要调整PATH环境变量。默认选项是Git from the command line and also from 3rd-party software建议保持默认。很多人装完发现在CMD里敲git没反应十有八九是这里选成了Use Git Bash only——那个选项会把Git命令限制在Git Bash终端里使用Windows的CMD和PowerShell里就找不到git命令了。1.2 环境变量的坑装完Git却提示找不到命令装完之后打开终端输入git --version如果看到版本号恭喜环境没问题。如果提示git 不是内部或外部命令那就是环境变量没配好或者安装时选错了PATH选项。手动配置的路径也很简单找到Git安装目录下的cmd文件夹比如C:\Program Files\Git\cmd把它加到系统的Path环境变量里。加到用户变量还是系统变量自己一台电脑的话无所谓但如果是公司电脑建议加到用户变量免得多跑一次管理员授权。配完之后记得把已经开着的终端窗口全部关掉再重开因为环境变量的读取是在终端启动时完成的不重启终端不生效。这个细节我被问过无数次每次都怀疑人生。1.3 Git Bash、小乌龟和IDE插件到底该用哪个Git安装完成后桌面上会出现Git Bash和Git GUI两个入口。Git Bash在Windows上模拟了一套Unix风格的命令行环境里面的命令习惯和Linux终端几乎一致这对以后要接触Linux服务器的同学特别友好。我个人在Windows上做Git操作一律用Git Bash除非某些特殊场景需要PowerShell。至于很多人搜到的小乌龟TortoiseGit它是个Windows资源管理器集成客户端装上之后文件夹右键菜单里就会出现一堆Git选项对新手非常直观。但我的看法是可以用它来做日常的提交、拉取、更新操作但不要让它在最开始就替代你对命令的理解。原因很简单图形界面帮你把操作封装好了你反而不知道背后发生了什么。等你在命令行里把每个操作都跑熟了再回去用任何图形客户端都很快。反过来一旦习惯了图形界面遇到命令行报错就容易抓瞎。VS Code和IDEA里也有内置的Git插件和图形化面板。VS Code左侧的源代码管理面板可以看改动、写提交信息、推送拉取属于轻量操作的好帮手IDEA的Git面板更强大分支管理、历史查看、交互式Rebase都有可视化界面。我的建议是IDE的图形面板作为操作入口但终端里的git命令必须会看、会用因为可视化界面报错时最终给出的线索还是那句命令行提示。2. 先打通认证关系SSH密钥、Gitee配置和免密登录很多人的Git学习进度不是死在命令上而是死在认证上。clone一个公开仓库没问题一旦想push自己的代码就开始弹出账号密码、报权限错误、提示登录失败。这里面的核心逻辑就一句话远程仓库需要确认你是谁而确认方式有HTTPS账号密码和SSH密钥两种。2.1 为什么推荐用SSH而不是HTTPSHTTPS方式在clone时最省心仓库地址直接填https://github.com/xxx/xxx.git第一次push会让你输入用户名和密码或Token之后Windows凭据管理器会帮你记住。但缺点也很明显公司内部GitLab如果开启了二次验证或者Token过期你就要重新生成、重新配置而且不同平台的Token管理规则还不一样时间一长很容易乱。SSH方式的核心是密钥对你本地生成一把私钥和一把公钥把公钥放到Gitee、GitHub、GitLab等平台的SSH公钥设置里之后Git操作走SSH协议时平台靠公钥识别你的身份整个过程不需要输入密码。密钥对机制说白了就是一把锁和一把钥匙公钥是锁挂在服务器上私钥是钥匙留在自己电脑里。谁拿钥匙开锁就证明是谁。2.2 生成密钥并配置到Gitee生成密钥的命令是一行ssh-keygen -t rsa -b 4096 -C 你的邮箱执行后会问你保存位置和密码短语passphrase。保存位置默认是~/.ssh/id_rsa直接回车用默认就行。密码短语类似给私钥再加一层保险如果你不想每次push都输一次密码可以直接留空。但需要注意的是私钥文件本身一定要保护好谁拿到你的私钥且知道密码短语就等于能冒充你操作远程仓库。生成完毕后把公钥内容复制出来cat ~/.ssh/id_rsa.pub打开Gitee进入 设置 - SSH公钥把内容粘贴进去标题随便写。这一步就完成了公钥的绑定。配置完成后建议先测一下连接ssh -T gitgitee.com如果返回欢迎信息说明认证链路已经通了。这里最容易犯的错是用git开头但没有指定端口或者公司内网自己搭的GitLab走的是非22端口这时候需要在~/.ssh/config里写清楚Host、HostName和Port否则连不上还一直以为密钥配置错了。2.3 免密配置与Login Failed的排查思路搜git免密的人很多实际上分两种情况。一种是SSH方式本身就不需要输密码私钥没设密码短语的情况下另一种是HTTPS方式想记住账号密码。HTTPS免密在Windows上通常这样设置git config --global credential.helper store这样第一次输过账号密码后凭据会明文保存在~/.git-credentials文件里。安全性要求高的机器上不推荐用store改用manager其实是更好的选择git config --global credential.helper manager这是Git for Windows自带的Windows凭据管理器凭据会加密存放在系统凭据库中。至于报错login failed. check api token or gitlab version这类信息看起来像是个大问题其实大多数情况下就三个原因认证信息过期、Token权限不足、Git版本太旧跟GitLab的接口不匹配。排查顺序建议先看Git版本再看远程地址是不是写成了旧的HTTP路径最后检查Token或SSH密钥是否还有效。没有银弹按顺序排除最快。3. 高频命令的主干链路clone、add、commit、push之间到底发生了什么命令学到最后你会发现日常操作的无非就是一条链路把远程代码拿到本地改完代码把改动记录下来再把记录推到远程。听起来简单但每一步展开都能牵出不少细节。3.1 clone远程仓库和git init的区别从零开始一个项目两条路本地初始化或者克隆远程仓库。git init是在当前目录里创建一个全新的仓库之后可以手动添加远程地址再推送。而git clone 仓库地址是把远程仓库完整地拉下来包括所有历史记录和分支信息。clone完默认会有一个origin远程指向还自动切到了默认分支。对新手来说如果不是要从零建项目git clone是更符合直觉的方式因为不需要手动去配远程地址。克隆时有个小参数我建议立刻养成习惯git clone --depth 1 仓库地址这个叫浅克隆只拉取最新一次提交的历史。对于超大仓库不指定depth的话光下载历史就能让你等到怀疑人生。如果后续需要完整历史再用git fetch --unshallow补全。3.2 status、add、commit、push怎么配合才不慌我见过太多人一开IDE就噼里啪啦敲代码最后要提交时对着一大堆红红绿绿的文件不知所措。正确的节奏应该是改代码前先看一眼当前状态git status每次完成一个逻辑小改动后立刻git add这个文件写清楚本次改动目的的提交信息然后git commit最后才统一git push到远程git add是把改动从工作区放到暂存区git commit是把暂存区的快照写入本地仓库历史里。很多新手不理解为什么有个暂存区这么绕我的理解是它允许你把一次大的改动拆成多个逻辑清晰的提交。比如你改了三个文件分别修复了三个不同的问题你可以分三次git add指定文件再分三次git commit这样以后回溯问题时定位特别快。提交信息是最能拉开专业度的地方。别写fix或者update这种谁都看不懂的废话至少要说清楚修了什么、影响哪里、为什么这么改。Push之前养成先拉取的习惯git pull --rebase为什么加--rebase这里先埋个伏笔后面分支管理那一节再说。你只需要知道直接git pull在多人协作时容易产生多余的merge提交记录用--rebase可以让历史保持线性。3.3 pull和fetch的分别不好好用会让人社死git fetch是把远程的最新提交下载到本地但不修改你当前的工作区也就是说你还在原来的代码上继续干活。git pull则等于fetch加merge它会直接把远程的改动合并到你当前分支。很多尴尬场景都来自滥用git pull你正在改一个文件的A部分同事改了同一个文件的B部分你都没意识到然后pull的时候冲突了。如果先fetch再决定怎么处理主动权就在你手里直接pull的话冲突发生时你已经被强制拉进了合并状态。更稳妥的一套操作git fetch origin git log origin/main --oneline先看看远程分支和你本地分支差了多远再决定是pull、rebase还是仅仅推送。这套逻辑对新手来说可能需要点时间适应但一旦养成你在团队里不乱来的口碑就立住了。4. 改历史是一张安全网commit --amend、reset、revert的边界感代码提交上去不代表不能后悔Git的灵活之处就在于提供了多层次的撤销机制。但撤销也要讲究方式方法尤其在多人协作的仓库里改历史有多爽后续同步就有多痛。4.1 commit --amend到底能干什么git commit --amend最常见的用法是提交完发现漏掉了一个文件或者提交信息写错了想在不新增一条提交记录的前提下修正。漏文件场景的处理git add 漏掉的文件 git commit --amend --no-edit--no-edit表示沿用原来的提交信息不额外弹编辑器。如果还想顺便改提交信息把--no-edit去掉即可。但这里要敲个黑板commit --amend的本质是把当前提交替换成新的提交对象所以提交的哈希值会变。如果这个提交已经被推到了远程而且远程分支上已经有别人基于它继续开发了你amend之后直接git push会被拒绝。解决办法是git push --force-with-lease但强推属于高危操作必须确认这个分支只有你自己在用。我的经验是commit --amend只适合处理还没推到远程的提交一旦push出去尽量不要通过amend去改历史而是用一次新的提交来修正。4.2 reset和revert同样是撤销方向完全不同git reset是本地仓库的时间机器它可以把当前分支的HEAD指针往回移动。硬重置git reset --hard HEAD~1会让HEAD指向上一个提交同时工作区和暂存区全部跟着回到那个时间点。命令很爽但特别危险因为你没提交过的代码改动会直接消失。软重置git reset --soft HEAD~1只移动HEAD指针工作区和暂存区的内容都保留。这种模式适合提交打散了想重组的场景。git revert则完全不同它不是让时间倒流而是生成一个新提交来反向应用某个旧提交的改动。比如你发布了一个版本老板说某个功能不要了这时候千万不能reset --hard应该用git revert commit哈希因为新提交能保留完整的推送历史别人拉取时不会因为历史被改写而跟你的仓库分叉。这条规则在多人协作分支上几乎没有例外。4.3 误操作之后怎么捞回代码实战中最惨烈的场景是git reset --hard之后发现刚刚的代码全没了脑子里一片空白。这时候不要慌Git没那么容易真正销毁数据关键看你当前的未提交改动是否曾经进入过暂存区或提交历史。如果你有提交记录但不知道在哪可以用git reflog这个命令记录的是本地HEAD指针的所有移动轨迹。哪怕你reset、checkout、merge一通乱搞只要仓库还在reflog里都能找到之前的操作记录。找到误操作前的哈希然后git reset --hard 哈希就能原样恢复。如果只是工作区里有未提交的修改被打断后错误地用了clean之类的命令那就比较棘手了。所以我的习惯是重要文件在开始大幅重构前先commit一次打一个临时存档点。宁可在历史里多一条临时提交也千万别裸奔。5. 分支和worktree多任务并行时怎么不失控分支是Git里最优雅的设计之一它让同时在两条甚至多条开发线上工作变成常态。但分支用好了是效率用不好就是灾难。5.1 分支管理的基本功新建、切换、删除最常用的一组git branch # 查看本地分支 git branch feature/login # 新建分支 git switch feature/login # 切换分支 git switch -c feature/login # 新建并切换 git branch -d feature/login # 删除已合并的分支Git 2.23之后官方推荐用git switch代替git checkout来切换分支语义更清晰也避免跟文件恢复的操作混淆。分支命名的规范性直接影响协作效率。我见过团队仓库里的分支名五花八门有叫test的、有叫aaa的、还有用自己昵称的。等过了一个月回来看谁也分不清哪个分支是干什么的。建议至少包含标识和用途比如feature/user-login、fix/payment-amount、release/v1.3.0有条件的可以加上工单号。5.2 git worktree解决什么痛点如果你的项目足够大每次切换分支都要重新构建、重新跑料缓存、重新等IDE索引这就很折磨人。更麻烦的是你在A分支上改到一半突然线上有个紧急bug必须立刻切到主分支去修。这时候工作区里的改动还没成型不想提交也不想丢怎么办传统做法是用git stash暂存一下紧急事情处理完再git stash pop。但stash多了之后很容易分不清哪一包是哪个任务的而且在大型项目上stash切换一样要重新构建。git worktree就是干这个的它允许你在同一个仓库上同时checkout多个分支到不同目录。例如git worktree add ../project-hotfix hotfix/urgent这个命令会在../project-hotfix目录下新开一个工作区里面checkout的是hotfix/urgent分支而你当前的目录里还继续保留着没改完的代码。两边互不干扰各写各的各自build各自跑。等修完bug这个worktree可以随时删除git worktree remove ../project-hotfix我特别推荐在需要同时在两个分支上长时间开发的场景里用worktree替代反复switch尤其是在前端工程、大型Java项目这类构建成本高的仓库里省下的时间非常可观。5.3 merge和rebase的取舍逻辑合并分支通常有两种姿势git merge feature/login git rebase feature/loginmerge会生成一个合并提交保留两个分支的历史分叉看起来像一张网状图。rebase则是把你当前分支的提交逐个重放到目标分支上历史变成一条直线。很多人纠结到底用哪个。我的选择标准很简单从main分支拉出feature分支开发时在feature分支里rebase main让feature的历史保持干净线性在正式合并回main时用merge保留一个清晰的合并节点。如果团队协作流程允许甚至可以要求feature分支在合并前必须先rebase到最新main这样主线的历史永远不会出现一条歪歪扭扭的线。但rebase也有个铁律不要rebase那些已经推送到公共远程分支的提交。一旦你重写了远程已有的提交哈希其他人在下次pull时就会遇到一堆莫名其妙的冲突和重复提交那种体验堪比灾难。6. 报错不可怕常见错误排查和.git目录的保护命令行工具默认不给新手面子报错信息又短又硬。但绝大多数Git报错本质上是同一个原因的不同变种。6.1 fatal: not a git repository (or any of the parent directories): .git这句报错几乎是每个Git新手都会遇到的。原因特别简单你执行git命令的当前目录根本不是Git仓库而且它的所有父目录里也找不到.git目录。我见过有人在C:\Users\用户名目录下直接敲git status然后拿着报错截图到处问的。判断方法就一条当前目录是仓库根目录或者仓库内的任意子目录。如果都不满足Git就找不到仓库元数据。解决办法要么是cd进正确的仓库目录要么用git init把当前目录变成仓库。这里有个进阶排查点如果确实在仓库目录里还报这个错通常是你设置了GIT_DIR环境变量指向了错误位置或者仓库的.git目录被误删了后一种情况如果本地没备份那就真的很难受了。6.2 命令失败先看返回码和完整提示Git的命令行提示其实比它看起来更有用。比如你push时报错会提示failed to push some refs下面跟着建议你git pull。很多人这时候直接就pull然后陷入pull冲突、解决冲突、再push又冲突的循环。实际上应该先看完整提示的前几行它会告诉你具体是哪个ref被拒绝了原因通常是远程分支比本地多了几个提交。还有一种常见报错是fatal: refusing to merge unrelated histories一般出现在两个没有共同祖先的仓库强行合并时比如分别用git init创建然后又各自提交了互不相关的历史再试图pull。解决办法是在pull时加上git pull origin main --allow-unrelated-histories但请记住这不是万能钥匙它只是允许Git把两条不相关的历史强行拼在一起代码层面是否有冲突还得自己面对。6.3 .git目录泄露一个平时没人注意但出事就麻烦的安全问题从相关搜索词里看到git目录泄露如何下载这个问题我得说两句。.git目录里存放着仓库几乎所有的元数据提交历史、所有分支、标签、配置甚至可能包含你无意中提交进去的敏感信息比如数据库密码、密钥文件、内网地址。如果这个目录被部署到Web服务器上而且服务器配置允许直接访问以.开头的文件那任何人都有可能通过浏览器直接下载.git目录里的文件进而还原你的整个源码。防御思路其实不复杂首先部署到Web服务器的目录不要包含.git文件夹常见的做法是发布时排除隐藏文件或者干脆用CI/CD构建产物来部署其次服务器配置里要禁止访问点开头的文件location ~ /\.git { deny all; }另外项目根目录的.gitignore一定要从一开始就维护好把*.env、config/secret.yml这类敏感文件提前排除掉别抱侥幸心理。我在实际项目里见过有人把.env文件提交进仓库然后又从仓库里删掉的但哈希历史里还留有记录这种情况只要别人翻一下历史就能拿到凭据。补救方法是清理历史并强制推送但最省心的还是从源头就别放进去。Git这东西初学时觉得命令多、概念抽象但真正常用的就那几张牌看状态、加暂存、提交、拉取、推送、开分支、合并、看历史。把这几个操作在命令行里敲到形成肌肉记忆再去看任何图形界面工具都等于白送。难的地方在于想让操作不出错靠的其实是对为什么这么设计的理解。仓库结构、提交对象、分支指针、远程跟踪这些基本概念想通了报错信息就不再是吓人的天书而是帮你定位问题的线索。