
1. 环境准备花15分钟把Git装好并跑通先说清楚Git是什么。它是一个分布式版本控制系统通俗点讲就是用来记录你项目文件每一次改动的“后悔药生成器”。写代码写崩了、改配置文件改坏了、想回退到三天前的某个状态Git都能帮你做到。新手学Git最容易卡住的往往不是命令本身而是第一关——“安装和配置”。这一关过了后面的操作基本就是复制粘贴加理解。我自己带过不少新人发现一个很有意思的规律凡是觉得Git难学的人80%都是因为最初环境没装对、配置没设置好导致后面每一条命令都在报错久而久之就对Git产生了恐惧。所以这篇文章我特意把“安装与基础配置”放在最前面花大篇幅讲透目的就是让你一次性把地基打牢。1.1 各平台安装方式速查Windows平台最主流的方式是安装Git for Windows也就是大家常说的Git Bash。直接去Git官网下载选择对应系统版本的安装包双击安装即可。安装过程中有几个选项需要留意安装路径建议保持默认不要带中文和空格。在选择“Adjusting your PATH environment”这一步务必选第二项“Git from the command line and also from 3rd-party software”。这样可以让Git命令在CMD和PowerShell里也能直接用而不仅限于Git Bash。换行符转换那步新手直接选默认的“Checkout Windows-style, commit Unix-style line endings”就行这个主要是解决Windows和Linux换行符不一致的问题默认选项在大多数团队协作场景下都没问题。安装完成后在桌面空白处右键如果看到“Git Bash Here”这个选项说明安装成功。Mac平台Mac用户最简单的方式是安装Xcode Command Line Tools它会顺带安装Git。如果你已经装了Homebrew也可以直接运行brew install git这种方式的好处是能装到比较新的版本而且后续升级方便。Linux平台Debian/Ubuntu系列运行sudo apt install gitCentOS/RHEL系列运行sudo yum install gitFedora用sudo dnf install git。装完以后运行git --version验证一下。1.2 安装验证与环境变量安装完以后打开终端Windows用户打开Git Bash输入下面这行命令git --version如果能看到类似git version 2.40.1.windows.1这样的输出说明安装成功。这里有一个新手容易遇到的经典报错在CMD或PowerShell里输入git提示“git 不是内部或外部命令也不是可运行的程序或批处理文件”。这个报错几乎可以断定是环境变量没有配好。排查思路很简单找到Git的安装目录一般是C:\Program Files\Git\cmd把这个路径加到系统环境变量的Path里然后重新打开一个终端窗口即可。注意修改完环境变量后一定要把之前开着的所有终端窗口全部关掉重开否则系统不会重新加载新的环境变量这也是很多人改了环境变量却依然报错的原因。1.3 Git Bash到底是什么为什么推荐新手用它Git Bash本质上是一个模拟Linux终端环境的程序它把Git所需的Unix工具集合到了一个窗口里。新手用它有几个好处路径分隔符是正斜杠/而不是Windows的反斜杠\这让Git命令的写法更统一支持ls、cd、pwd这些Unix命令网上绝大多数Git教程里的命令复制过来就能直接跑而且它自带的终端配色和提示符也比Windows原生的CMD更清晰。我现在的工作习惯是运维和执行Git命令用Git Bash日常编辑文件用VS Code。这个组合对新手来说是比较顺手的。等你慢慢熟悉了再迁移到任何终端工具都不会有障碍因为Git的核心命令在所有平台上都是完全一致的。2. 三个必配项用户名、邮箱、换行符规则安装只是第一步真正决定你提交记录是否“干净”、能否顺利推送到远程仓库的是安装后的个人配置。这一步很多人嫌麻烦直接跳过结果后面每次提交都要手动指定身份信息或者推送时反复提示权限错误反而浪费了更多时间。2.1 设置身份信息Git的每一次提交都会记录两样东西一个名字和一个邮箱。这个信息是跟着提交记录走的不是你登录远程仓库的账号密码。设置命令如下git config --global user.name 你的名字 git config --global user.email 你的邮箱加--global参数表示这台机器上所有仓库都用这个身份。不加的话就只对当前所在的仓库生效。如果你有多个Git平台账号比如一个Gitee一个GitLab建议在各自的项目仓库里单独设置仓库级别的身份避免身份混淆。验证配置是否生效运行git config --global --list2.2 为什么不设置身份就提交不了很多新手第一次执行git commit时会遇到一个非常诡异的提示Please tell me who you are.这是Git在明确告诉你我不知道你是谁请你先设置用户名和邮箱。Git的设计哲学是提交记录必须能追溯到人这样在团队协作中才能知道每一行代码是谁改的、为什么改。所以这一步是强制性的没有身份信息提交命令会被直接拒绝执行。2.3 换行符与文件编码的坑跨平台协作时换行符是最大的隐性坑。Windows系统默认使用CRLF回车换行作为行尾而Linux和Mac使用LF换行。如果不同平台的成员各自提交Git会认为整个文件都发生了改动导致git diff显示出一大堆无关的变化极大地干扰代码审查。Git通过core.autocrlf这个配置来自动处理转换。Windows用户建议设置git config --global core.autocrlf true这样Git在检出代码时会把LF自动转换为CRLF在提交时又把CRLF转换回LF。团队中只要统一了提交规范跨平台的换行符问题就能基本解决。另外建议所有的代码文件统一使用UTF-8编码避免因为编码不一致导致中文注释显示乱码。Windows记事本保存文件时默认带BOM的编码方式也容易引发问题建议配合VS Code等编辑器将文件编码统一设为“UTF-8无BOM”。3. 本地仓库实操从初始化到第一次提交配置完成以后就可以真正开始用Git了。这一节我会完整走一遍本地仓库的“生命周期”从新建文件夹到文件提交再到查看历史记录。这是日常使用频率最高的一套流程建议你跟着敲一遍。3.1 初始化仓库先在本地创建一个项目文件夹然后进入这个目录执行git init这条命令会创建一个隐藏的.git目录这个目录就是Git用来存储所有版本信息的地方。执行完以后你就拥有了一个“活”的Git仓库。注意.git目录是Git的大脑不要手动修改或删除里面的任何文件。很多人不知道这一点把.git删了以为只是删了个隐藏文件夹实际上等于把整个版本历史全部销毁了。3.2 到底什么是工作区、暂存区、版本库初学者学Git最怕的就是看到“暂存区staging area”这个词。我用一个生活化的例子来解释。把Git仓库想象成一个餐厅厨房。你的工作区就是切菜台你在这里处理食材创建、修改文件。暂存区是备餐盘你把切好的菜放进备餐盘git add表示这些菜准备下锅。版本库是冰箱你把备餐盘里的菜放进冰箱保存git commit表示这个状态被正式记录下来了。为什么要多一个暂存区的概念因为现实中我们往往不是把所有的改动一次性地提交。可能这个文件修好了要先记一笔那个文件还在改先不着急。暂存区给了我们选择“哪些改动进入本次提交”的灵活性。3.3 添加与提交的完整流程先创建几个文件比如echo hello git readme.md然后用git status查看当前仓库状态git status此时文件处于“Untracked”状态意思是Git还没有跟踪它。接下来把它添加到暂存区git add readme.md再一次运行git status文件状态会变成“Changes to be committed”说明它已经被放进备餐盘了。接着执行提交git commit -m 初始化项目添加readme文件-m后面的内容就是提交信息。提交信息虽然只是一个简短描述但它是团队协作中别人理解你改了什么的关键渠道。我的建议是提交信息要遵循“动词做了什么”的格式比如“修复登录接口报错”、“优化首页加载速度”而不是“修改了一些问题”这种毫无信息量的描述。查看提交历史git log你会看到这次提交的哈希值、作者、日期和提交信息。哈希值是一个40位的十六进制字符串是Git给每次提交生成的唯一ID相当于冰箱里那盘菜的唯一编号。3.4 提交信息的规范写法与修改技巧提交信息的规范性在团队协作的初期可能看不出差别一旦项目迭代到上百个提交规范的提交信息就是救命的排查线索。我习惯把提交类型作为前缀常见的有feat新增功能fix修复Bugdocs只改了文档style格式调整不影响代码逻辑refactor重构既有功能没有被修改比如feat: 添加用户注册页面、fix: 修复密码重置接口500错误。如果你提交完以后发现自己手滑写错了信息不用慌。还没有推送到远程仓库的情况下用下面这条命令修改最近一次的提交信息git commit --amend -m 新的提交信息--amend的作用就是“后悔了重新编辑一下最近一次提交”。它不只是改文字还会生成一个新的提交哈希。如果这个提交已经推送到远程仓库了--amend会导致本地和远程历史不一致推送时会被拒绝这时候就需要强制推送来解决但强制推送在团队协作中是比较危险的操作可能覆盖队友的提交。所以我的建议是--amend只在提交还没有推送的时候使用。4. 远程仓库打通克隆、推送、拉取和SSH配置本地仓库能让你自己愉快地写代码但在真实工作和开源项目中几乎一定是多人协作代码要么存放在Gitee、GitHub这类代码托管平台要么存放在公司内部的GitLab服务器上。把本地仓库和远程仓库连接起来是新手从“一个人玩”走向“一群人协作”的关键一步。4.1 HTTPS方式克隆远程仓库克隆就是把远程仓库的完整代码和历史记录复制到本地。几乎所有代码托管平台都支持HTTPS和SSH两种协议新手最省事的起步方式是直接使用HTTPSgit clone https://gitee.com/用户名/仓库名.git执行完以后当前目录下会出现一个和仓库名同名的文件夹直接进入这个文件夹就可以开始操作了。HTTPS方式的优点是配置为零缺点是每次推送和拉取都需要输入账号密码在部分平台上密码需要配置个人访问令牌Personal Access Token单纯的登录密码已经不能用了。还有一种情况是远程仓库在某个时刻之后新增了提交你想把这些新内容同步到本地。这时候用git pull4.2 SSH密钥配置一次配置长期免密如果你觉得每次输入密码很麻烦推荐直接配置SSH免密登录。SSH密钥的原理可以理解为一对钥匙和锁你的电脑生成一把私钥自己留着和一把公钥放到代码托管平台上平台验证的时候只要私钥能匹配上公钥就确认了你的身份不需要再输密码。生成密钥对ssh-keygen -t rsa -b 4096 -C 你的邮箱命令执行后会提示保存路径和设置密码短语直接连续回车使用默认配置即可设置密码短语是额外的安全措施但会增加每次使用时的交互成本个人项目通常不需要。生成的密钥默认在用户主目录下的.ssh文件夹里。id_rsa.pub是公钥id_rsa是私钥。用记事本打开id_rsa.pub复制里面的全部内容。然后登录你的代码托管平台找到“个人设置”或“SSH公钥”菜单把复制的内容粘贴进去保存。验证配置是否成功ssh -T gitgitee.com如果提示“Hi 用户名! Youve successfully authenticated”说明SSH配置成功了。配置好以后在克隆仓库时选择SSH地址形如gitgitee.com:用户名/仓库名.git就能免密推送拉取了。注意私钥文件id_rsa绝对不能泄露给任何人公钥可以随便公开。私钥一旦泄露别人就可以冒充你的身份操作远程代码仓库。如果怀疑私钥泄露应该立即在本地重新生成密钥对并在代码托管平台上删除旧的公钥。4.3 本地项目推到远程空仓库有时候你本地已经有一个项目想把它推到远程新创建的仓库里。先在你选择的代码托管平台上创建一个空仓库注意不要勾选“初始化仓库”相关的选项比如自动生成README文件保持完全为空。然后在本地项目目录下添加远程地址git remote add origin gitgitee.com:用户名/仓库名.gitorigin是远程仓库的默认别名这是Git社区约定俗成的叫法意思就是“主要远程仓库”。推送前先确认本地有提交记录然后执行git branch -M main git push -u origin main-M main是把当前分支重命名为main与远程仓库默认分支保持一致。-u参数建立本地分支与远程分支的跟踪关系这样以后的git push和git pull就不需要再指定远程仓库和分支名了。如果推送时遇到类似fatal: refusing to merge unrelated histories的报错通常是因为本地仓库和远程仓库都有各自独立的初始化提交。需要合并两个仓库的历史时可以拉取时加上允许无关联历史的参数git pull origin main --allow-unrelated-histories这个参数的意思是允许两个没有共同祖先的仓库进行合并。合并完以后再次推送即可。4.4 远程仓库的查看与管理查看当前项目关联的远程仓库git remote -v这里的-v参数会显示远程地址的完整形式方便你确认当前用的是HTTPS还是SSH协议。如果要删除某个远程地址用git remote remove origin再重新添加。5. 分支管理并行开发的基石分支是Git最强大的功能也是新手从“会用”走向“会用得优雅”的分水岭。简单来说分支让你能够从主线上“岔”出一条独立的开发线在这条线上改代码、提交完全不干扰主线的稳定性。等你的改动稳定了再把这条开发线“合并”回主线。5.1 为什么需要分支一个真实的翻车现场我刚带团队那会儿有个新来的同事直接在主分支上开发新功能结果功能写到一半线上有个紧急Bug需要立刻修复。主分支上躺着他写到一半的半成品代码谁都不敢动因为一提交Bug修复就会把半成品也一起带上线。这就是没有分支的代价。如果当时他遵守分支规范从主分支拉一条feature/xxx开发分支主分支始终保持可发布状态修复线上Bug就是几分钟的事。分支的意义就是为了隔离“不稳定”和“稳定”让多线程的开发任务互不干扰。5.2 创建合并分支的完整操作查看当前在哪个分支git branch创建一个新分支并切换到它git checkout -b feature/new-page这条命令相当于连做两步git branch feature/new-page加git checkout feature/new-page。-b参数就是“branch”的意思。在这个新分支上修改代码、提交然后切回主分支git checkout main此时你在新分支上做的所有提交在主分支上都是看不到的。隔离的效果就验证了。接下来把新分支合并到主分支git merge feature/new-page合并完成后可以放心地删除已经合并过的分支git branch -d feature/new-page5.3 合并冲突的产生与解决办法合并冲突是多分支协作中最常见也最头疼的问题。它发生的场景是两个分支都修改了同一个文件同一行内容Git不知道该听谁的只能把决定权交给人工处理。实际开发中常见的原因是一个人在主分支上修改了某个接口的返回字段另一个人在功能分支上也修改了同一个字段合并时就会冲突。遇到冲突时Git会在冲突文件里插入标记 HEAD 你当前分支的代码 被合并分支的代码 feature/new-page中间的是分界线上半部分是当前分支的内容下半部分是外来分支的内容。手动删除不需要的部分保留正确的代码删除三行标记然后重新执行git add 冲突文件 git commit -m 解决合并冲突这里有一个经验合并冲突尽量在本地解决不要带着冲突去提交否则会把中间状态带入历史记录。解决完成后务必运行一遍相关的测试用例确保合并后的代码逻辑没有因为冲突解决而产生新的问题。6. 工作区操作核心撤销、回退、暂存改动Git之所以让人安心很大程度上是因为它几乎所有操作都可逆。重点讲几个日常开发中最高频的“后悔药”操作。6.1 文件改坏了如何撤回工作区修改文件被修改后还没有执行git add想恢复到最近一次提交时的状态git checkout -- 文件名这条命令会用版本库里的版本覆盖工作区的改动。注意它撤销的是“工作区的未暂存修改”一旦用了这个命令那些改动就彻底没了如果你改了半天发现撤销错了是找不回来的。在执行前可以用git diff确认一下当前到底改了哪些内容。6.2 已经add了想撤销暂存文件已经被git add放进了暂存区但你想把它退回工作区文件内容保留只是取消暂存git reset HEAD 文件名这个操作很安全它只是把文件从暂存区移出来不会动文件内容。6.3 提交记录能回退吗如果你想回退到之前的某个提交有两个工具git reset和git revert它们的使用场景完全不同。git reset是“时光倒流”它会移动当前分支的指针让提交历史直接指向过去的某个节点。它有一个危险的地方如果这个提交已经推送到远程仓库且别人已经基于这个提交做了开发你本地reset以后想强制推送会直接导致远程历史被改写其他人的本地仓库会变得非常混乱。所以git reset只适用于提交从未推送出去的场景。git revert是“生成一个反向提交”。它会创建一个新的提交内容恰好是撤销目标提交的改动。历史的每个节点都完整保留不会改写任何历史。它的好处是安全适用于所有场景包括已经推送的提交。团队协作遇到需要撤销某次提交时我应该会优先考虑git revert。6.4 改到一半想切换分支用stash暂时封存你正在feature/a分支上改代码改到一半突然需要去main分支修复一个紧急问题。此时切换分支Git可能会报错因为工作区的未提交改动会在分支切换时产生冲突。解决办法是把当前改动临时藏起来git stash这个命令会把未提交的改动保存到一个独立区域让工作区变得干净。处理完紧急问题后回到这个分支再执行git stash pop改动会原封不动地回到工作区。查看当前有多少条暂存的改动用git stash list。如果有多条stashpop时可能遇到冲突手动解决后继续即可。7. 图形化工具与常用命令速查虽然命令行的Git已经能完成所有操作但很多场景下图形化工具能让你对仓库状态有更直观的把握。7.1 TortoiseGit小乌龟Windows右键操作TortoiseGit是Windows平台老牌的图形化Git客户端最核心的卖点是与资源管理器深度集成——在文件夹上右键就能直接看到提交、拉取、推送、日志等操作。它的安装逻辑比较特殊先装Git for Windows再装TortoiseGit最后装对应的中文语言包。装完以后在文件夹里右键“TortoiseGit”子菜单下就能看到所有常用操作。版本库的“日志”视图会以图形化方式展示分支、合并、提交节点对理解Git历史非常有帮助。7.2 VS Code内置版本控制VS Code内置了Git支持左侧的源代码管理图标会显示当前仓库改动了哪些文件。每次修改文件后它可以分文件查看差异在输入框里写上提交信息点“提交”再点“同步更改”操作的流畅度很高。对新手友好的一点是VS Code会在文件列表中明确标注增删改的行数提交前给你足够的确认空间。7.3 高频命令速查表操作场景命令查看仓库状态git status查看文件改动详情git diff添加文件到暂存区git add 文件名添加所有改动git add .提交所有已暂存改动git commit -m 说明推送本地提交到远程git push拉取远程更新git pull查看提交历史git log --oneline查看某个文件历史git log --oneline -- 文件名切换分支git checkout 分支名临时保存改动git stash恢复临时保存的改动git stash pop速查表不需要死记硬背用多了自然就形成了肌肉记忆。8. 疑难杂症排查与避坑技巧git命令本身不复杂复杂的是报错信息。作为新手报错不要慌把报错信息完整地复制下来去搜索往往比自己瞎猜效率高得多。我整理了几个出现频率最高的报错场景。8.1 fatal: not a git repository这个报错的意思是“当前目录不是一个Git仓库”。新手最容易遇到的情况是在项目的子文件夹里执行Git命令但这个项目本身还没有git init初始化或者你进入了一个普通文件夹以为它是仓库但其实只是远程仓库克隆后的某个子目录外层的普通文件夹。排查思路先在根目录确认有没有隐藏的.git文件夹存在。另外在克隆项目的时候请把克隆操作指向仓库的根目录不要在项目子文件夹里克隆否则会出现仓库嵌套仓库的混乱情况。8.2 GitHub / Gitee 推送时提示认证失败比如上面搜到的login failed. check api token or gitlab version. log in via git这类问题在GitLab、Gitee等平台都会出现。常见原因有三个账号密码输错了平台已经不支持用登录密码直接推送需要改用个人访问令牌你用的是旧版Git与服务端的认证机制不兼容。处理方式很简单如果用的是HTTPS地址优先保证账号密码正确并确认你是否为这个平台开启了双因素认证。开启了的话必须用Token而不是密码。如果用的是SSH地址确认密钥已经放到平台上并且本地仓库的远程地址确实用的SSH协议而不是混搭了HTTPS。8.3 推送被拒绝non-fast-forward这个报错通常发生在多人协作时你本地没有拉到最新的远程提交就想推送但远程仓库已经有了别人提交的新内容Git为了安全起见直接拒绝你的推送。解决办法先执行git pull拉取远程更新把别人的改动合并到本地解决可能的冲突然后再推送。记住一条铁律推送之前先拉取尤其是协作项目养成这个习惯能省掉90%的推送纠纷。8.4 误把敏感文件提交进仓库怎么办这是我在实际工作中见过最严重的事故之一。比如把数据库密码、密钥文件不小心提交到了Git仓库哪怕之后立刻删除了文件并提交它依然存在于历史记录中只要仓库被克隆过信息就已经泄露了。处理办法分两步第一步立即重置泄露的密码或密钥这一点是最重要的第二步清理仓库历史。如果是私有仓库可以考虑直接用git filter-repo清理版本历史但操作复杂且有改写历史的风险如果是团队协作项目一定要先和所有人沟通好统一操作流程。更根本的预防手段是写一个.gitignore文件把敏感文件、编译产物、环境配置等通通排除在版本控制之外。.gitignore示例# 环境配置文件 .env config.local.js # 依赖目录 node_modules/ vendor/ # 编译输出 dist/ build/ # IDE相关 .idea/ .vscode/ *.iml # 系统文件 .DS_Store Thumbs.db把.gitignore放在项目根目录即可。注意.gitignore只对尚未被跟踪的文件生效如果文件已经被提交过光加.gitignore是没用的需要先用git rm --cached把文件从跟踪列表里移除。9. 日常协作的高效小习惯最后分享几个我在多年实践中沉淀下来的习惯这些不属于任何一条具体命令但对团队协作效率的影响非常大。先看分支命名。分支名本身就是团队交流的一部分晦涩的分支名会让同事在合并时一头雾水。我建议分支名带上功能描述和作者标识比如feature/user-login-张三、fix/payment-bug-李四这样一看就知道这是谁在干什么。再看提交节奏。提交不是越少越好也不是越频繁越好。我的习惯是“一个逻辑变更一次提交”。比如今天你改了登录页的样式、修了一个接口报错、调整了一份文档这三个改动属于三个逻辑单元应该分三次提交。这样在回溯问题时git log能在第一时间定位到具体哪一行改动引发的Bug而不是把所有变更混在一起无从下手。最后是拉取策略。每天早上开工前第一件事先执行一遍git pull把队友昨天的改动同步到本地这是防止一天工作结束时推送冲突最简单的手段。下午休息回来再拉一次就更好。看似频繁的拉取并不会带来多少额外成本却能让你始终基于最新代码开发避免自己在一个过时的分支上白费力气。我在实际带新人的过程中发现Git真正难住人的地方从来不是命令本身而是对“状态”的理解。每一次执行命令前先停下来想一想现在文件处于什么状态我执行的命令会把文件移动到哪个状态一旦你建立了这种状态机的思维方式所有Git报错在你眼里都会变得清晰得多——你看见的不再是一堆恐怖的英文报错而是“当前状态和期望状态不匹配”的一个明确信号。