开头
我见过太多拿着Git当网盘用的同学,也见过工作了三四年还在用git add .一条龙提交然后天天被同事骂的队友。Git这东西,说简单是真简单,无非就是add、commit、push、pull、merge这几个命令来回用;说复杂也真复杂,光是分支模型、rebase和merge的区别、冲突处理策略,就能让一个团队吵上一个下午。
这篇内容不是照抄官方文档的命令清单,而是从实际工作场景出发,把Git安装配置、日常操作、分支合并、IDE集成、SSH认证这些高频场景完整过一遍。无论你是刚接触Git的新手,还是用了一阵子但总感觉哪里没搞明白的开发者,这篇"操作大全"应该都能帮上忙。每个环节我都会写明"为什么这样做",而不是只丢给你一条命令让你背。
1. 环境准备:Git安装与初始配置
很多人觉得安装Git就是一路点"下一步",其实这里藏着几个直接影响后续使用体验的细节。选错版本、忽略环境变量、不配置换行符规则,都会在某个夜深人静的加班时刻给你挖坑。
1.1 Git下载安装:不同操作系统的正确姿势
Windows上装Git,大多数人会直接去官网下载安装包,这没问题,但有两个点需要额外注意。
第一,官网同时提供32位和64位版本,现在的新电脑基本都是64位系统,装64位版本就行。判断方法很简单:右键"我的电脑"看系统类型,确认是x64就下载64位安装包。千万别图省事随便下一个,32位版本在大型仓库上操作明显卡顿。
第二,安装过程中的"Adjusting your PATH environment"这一步,一定要选"Git from the command line and also from 3rd-party software"(推荐选项)。这个选项会把git命令注册到系统PATH中,意味着你之后在CMD、PowerShell、IDEA终端里都能直接用git命令。选了"Use Git Bash only"的话,系统自带终端会提示"git不是内部或外部命令",后续集成到IDE或其他工具时大概率踩坑。
macOS上安装相对简单,推荐用Homebrew执行brew install git,或者直接下载安装包。Linux用户则一般通过包管理器,比如Ubuntu/Debian用sudo apt install git,CentOS/RHEL用sudo yum install git。
装完后在终端里执行git --version,能正常打印出版本号,说明安装成功。
提示:如果安装后发现系统终端识别不了git命令,首要排查PATH环境变量。Windows用户可在"系统属性-环境变量-Path"里手动添加Git安装目录下的cmd文件夹路径(通常是
C:\Program Files\Git\cmd),改完记得重开终端窗口。
1.2 初始配置:不配置这3项,后面寸步难行
Git有个特点:不要求你登录才能用,但它会在每次提交时记录操作者身份。如果不设置用户名和邮箱,提交时要么报错,要么生成一串乱糟糟的默认身份,导致代码评审时根本不知道这块是谁写的。
核心配置就三条命令:
git config --global user.name "你的名字" git config --global user.email "你的邮箱" git config --global core.autocrlf true # Windows环境推荐第一条设置用户名,第二条设置邮箱,这两项会写入提交记录中,团队协作时对方能直接看到代码是谁提交的。邮箱建议使用公司邮箱或你常用的Git平台账号邮箱,因为它会和代码托管平台(如GitHub、GitLab、Gitee)的账号做关联,用于头像展示和提交贡献统计。
core.autocrlf是Windows用户的特殊配置。Windows下文件行尾默认是CRLF(回车+换行),Linux/macOS习惯用LF(仅换行)。如果团队中有人用Mac有人用Windows,提交代码时Git会检测到"一整行全变了",diff里出现大量无意义的变化。设置为true后,Git会自动把提交进仓库的内容转成LF,检出到本地时再转回CRLF,从而避免这种"假差异"。
查看当前配置用git config --list,这个命令会列出所有生效配置项,排查问题时特别有用。
2. 常用命令实战:从建仓到日常提交
聊完安装配置,接下来是每天都要用的核心操作。我会按照一个完整的工作流来梳理:建仓库、克隆代码、修改、暂存、提交、推送、拉取,每一环都讲清楚命令背后的逻辑。
2.1 新建仓库的两种方式与克隆的细节
新建项目时,本地仓库和远程仓库的关联方式分两种场景。
场景一:本地已有项目文件夹,需要纳入Git管理。在项目根目录执行:
git init这会生成一个隐藏的.git目录,本地仓库就初始化完成了。此时如果你想和远程仓库关联,执行:
git remote add origin https://github.com/用户名/仓库名.git把远程仓库地址命名为origin是约定俗成的习惯,origin相当于一个别名,后续推送拉取都可以直接用这个别名指代那一长串URL。
场景二:远程仓库已经存在,直接拉取到本地。执行:
git clone https://github.com/用户名/仓库名.git这里有个容易忽略的细节:git clone默认会把远程的master或main分支拉下来,并自动建立本地分支和远程分支的追踪关系。克隆完成后你直接git pull和git push都不用额外指定分支,因为Git已经替你记住了。如果使用git remote add方式,第一次推送时要加上-u参数:
git push -u origin master-u的意思是把本地master分支与远程master分支建立追踪关系,之后推送拉取就可以省略分支名了。很多新手直接用git push报错,就是因为没建立追踪关系。
注意:克隆私有仓库时,使用HTTPS协议每次推送都要验证账号密码(现在多数平台改用Token令牌)。如果觉得麻烦,建议直接配置SSH密钥,后面专门讲。
2.2 工作区、暂存区、提交区的底层逻辑
Git有三个核心区域,搞懂这三个区的流转关系,就理解了Git一半的精髓:
- 工作区(Working Directory):你本地看到的文件,可以随意编辑
- 暂存区(Staging Area / Index):用
git add命令把修改暂存起来的区域,相当于"预提交清单" - 版本库(Repository):
git commit提交后生成的快照,保存在.git目录里
日常操作流程是:改文件 →git add→git commit→git push。
为什么非要经过暂存区这一步?直接改完就提交不好吗?暂存区的设计意义在于:它允许你选择性提交。假设你同时改了功能A和功能B两个模块,只想先提交A模块的代码,就可以只git add相关的文件,B的修改继续留在工作区,互不干扰。这在团队评审时特别有用。
查看当前状态用git status,它会告诉你哪些文件被修改了、哪些已暂存、哪些未跟踪。强烈建议每次提交前都先观察这一步,别直接闷头执行。
提交命令是:
git commit -m "提交说明"提交说明的规范程度反映一个开发者的专业度。"fix: 修复登录接口返回500错误"远比"修改"有价值。后续排查问题时,好的提交说明能帮助你快速定位到具体改动。
2.3 撤销与回滚:改错了怎么补救
Git最让人安心的特性就是"什么都能撤"。关键是知道该用哪条命令。
- 工作区的修改还没
git add:执行git checkout -- 文件名,或者git restore 文件名(新版推荐),丢弃工作区的改动,恢复到上一次暂存或提交的状态。 - 已经
git add进暂存区了:先执行git reset HEAD 文件名撤出暂存区,再执行git checkout -- 文件名还原。 - 已经
git commit提交了:如果是最后一次提交,执行git reset --soft HEAD^可以回退到上一个提交但保留本次改动;git reset --hard HEAD^则彻底回退且丢弃改动,慎用,丢弃的改动无法找回。
git log用于查看提交历史。加上--oneline参数可以精简输出,每行只显示提交哈希和提交说明,适合快速浏览。
还有一个彩蛋命令git stash:当你正在A分支干活改到一半,紧急需要切到B分支处理问题,又不方便提交半成品代码时,执行git stash把改动暂存到栈里,切过去处理完,再切回来执行git stash pop恢复改动。这个命令用得好,能避免大量"临时注释代码"的尴尬。
3. 分支操作与合并:协作中的核心战场
单人在自己的仓库里用Git,怎么折腾都行。真正体验Git威力的是多人协作场景,而分支管理是协作的核心。别说你不用分支,工作中master直接提交的"勇士"往往在出事之后才意识到分支的重要性。
3.1 分支的创建、切换与删除
创建并切换到新分支,推荐用一条命令搞定:
git checkout -b feature/login这条命令等价于git branch feature/login加git checkout feature/login两步操作。新版Git更推荐用相对语义更清晰的:
git switch -c feature/loginswitch命令是Git 2.23版本引入的,把"切换分支"的语义从checkout中独立出来,用起来更不易混淆。
查看本地所有分支用git branch,查看远程分支用git branch -r,查看所有(本地+远程)用git branch -a。
分支开发完毕后,删除本地分支:
git branch -d feature/login如果分支上有未合并的改动,-d会报错提示,这时如果你确认不要这些改动了,用-D强制删除。这个保护机制很重要,防止误删未合并代码。
删除远程分支的命令是git push origin --delete feature/login,平时很少用到,但清理远程仓库时还是要知道。
3.2 合并、变基与Cherry-Pick:三条路的取舍
把A分支的改动合并到B分支,最常用的命令是:
git merge A分支名假设当前在B分支,执行这条命令后,Git会找出A分支相对B分支的差异,将这些改动合入B分支,并生成一个新的合并提交。如果两个分支各自都有未重叠的提交,Git会自动"三方合并",无需人工干预。
另一种方式是git rebase:
git checkout A分支名 git rebase B分支名Rebase的直观效果是"把A分支的提交改造为基于B分支最新提交之后的一条直线",提交历史干净整齐,没有分叉。但Rebase会重写提交哈希,如果这些提交已经推送到了远程且其他人也在基于它开发,会造成历史错乱。公共分支千万不要rebase,这是团队合作里的铁律。
还有一种精准操作叫git cherry-pick commit号,它的作用是:把某一个具体的提交,从别的分支"复制"到当前分支。适用场景是——某人在开发分支上修了一个紧急bug,但主分支这会儿也需要这个修复,又不想把整个开发分支合并过来,那cherry-pick就是最优解。
三种方式各有适用场景:
| 操作方式 | 适用场景 | 风险程度 |
|---|---|---|
| git merge | 功能分支合并回主分支,保留完整历史 | 低 |
| git rebase | 个人分支整理提交历史,保持线性 | 中(会重写历史) |
| git cherry-pick | 精准移植单个提交 | 低 |
3.3 冲突处理:新手最慌、老手也头疼的环节
合并时出现冲突(Conflict)是一件再正常不过的事。所谓冲突,就是两个分支改了同一个文件的同一块内容,Git不知道该听谁的,只能停下来让你做裁判。
冲突标记大概长这样:
<<<<<<< HEAD 当前分支的内容 ======= 被合并分支的内容 >>>>>>> feature/login手动编辑这个文件,保留你想要的代码,删掉<<<<<<<、=======、>>>>>>>这三组标记线。处理完后执行git add 文件名,再git commit完成合入。
这里分享一个实战经验:合并大功能分支前,先把主分支的更新合到功能分支上。也就是先切回功能分支,git merge master,在功能分支上解决冲突并测试通过后,再合并回master。这个"先合入再合并"的做法能避免直接在master上处理冲突的紧张感,因为功能分支本来就是你的地盘,调整自由度更大。
另一个减少冲突的方法很朴素:小步提交、频繁推送。分支放得越久,和主分支的差异就越大,冲突概率自然越高。
4. IDEA集成:创建新项目并拉取Git仓库
很多开发者日常开发不是在终端里敲命令,而是通过IDEA(IntelliJ IDEA)这类IDE完成Git操作。IDEA对Git的支持算得上业界标杆,可视化界面降低了操作门槛,但它的"自动操作"也经常让人一头雾水。
4.1 IDEA中配置Git插件的两个关键步骤
IDEA内置了对Git的支持,所以你不需要额外安装插件(之前的旧版本需要装Git Integration插件,现在默认集成)。需要做的是告诉IDEA你的Git可执行文件在哪里。
打开File → Settings → Version Control → Git,在"Path to Git executable"栏填入git的路径,Windows下通常是C:\Program Files\Git\bin\git.exe。填好后点击"Test",显示版本号说明配置成功。IDEA无法自动识别时,多半是Git安装时没注册到PATH,此时手动指定路径接入即可。
另一个容易被忽视的设置是Settings → Version Control → Confirmation,这里控制各种提交、添加、删除操作是否弹窗确认。推荐把"Show commit options in local commit"保留默认,它能让你在提交时勾选要不要运行测试、要不要Review改动,避免误提交。
4.2 从零创建新项目并拉取远程仓库的完整流程
场景:公司GitLab上已经创建好了一个项目仓库,你要在本地把它拉下来开发。这段流程是Git和IDEA配合的经典操作。
第一步,在IDEA欢迎界面选择Get from VCS(从版本控制获取)。如果你已经在某个项目里,操作路径是File → New → Project from Version Control。弹出的窗口里填远程仓库地址,选择存放目录,点击Clone即可。
第二步,克隆完成后,IDEA会自动识别项目结构。如果是一个Maven/Gradle项目,右下角会弹出提示"Import project"或"Maven projects need to be imported",点一下让IDEA建立依赖关系。这里有一个很多人踩过的坑:拉下来之后直接写代码,结果因为依赖没导入,一堆红色报错。看到右下角的加载提示记得先处理完再动手。
第三步,确认分支状态。IDEA右下角的状态栏会显示当前所在分支。如果远程分支很多需要切换,点击分支名弹出所有分支列表,选择Target分支切换到具体分支。
创建全新的项目再关联到远程仓库,则是另一套流程:先在本地用IDEA建好项目,仓库里创建一个空库(不要勾选README和.gitignore初始化),然后在IDEA终端执行:
git init git remote add origin 远程仓库地址 git add . git commit -m "init project" git push -u origin master这里有个实用技巧:远程仓库初始化时可以同时生成一份写好规则的.gitignore文件,防止把target、node_modules、.idea、*.iml这些本不该进版本库的文件推上去。如果之前没建,项目根目录手动创建.gitignore也不难,就是一些规则行的事。
4.3 IDEA日常提交与分支操作的心得
IDEA里提交代码的操作路径是⌘+K(Mac)或Ctrl+K(Windows/Linux),推送是⌘+Shift+K或Ctrl+Shift+K。提交之前弹出窗口会列出所有改动文件,你可以逐个Review,不想提交的可以勾选去掉。这个界面还支持Postfix语法,比如在提交信息里加#123这样的issue编号,配合Jira一类的管理工具非常顺手。
分支操作在IDE中更直观。右键项目Git → Branches,可以创建新分支、切换分支、合并变更。合并时如果出现冲突,IDEA会弹出一个三分栏diff窗口:左边是本地版本,右边是要合入的版本,中间是最终结果。你可以在图形界面里选择保留哪边的内容,或者手动编辑合并后的文件。相比在终端里面对冲突标记手忙脚乱,这种可视化解法对新手友好得多。
说一个IDEA特有的坑:IDEA会自动帮你做"自动变更集"管理。当你切换分支时,如果当前有未提交的改动,IDEA会弹窗询问"Smart Checkout"还是"Don't Checkout",Smart Checkout会把你未提交的改动带到新分支上,Don't Checkout则阻止切换并提示先处理改动。如果选择Smart Checkout后在新分支上看到了不属于本分支的修改,不用惊慌,那是IDEA帮你带过来的,直接提交会影响其他分支的干净程度。稳妥做法是养成"切换分支前先提交或stash"的好习惯。
5. SSH认证:密钥配置与失败排查实录
推送代码时频繁输密码、认证突然失效、克隆仓库报权限错误……SSH认证问题在任何团队里都是高频问题。这一节把SSH的原理、配置和常见坑一次说透。
5.1 为什么推荐用SSH而不是HTTPS
HTTPS协议操作Git仓库时,平台会要求你验证身份。早期做法是账号密码,现在GitHub、GitLab这些平台普遍改为Personal Access Token(个人访问令牌),在克隆时把密码替换成token使用。这种方式的好处是"即用即走",安全性高,但坏处也很明显:token有有效期,过期后要重新生成;而且每次push都要验证,体验上拖沓。
SSH的方式则不同。你在本地生成一对密钥(公钥和私钥),公钥配置到代码托管平台的账号里,私钥保存在本地。之后每次push/pull,Git客户端都会自动使用私钥完成认证,全程无感,也不需要任何密码或token。配置一次,长期有效。
因此对于日常开发,强烈建议优先配置SSH方式。尤其在公司内网的GitLab上,SSH几乎是标准配置。
生成密钥的命令是:
ssh-keygen -t rsa -b 4096 -C "你的邮箱"这里可以一路回车使用默认生成路径~/.ssh/id_rsa,也可以设置passphrase(安全密码短语),每次使用密钥时需要输入这个口令,安全性更高但便利性降低。个人开发环境建议不设置passphrase,工作机如果多人共用则建议设置。
执行完后会生成两个文件:id_rsa是私钥,绝对不能泄露;id_rsa.pub是公钥,可以放心给平台。查看公钥内容:
cat ~/.ssh/id_rsa.pub复制全部内容,粘贴到平台的SSH Keys设置页面,保存即可。
5.2 SSH认证失败的典型场景与排查步骤
SSH认证失败的错误提示是Permission denied (publickey),看到这个提示先别慌,按下面的清单逐项排查,绝大多数情况能解决。
场景一:公钥没配置或配置错了
检查公钥是否已添加到平台账号。另一个隐蔽的问题是:添加公钥时少复制了结尾部分或者多复制了换行,粘贴时多出来空格,都会导致认证失败。重新复制公钥内容,确认首尾完整后再试一次。
场景二:公钥添加到别的平台
很多人手上有GitHub、GitLab、Gitee多个账号,想当然把GitHub的公钥复制到GitLab上用,结果认证肯定失败。每个平台需要单独配置对应的公钥。当然,你可以在多台电脑共用一个邮箱生成一对密钥,分别添加到不同平台,但最稳妥的是每个平台独立生成。
场景三:SSH Agent没有加载私钥
Windows新装的OpenSSH客户端有时不会自动加载私钥。执行:
ssh-add ~/.ssh/id_rsa如果没有ssh-agent在运行,先启动服务。查看当前加载了哪些密钥用ssh-add -l。
场景四:远程地址错误
注意区分地址类型:正确的SSH地址是git@开头的,例如git@github.com:用户名/仓库名.git,如果填成了https://github.com/用户名/仓库名.git,即使SSH配置完全正确也走的是HTTPS通道,会被要求输入用户名密码。检查一下git remote -v输出的地址格式。
场景五:SSH配置文件问题
高级用户在~/.ssh/config文件里做过多主机配置,例如多个Host设置了同一个HostName或错误的IdentityFile路径,会导致密钥加载错乱。排查时先用带详细参数的命令测试:
ssh -T git@github.com -v-v参数打印调试日志,能清晰看到SSH客户端连接了哪个地址、尝试加载哪个私钥、被远端拒绝的原因。
5.3 换电脑或换密钥后的必备操作
换电脑后克隆仓库出现认证失败,第一反应是先确认是否在新机器上生成并配置了新的SSH密钥。每台机器生成的密钥都是独立的,旧密钥不会自动跟着过来。
有个针对公司GitLab的好习惯:离职或不再使用某台机器后,把该机器的公钥从平台删除,避免遗留安全隐患。另外,私钥文件id_rsa建议设置文件系统权限,Linux/macOS下执行chmod 600 ~/.ssh/id_rsa,防止其他用户读取。
提示:如果你有多对密钥管理需求,
~/.ssh/config可以配置不同Host对应不同密钥,例如GitHub用一个、GitLab用另一个。这属于进阶玩法,日常单账号用户直接用默认的id_rsa就足够了。
6. 实操经验:提交、回滚与仓库维护的几个避坑心得
最后一节,把我这些年踩过的坑、总结出来的经验一次性倒出来。每一条都来自真实事故现场,不是命令行文档里能查到的。
6.1 提交信息:从"改了一下"到清晰可回溯
见过最崩溃的提交信息是"update"、"demo"、"test",还有更离谱的"asdf"和""(空信息)。这种提交在代码评审、问题回溯阶段毫无价值,因为Git只能告诉你"某个时间点改过",说不清改了什么、为什么改。
我习惯的提交格式是type(scope): description,比如:
feat(auth): 新增短信验证码登录入口 fix(cart): 修复购物车数量清零bug docs(readme): 补充部署说明 refactor(order): 拆分订单服务为独立模块feat表示新功能,fix表示修复bug,docs是文档变更,refactor是重构。这种规范化格式看起来简单,但长期坚持下来,git log --oneline扫一眼就能对整个项目演进脉络有清晰认知。配合git log --author还可以单独查看某人的提交记录,回滚时也能精确定位到具体提交点。
6.2 回滚与丢失恢复:误操作后的求救指南
如果有人告诉我"代码被reset --hard搞丢了",我先让他执行git reflog再看结果。
git reflog是非常强大的命令,它记录了所有分支的HEAD移动历史。即使你执行了git reset --hard HEAD^,只要reflog里还保留之前的记录,你就能找回丢失的提交:
git reflog输出里能看到一系列操作历史和对应的提交哈希,找到你要的那条记录,执行:
git reset --hard 提交哈希就能恢复到那个时间点。这个命令甚至能找回误删除的分支。当然,reflog记录有保留期限,默认90天,超过这个期限确实救不回来了,所以重要操作前建议先备份分支或者用git branch 备份名创建备份分支。
再分享一个养成习惯:执行带有--hard或-f的破坏性命令前,先看一眼当前分支是否有未提交的改动。git status会告诉你工作区状态,干干净净执行reset --hard才会安全。
6.3 .gitignore的书写与权限管理:仓库卫生小事不小
.gitignore文件写的规则决定哪些文件不进版本库。写错了会导致一堆垃圾文件被提交,写漏了会导致关键敏感文件(比如配置了数据库密码的application.yml)被推送。
基础规则很简单:target/忽略目录、*.log忽略指定后缀、!important.log表示例外保留。新手最容易犯的错是:忽略规则写对了,但文件在规则添加之前已经被Git跟踪了。这种情况下git status仍然会显示该文件的修改,因为已经被跟踪的文件不受.gitignore影响。解决方法是先从Git索引中移除:
git rm --cached 文件名这个操作只移除Git对文件的跟踪,不会删除本地文件,下次提交后该文件就不在版本库里了,但本地还在。很多同事就是在这里卡住,明明加了.gitignore,文件却阴魂不散地出现在提交列表里。
还有一个团队层面的建议:仓库权限要分级。主分支最好设置保护,不允许直接push,只允许通过Merge Request(MR)或者Pull Request(PR)合并。这样强制每次代码变更都走评审流程。GitLab/GitHub均支持这个设置,在分支保护规则里把master或main配置为"不允许开发者直接推送,仅允许通过合并请求合入"即可。从源头杜绝"未评审代码直接上主分支"的风险。
6.4 大型仓库和稀疏检出
如果你的仓库变得很大,clone一次要等很久,可以考虑稀疏检出(sparse checkout)。这个功能允许你只拉取仓库中指定的子目录,而不是全部文件:
git clone --filter=blob:none --sparse 远程仓库地址 git sparse-checkout set 子目录名这是一个进阶但非常实用的优化项,尤其在接入体量很大的单体仓库时有奇效。日常中小项目的仓库基本用不上,但提前知道没坏处。
结尾
最后聊一点个人感受。Git操作本身并不难,真正难的是建立一套适合自己的工作习惯:提交信息写清楚、分支命名有规律、合并前先测试、破坏性操作前先备份。这些习惯不是一朝一夕养成的,我在前几年也经历过"push错了紧急回滚""合并把同事代码顶掉了然后一屋子人帮忙恢复"的狼狈时刻。每次事故之后认真复盘,把踩过的坑记下来沉淀成规范,团队的协作效率才会真正上一个台阶。如果这篇操作大全能帮你避开几个我当年踩过的坑,那这通篇写得就值了。