Git基础教程:从安装配置到分支协作一次搞懂

Git基础教程:从安装配置到分支协作一次搞懂 做开发这些年Git是我几乎每天都在用的工具但坦白讲身边很多朋友并不是第一天就真正理解了它。他们往往靠“死记硬背”记住那几条常用命令遇到分支冲突、历史回退、协作报错时就开始懵。这篇博客就带你系统过一遍Git基础——从安装、配置到常用命令、分支协作把那些“知其然不知其所以然”的地方一次讲透。内容基于我自己的实践来写没有复杂的废话每一步都可以照着敲也补充了很多我在教团队新人时反复强调的细节和踩过的坑。不管你是刚入门的学生、准备转行开发的自学者还是用了一段时间Git但心里没底的初级工程师这篇文章都适合你慢慢看完。git安装及配置教程这块我会把Windows环境作为主线路来讲其它系统也会简单带过。1. 为什么每个开发者都该认真学Git1.1 版本控制到底解决了什么问题先聊一个特别直观的场景。你有没有写过这样的文件“项目最终稿.doc”“项目最终稿_改3.doc”“项目最终稿_最终版_绝对不改了.doc”。如果是代码情况更糟——一个文件里被注释掉的旧代码一堆删了怕后悔留着又碍眼。版本控制就是为了根治这个乱象。Git能记录项目每一次“存档”的状态你想回到哪一次就回到哪一次想对比任意两次的区别也可以。再直白一点Git给你的项目装了一台“时间机器”你做过的每一个有意义的状态更新都会有迹可循。团队协作里这个需求更刚性。没有版本控制的时候两个人同时改一个文件后保存的人会直接把前一个人的成果覆盖掉。有了Git每个人在自己本地改最后合并时再协调谁改了哪一行都有据可查。更关键的是合并冲突虽然烦人但它至少把问题摆到了明面上而不是让某个人悄悄丢失半天工作量。就冲这一点Git就是团队的刚需。另外说个背景。Git是Linus Torvalds在2005年为Linux内核开发设计的工具他当时的诉求是分布式、高性能、能支撑Linux这种超大规模项目的协同。后来的事大家都知道了Git一路赢过了SVN、CVS这些老牌集中式版本控制工具今天已经成了全球开发者的默认选择。1.2 Git与SVN的本质区别分布式和快照很多人用Git时脑子还停留在SVN的思维上这会导致理解别扭。SVN是集中式的服务器有一份完整的代码库每个人改完直接提交到服务器你的本地只有当前工作的一份文件。Git不一样它是分布式的——你克隆下来的仓库本地就有一份完整的全部历史不联网也能提交、查日志、建分支。还有一个更底层的区别Git存的是快照snapshot不是差异diff。SVN记录的是“这个文件相对上一个版本改了哪些行”而Git每次提交保存的是所有文件的一个完整快照。听起来Git会更占空间实际上它通过对象压缩和只存变化的部分做了优化并不会浪费太多空间但换来了一个巨大的好处切换分支、回退历史都非常快因为Git面对的是一个个完整的快照而不是按顺序重放补丁。理解了这两点再去看Git的工作流程会顺畅很多。Git把本地仓库分成了三个区域工作区你正在编辑的目录、暂存区你准备好的变更集合、版本库已经提交的历史快照。日常操作本质上就是在三个区域之间搬运内容。2. 环境准备从零装好Git开发环境2.1 Windows下安装Git的完整步骤很多新手卡在第一步——不知道该去哪下载、安装时那么多选项选哪个。先说下载直接去Git官网git-scm.com下载对应Windows 64位的安装包就行。下载完成后双击安装包大部分选项保持默认即可但有几个地方值得留意一下。第一个是“Select Components”这步默认会勾选“Git Bash Here”和“Git GUI Here”建议保留后面用右键菜单快速打开Git Bash很顺手。第二个是“Choosing the default editor for Git”这里会选Git默认调用的文本编辑器。我以前习惯选Vim但对不熟悉Vim的朋友来说一旦不小心进到Vim界面就会手足无措。建议直接选Notepad或VS Code你在“Adjusting your PATH environment”这一步选择默认的“Git from the command line and also from 3rd-party software”就行这个选项会帮你在命令提示符里也注册好git命令。遇到“Configuring the line ending conversions”这步保持默认的“Checkout Windows-style, commit Unix-style line endings”就好这个设置会让Windows和Linux/macOS协作时尽量少出现换行符问题。安装完成后验证是否成功。打开命令提示符WinR输入cmd回车或者右键选择Git Bash Here输入git --version能看到类似git version 2.40.0.windows.1的输出就说明环境已经装好了。有一点我踩过坑提醒你安装路径最好不要带中文和空格有些老项目里的构建脚本对路径敏感路径有问题会报一堆奇怪的错。2.2 全局配置告诉Git你是谁Git装好以后第一件事是配置你的身份信息。你每次提交代码Git都会把提交者的名字和邮箱写进历史记录里所以这一步绕不开。打开命令行执行git config --global user.name 你的名字 git config --global user.email 你的邮箱这里有个细节邮箱不一定非得是真实邮箱但建议用你经常收邮件、并且能认领到代码平台的邮箱比如在Gitee或GitHub上注册用的邮箱。因为很多代码托管平台会通过邮箱把提交记录关联到你的账号上这样你的提交会显示成你的头像而不是一个无名者。配置完以后可以用下面的命令确认git config --list它会列出当前生效的所有配置项包括你刚设置的名字和邮箱。如果哪天想修改重新执行一次上面的命令就行。--global这个参数的意思是“对当前电脑上的所有项目都生效”如果你只在某个仓库里用不同的身份可以在那个仓库目录下去掉--global单独设置。2.3 SSH密钥避免每次推送都输密码如果你平时要跟远程仓库Gitee、GitHub等打交道建议配置SSH密钥。这样你pull、push代码的时候就不用反复输账号密码了。步骤很简单打开Git Bash执行ssh-keygen -t ed25519 -C 你的邮箱之后会问你要把密钥文件保存在哪直接回车用默认路径就行。然后会问你是否设置passphrase密钥口令这个看你自己我建议本地个人电脑不设口令方便日常操作公司电脑或者安全性要求高就设一个。生成完成后找到公钥文件~/.ssh/id_ed25519.pub用记事本打开复制里面的全部内容。接着登录你的代码托管平台以Gitee为例找到“设置 - SSH公钥”页面把复制的内容粘贴进去保存。验证是否配置成功ssh -T gitgitee.com第一次连接会询问是否确认主机指纹输入yes回车如果看到“Hixxx! Youve successfully authenticated”字样就说明SSH连接已经通了。这一步配置好之后远程协作的体验会顺畅很多不用每敲一次push都摸一遍密码。macOS和Linux下安装Git也顺手提一下。macOS装了Homebrew的话brew install git一行搞定Ubuntu/Debian系用sudo apt install gitCentOS/RHEL系用sudo yum install git。后面的全局配置完全一致。3. 核心基础命令把这套组合拳练熟3.1 git init 与 git status一个仓库的诞生所有Git项目都是从初始化仓库开始的。我在D盘建一个测试目录mkdir git-demo cd git-demo git init执行完git init后Git会在当前目录下生成一个隐藏的.git文件夹这个文件夹就是Git的“数据库”项目所有版本历史、分支、配置都存在这里面。你会发现在这个目录里敲ls -a才能看到它平时正常浏览目录时它不会碍事。这时候再执行git status不出意外会提示你“On branch master”或者“On branch main”并且说“No commits yet”——仓库是空的还没有任何提交。注意看Git还贴心地把下一步该做什么都写出来了比如“nothing to commit”或“use git add ...”这样的提示。所以新手遇到不知所措的情况时多看看git status的输出它就是一个“下一步引导指南”。新建一个文本文件试试echo hello git readme.txt git status这次输出会明显不同readme.txt出现在“Untracked files”下面意思是这个文件还没被Git管理起来。Git不会自动跟踪仓库里的所有文件你必须明确告诉它“我要跟踪这个文件”它才会进入版本管理。这个设计是有意的避免把临时文件、日志文件全卷进来。3.2 git add 与 git commit提交一个快照刚才readme.txt处于未跟踪状态现在把它加到暂存区git add readme.txt git status这时候文件会出现在“Changes to be committed”下面也就是说它已经进入暂存区但还没真正成为历史记录。git add的意思是“把这次变更汇总到待提交清单里”。你可以一次性git add .把目录下所有变更都加进去但我的建议是刚开始学的时候尽量显式写文件名这样你清楚自己到底提交了什么。下一步提交git commit -m 初始化项目添加readme文件-m后面的内容是提交说明这个不是随便写的它会被永久记录在历史里将来你回看提交记录靠的就是这句说明。所以提交信息一定要写得能看懂。团队协作里常见的规范是约定前缀feat表示新功能fix表示修Bugrefactor表示重构docs表示文档变更。比如git commit -m feat: 新增用户登录接口 git commit -m fix: 修复订单列表分页异常这种格式的好处是日志一拉出来项目每个阶段的意图清清楚楚配合一些自动化工具还能自动生成变更日志。个人项目也建议养成这个习惯一个习惯带来的收益远超你想象。add和commit是一对组合拳逻辑上是“先把要提交的变更挑出来再一次性固化成一个快照”。你可以分多次add再一次性commit这样能把不同文件的变更归并到一个逻辑完整的提交里历史也更干净。3.3 git log 与 git diff看清历史与变化提交了几次以后怎么回顾历史用git loggit loggit log会显示每次提交的唯一哈希值一串很长的十六进制字符、作者、日期和提交说明。这个哈希值就是每次提交快照的“身份证号”后续回退、对比、切换都要用到它。觉得输出太长的可以用git log --oneline每条记录压缩成一行只显示短哈希和提交说明日常查看历史用这个就够了。那想看某个文件具体改了什么呢用git diff。比如我修改了readme.txt还没add和commit这时候执行git diff readme.txt输出会显示删除行前加-和新增行前加非常直观。如果你想看已经暂存了的变更和上次提交之间的区别用git diff --staged这两个diff命令配合git status基本上能让你随时掌握仓库里“谁变了、变了什么、要不要提交”。我个人的习惯是每次提交前先git status看有哪些变更再git diff确认内容没问题最后才add和commit。这套流程多走几次就会形成肌肉记忆很少会出错。4. 分支管理Git最值钱的设计4.1 分支的本质一个可以移动的指针如果说Git只有一个概念值得你花时间搞懂那一定是分支。很多人被分支吓住但它没那么玄乎。简单说分支就是Git仓库里的一条独立的开发主线它本质上是一个指向某次提交的指针。你可以在一条分支上开发新功能完全不影响主线。创建一个新分支并切换过去git branch feature-login git checkout feature-login上面的写法每次要敲两行我更喜欢新版Git提供的快捷命令git switch -c feature-login-c的意思是“create”即创建并切换。老版本Git没有switch命令如果你用的版本不支持就用老命令。切换到新分支后再做几次修改和提交然后用git log --oneline --all --graph看一下你会发现主分支master或main停留在原地而feature-login分支在这个基础上继续向前走。有个点我必须强调分支切换时工作区的文件内容会跟着变。Git会把你当前的工作区恢复成目标分支最后一次提交时的模样。所以如果你正在某个分支上改了东西但还没提交直接切分支往往会被Git拦下来提示你有未提交的变更。这时候要么先提交要么用后面会讲到的git stash把变更暂存起来。分支之间互不影响这是团队并行开发的核心。一个人在主分支上修Bug另一个人在新功能分支上开发新模块大家各自提交最后再把功能分支合并回主线。没有分支团队就只能排队干活效率完全不是一个量级。4.2 合并分支与解决冲突实操中的必修课功能做完了要把分支合回去。切回主分支然后执行mergegit switch master git merge feature-login如果主分支在分叉期间没有新的提交Git会走一次“快进合并”Fast-forward就是直接把主分支的指针移到feature-login所指向的提交上干净利落。但更常见的情况是主分支在被分出去之后也有了新的提交。比如修复了一个紧急Bug并提交了这时候合并是两个分支从分叉点分别演进的“三方合并”。Git会把两个分支的更改同时应用到一个新提交上。如果两边改的是完全不同的文件合并很顺利Git自动完成然后弹出一个提交信息编辑界面你保存退出即可。真正让人头疼的是冲突。当两个分支修改了同一个文件的同一段代码时Git无法替你做选择——谁知道你要哪个版本呢这时候Git会在冲突文件里标注出两个版本的内容你用编辑器打开会看到类似这样的结构 HEAD 当前分支的代码 feature分支的代码 feature-login HEAD到之间的内容是你当前分支上的版本到 feature-login之间是合并进来的分支的版本。手动决定保留哪个、删除哪个、或者两个都改改然后保存文件接着git add 冲突文件名 git commit -m 合并feature-login分支并解决冲突这里我要给一个关键建议解决冲突时不要只顾着看本地文件的冲突标记然后瞎删。一定要搞清楚两边代码各自的业务逻辑最好是让熟悉这段代码的人一起确认。我曾经在一次合并里想当然地选择了自己分支的版本结果把同事已经修复好的一个问题又带回去了上线后被用户反馈后才追悔莫及。Git的merge只负责合并不负责判断谁的代码是对的上线逻辑这个判断只能靠人来做。如果合并到一半你发现不对劲想退回去重新来可以用git merge --abort它会放弃这次合并让仓库回到合并前的状态。这个命令是新手的好朋友遇到合并混乱不知道该怎么办时先撤回去理清楚再继续。5. 远程协作把本地仓库推到远端5.1 连接远程仓库clone 与 remote前面讲的所有操作都发生在本地。但真实的工作流一定离不开远程仓库不管是用Gitee、GitHub还是公司内部的GitLab。远程仓库是你的项目在服务器上的一个备份和协作中枢组员之间通过它交换代码。有两种方式开始远程协作。第一种是你参加一个已有项目直接克隆git clone gitgitee.com:some/project.git这个命令会把远程仓库的完整历史全部拉到本地并自动帮你设置好名为origin的远程仓库地址。克隆完以后你的本地仓库和远程仓库就建立起了联系。第二种是你本地已经有一个仓库想推送到远端。先在代码托管平台上创建一个空仓库不要勾选“初始化README”然后把远程地址关联到本地git remote add origin gitgitee.com:your-name/project.git这条命令的意思是“给远程仓库地址起个别名叫origin”origin只是约定俗成的名字原则上你可以叫别的但大家一看origin就知道这是主仓库地址。关联好以后执行git push -u origin master这里解释一下-u的作用。它会把你本地的master分支和远程的master分支“绑定”起来绑定之后以后再执行git push或git pullGit会自动知道跟哪一个远程分支对应不用每次都写全参数。第一次推送时加上-u这个参数后面会省心很多。5.2 push、pull与fetch搞清楚方向就不乱远程协作基础操作就是三个命令push推、pull拉、fetch抓取。push很好理解把你本地的提交发送到远程仓库。pull是用远程仓库的最新提交来更新你本地。fetch和pull的区别很多人搞混fetch只会把远程的新提交下载到本地但不会动你当前工作区的代码pull则是fetch加merge两步一起做直接把远程变更合并进你当前的分支。那么执行pull时最常见的报错就是下面这个! [rejected] master - master (non-fast-forward) hint: Updates were rejected because the tip of your current branch is behind出现这个提示说明远程仓库有别人已经提交了你没有的新历史。你想把自己的提交推上去Git发现如果直接推的话会把别人的提交“顶掉”于是果断拒绝。解决办法是先拉取远程的变更合并后再推送git pull origin masterpull的过程中如果遇到冲突处理方法和merge的冲突一样解决后commit再push。如果你希望拉取远程历史时保持提交记录是一条直线不让Git自动产生一个merge提交可以用git pull --rebase origin master--rebase的含义是把你本地的提交“重新放到”远程最新提交的后面。好处是历史更干净坏处是如果你的提交和别人的提交有冲突解决起来会需要逐条处理稍微麻烦一点。我的个人建议是单人开发的分支随便用pull还是rebase大家共用的主线分支团队约定一种方式就行不要混用否则历史会乱成一团。还有一件事必须单独说永远不要对公共分支使用git push --force。force参数会强行用你本地的历史覆盖远程历史这意味着远程仓库上其他人的提交会彻底消失。如果覆盖的是你自己刚创建的个人分支问题还不大一旦覆盖的是团队主线那基本上就是事故级别的操作。我见过新手往团队公共仓库执行了force push导致同事半天的工作成果“人间蒸发”最后只能靠本地备份和运气去抢救。非要用force也要确认项目组里约定好这是个人可牺牲的分支并且大家都没有基于这个分支在开发。6. 踩坑记录与日常锦囊6.1 常见问题速查表下面汇总了一些我刚学Git时经常踩的坑做成速查表建议收藏备用。现象原因解决办法提交记录中文乱码终端编码和Git默认编码不一致设置git config --global core.quotepath false终端切到UTF-8编码每次pull都提示换行符警告Windows和Linux换行符差异在你项目的根目录添加.gitattributes统一指定换行符规则误提交了一个大文件没提前配置.gitignore用git rm --cached 文件名从版本控制中移除并加入.gitignore不小心提交了敏感信息如密码疏忽立即从提交中删除并修改密码必要时重写历史但公共分支要谨慎想撤销上一次提交提交信息写错了用git commit --amend重新提交会覆盖上一次提交信息想把某个文件恢复到之前版本改坏了文件用git checkout -- 文件名将工作区文件恢复到最近一次提交的状态想回退到指定历史版本需要整体回退用git reset --hard 提交哈希注意该操作会丢弃之后的所有提交这里面git reset --hard要特别提醒它会让工作区、暂存区全部恢复到指定提交的状态之后的所有提交都会从历史中消失。如果那些提交只在本地没过push那就是真的找不回来了。所以我用这个命令之前通常会先git branch backup建一个备份分支万一后悔了还能切回去。6.2 我建议你从现在开始养成的习惯学Git不是背命令而是建立一套稳定的工作习惯。第一是提交信息规范化小到个人项目大到团队协作都建议统一格式。我见过有些人的提交信息写“update”“fix”“111”回看历史时完全不知道做了什么等于没写。第二是.gitignore一定要早配。新建项目先写好要忽略的目录和文件类型比如Java的target、Node.js的node_modules、IDE配置文件等避免一堆垃圾文件被误提交进仓库。你可以搜一下“gitignore模板”直接套用比自己从头写省事得多。第三是学会用git stash。当你正在开发一个功能临时被叫去修个Bug但当前代码又改了一半不想提交这时候git stash会把所有未提交的变更“存起来”让你切换到干净的工作区去修Bug改完再执行git stash pop原来的变更全部回来。这个命令我在日常开发中几乎每周都会用非常实用。第四是配置几个常用别名让高频操作更顺手git config --global alias.co checkout git config --global alias.br branch git config --global alias.st status git config --global alias.lg log --oneline --graph --all配置好以后你可以用git st代替git status用git lg查看更清晰的提交历史图效率和体验都会提升不少。这些习惯不一定花很多时间但长期积累下来效果非常明显。根据我个人的体会学会Git的转折点不是你会敲多少条命令而是你真正理解了仓库状态和分支模型。从那以后遇到任何问题都能顺着“当前在哪个分支、工作区什么状态、远程和本地差多远”这几个问题去排查。建议你本地建一个测试仓库把今天讲的命令挨个敲一遍多试试merge冲突和reset回退的感觉亲手攒几次经验之后Git就会变成你日常开发里最顺手的工具之一。