
今天开始做苍穹外卖。第一天我没写任何一行业务代码而是把大半天时间花在了 Git 上。原因很简单——这个项目后面每一天的增删改查、每一次接口调试、每一轮 BUG 修复都会和版本控制牢牢绑定。如果前三天不把分支、提交、回滚、合并这些概念理清楚后面写到 Redis 缓存、用户下单、店铺管理这些模块时一定会被各种“代码去哪了”“怎么回不去了”的问题反复折磨。先说结论第一天的重点不是代码量而是把“改动可以撤销、历史可以回看、环境可以复现”这套铁律立起来。下面我把第一天摸 Git 的过程完整记录下来包括踩过的坑和补救方法如果你也在刷苍穹外卖或者任何 Java 实战项目拿去就能用。1. 为什么第一天我没有直接写代码而是先补 Git1.1 苍穹外卖这个项目和 Git 到底有什么关系苍穹外卖是一个典型的 Java 全栈实战项目前端有用户端小程序和商家端网页后端是 Spring Boot 体系里面还涉及 MySQL、Redis、MyBatis、JWT 登录鉴权、文件上传这些常见模块。很多人拿到项目资料后的第一反应是“赶紧把代码跑起来”我第一天的想法也是但很快意识到一个问题这个项目从克隆到本地的那一刻起就已经进入了 Git 的管理范围。但凡你把它传到 Gitee 或 GitHub或者跟着视频里的多模块结构去改配置一天下来至少会产生几十次 diff。这些改动如果没有版本控制一旦误删文件、改错配置、合并分支时覆盖了别人的代码基本没有任何后悔药。平时自己写几百行代码可能感觉不到但苍穹外卖这种模块多、配置杂、还要反复联调的项目Git 是最基本的“后悔药”和“保险丝”。我第一天的目标是把本地仓库跑起来和远程仓库建立连接学会提交与分支操作把后面写业务代码可能遇到的版本问题提前清空。1.2 第一天只做一件事让改动变得可以撤销很多教程会把“安装 Git 并提交一次代码”作为开头但真正到实操时大家往往会跳过原理直接敲命令。结果就是——会敲git add .和git commit -m 却不明白为什么有时候需要先 pull 再 push更不知道分支合并冲突是怎么来的。我第一天给自己的任务只有一个让每一步改动都能被记录让任何一次误操作都能回到上一个存档点。这个概念有点像玩单机游戏。苍穹外卖就是你的游戏地图Git 就是存档系统。每打通一个小关卡也就是写完一个功能就存一次档存档写清楚“这次干了什么”以后想回到哪一关都行。如果你一路闷头往前冲不存档那就真的可能“辛苦打了两小时啪一下全没了”。所以第一天即使一行业务代码没写也不许慌。把存档体系搭好后面心不慌项目推进速度反而更快。2. 先把 Git 的原理聊透仓库、提交、分支到底是干什么的2.1 三个生活中的类比帮你少走弯路我学习 Git 时发现最有效的不是背命令而是用三个生活化的模型先建立画面感。第一个是“仓库”。你可以把它理解成一个项目的根目录里面包含了项目所有文件以及这些文件的历史记录。本地所有改动都在仓库里被跟踪远程仓库则相当于你把整个项目上传到云端大家都能从这里拉取代码也都能把各自改动推送上去。第二个是“提交”。提交就是一次存档它记录的是某一时刻项目文件的完整快照。你在苍穹外卖里写完一个“添加分类”的功能跑通测试然后执行git commit系统就把这一刻的代码状态保存下来了。提交还附带一条说明信息比如“feat: 完成分类新增接口”将来回看提交记录时一眼就能知道这个节点做了什么。第三个是“分支”。开发同一套代码时我们不会所有人挤在一条线上改而是拉出不同的线来并行推进。假设你负责订单模块我负责店铺模块我们各自从主线上开出分支互不干扰等两边都写完了再把分支合并回主线。这个机制能避免正在改代码时被人打断也让每个功能都有自己独立的生命周期。这三个概念理解到位之后再去看那些命令顺序和含义就变得很清晰。2.2 Git 安装教程装完不等于能用Windows 下安装 Git 非常简单去官网下载最新版本或者用镜像地址下载都行。安装过程基本保持默认配置但有三个选项建议手动确认一下不然之后会踩坑。第一个是默认分支名。新版 Git 安装时可能会让你选初始分支名建议直接用main和现在主流平台保持一致。第二个是换行符处理。Windows 和 Linux 的换行符不一样推荐选择 “Checkout as-is, commit as-is”或者选 Git 默认的自动转换。如果不注意后面在 IDEA 里打开别人的文件可能每个文件都显示成全部变化非常烦人。第三个是凭据管理器。选择 Git Credential Manager这样后面用 HTTPS 拉取仓库时输一次账号密码就能记住。安装完成后先做两件初始配置所有仓库都会继承git config --global user.name 你的昵称 git config --global user.email 你的邮箱这两行必须配不然每次提交都会报错。检查是否成功的命令是git config --global --list我第一天就在这里栽过跟头以为装完 Git 就能提交结果作第一次提交时被拦截提示没有用户名和邮箱。当时还以为是安装失败浪费了几分钟。2.3 初始化本地仓库打上第一个提交苍穹外卖的源码一般以压缩包形式提供解压后先把它变成一个本地仓库cd sky-take-out git init然后看一眼当前状态git status第一次执行git status你会看到一堆未跟踪文件。这时先别急着全部提交因为项目里通常有target目录、.idea目录等编译产物和 IDE 配置这些并不适合进版本控制。最稳妥的做法是在项目根目录放一个.gitignore文件把这些东西先屏蔽掉再考虑提交。具体怎么写我在后面第六节专门讲。准备好之后把所有需要跟踪的文件加入暂存区git add .再提交git commit -m init: 苍穹外卖初始代码用git log --oneline就能看到第一条提交记录。至此本地仓库的第一个存档点建立成功。后面的所有操作都可以基于这个点来展开。3. 远程托管与 SSH 认证从“本地仓库”走向“云端仓库”3.1 创建远程仓库并配置 SSH 连接本地仓库只能让自己回滚要想跨机器继续开发或者把项目推到 Gitee、GitHub 上留作备份就需要远程仓库。第一天我建议大家无论用不用得上都创建好远程仓库并建立连接因为这一步能提前暴露 SSH 配置问题总比以后着急上传时再抓瞎强。在 Gitee 上创建一个空仓库名字可以叫sky-take-out不要自动生成 README 和 .gitignore保持干净然后复制远程地址。接着在本地生成 SSH 密钥ssh-keygen -t ed25519 -C 你的邮箱一路回车即可生成完成后用下面命令查看公钥cat ~/.ssh/id_ed25519.pub把这段公钥复制到 Gitee 或 GitHub 的 SSH 公钥设置里名字随意。然后测试连通性ssh -T gitgitee.com如果返回欢迎信息说明 SSH 配置成功。之所以推荐 SSH 而不是 HTTPS是因为 SSH 不用每次提交都输入账号密码而且稳定性更好。3.2 SSH 认证失败的真·排查顺序“ssh 认证失败 git”是网络上非常高频的报错我第一天也撞上了。当时报错是Permission denied (publickey).这个报错看起来很吓人但排查顺序其实很固定。第一步先确认公钥是否真的已经添加到平台上。很多人复制公钥时把结尾的邮箱也复制进去了或者复制时多了一个换行都会导致认证失败。重新生成、重新添加一次往往就解决了。第二步确认本地使用的是不是正确的密钥文件。如果你曾经生成过多个密钥或者电脑上配置过别的 SSH 密钥可能默认用的不是你刚生成的那把。可以执行ssh-agent相关命令把密钥加载起来或者直接指定密钥文件测试。第三步检查你使用的远程地址是否为 SSH 格式。远程地址有两种一种是gitgitee.com:用户名/仓库名.git另一种是https://gitee.com/用户名/仓库名.git。如果你本地仓库绑定的是 HTTPS 地址却想用 SSH 密钥认证那当然失败。使用git remote -v查看地址不对劲就用git remote set-url origin修改。第四步处理端口问题。有些网络环境下 22 端口被防火墙或安全策略拦截可以尝试改用 443 端口。GitHub 官方支持ssh.github.com:443Gitee 也有类似端口配置方案。这个属于网络环境问题我第一次怎么配都不行换了端口之后立刻通了。排完前四步大部分认证失败问题都能解决。别一上来就删掉密钥重新生成先看是不是地址或公钥配置出错十次里至少有八次是低级问题。3.3 把本地仓库与远程仓库绑定SSH 通之后把本地仓库和远程仓库关联起来git remote add origin gitgitee.com:你的用户名/sky-take-out.git git branch -M main git push -u origin main第一次推送时远程仓库没有历史记录应该能顺利推送上去。如果远程仓库已经有 README 文件就需要先拉取合并git pull origin main --allow-unrelated-histories这个参数很关键它的意思是允许两个没有共同提交记录的仓库进行合并。很多人第一次 push 失败就是因为远程有文件而本地没有两边的历史没有关联Git 默认拒绝合并。推送成功后打开 Gitee 页面你就能看到苍穹外卖的初始代码已经躺在云端。至此本地仓库和远程仓库正式打通也意味着我的“第二份存档”已经放到了云上。4. IDEA 拉取 Git 仓库第一天必须会的基础操作4.1 直接用 IDEA 从远程仓库拉取新项目后面刷苍穹外卖的过程中你会在不同电脑之间切换今天在公司电脑上写明天在家里电脑上继续。这时候从 IDEA 直接拉取远程仓库就是高频操作。打开 IntelliJ IDEA在欢迎界面选择Get from VCS粘贴远程仓库地址选择本地保存路径然后点击 Clone 即可。IDEA 会自动识别这是一个 Maven 项目等待依赖下载完成就能直接开始开发。如果你已经打开了一个其他项目想再拉一个苍穹外卖可以File - New - Project from Version Control操作逻辑一样。克隆完成后IDEA 右下角会显示当前分支。在项目更新时可以直接用菜单栏的Update Project也可以用快捷键自动执行git pull。4.2 本地已有项目时如何导入并关联 Git有同学会遇到另一种情况源代码已经解压在本地也自己提交了好几个版本但还没有和远程仓库关联。这种情况下不需要重新克隆直接把本地项目导入 IDEA然后通过VCS - Enable Version Control Integration让 IDEA 识别 Git再执行我第三节提到的 remote 关联命令即可。这里要特别说明如果你在本地做过多次提交而远程仓库也有完全不同的历史首次推送时需要执行git pull origin main --allow-unrelated-histories合并一次远程的初始文件然后再推送。这个操作会生成一条合并提交没问题属于正常现象。4.3 克隆之后Maven 与模块识别的常见坑苍穹外卖这种项目通常是多模块结构克隆到本地后IDEA 有时不会立即识别所有模块。表现为左侧项目树只显示几个目录或者找不到启动类、找不到 Maven 依赖。遇到这种情况先别急着重新克隆去 Maven 面板点一下刷新或者File - Project Structure - Modules里手动导入模块。另一个常见问题是不同电脑上的 JDK 版本不一致。苍穹外卖有的版本要求 JDK 8有的要求 JDK 17。克隆之后记得检查 Project SDK 和 Maven 的 Java 版本否则编译会报出各种奇怪的错误。这些和 Git 无关但会严重影响第一天的心情顺手记一下。还有个小技巧IDEA 内置的 Git 插件读取的是你系统安装的 Git 路径。如果系统里 Git 路径变了或者 IDE 提示 Git 可执行文件未配置打开Settings - Version Control - Git手动指定git.exe的位置即可一般不会出现这种问题但一旦出现就是在最不该出问题的时候出问题。5. 分支与合并在被团队毒打之前先把习惯养好5.1 分支存在的意义以及为什么不要都在 main 上开发很多新手一开始只在一个分支上工作main上直接提交等到需要写多个功能时就乱了。苍穹外卖虽然多是单人开发或跟着视频一步步做但同样会面临“登录功能写到一半想先去看店铺管理模块”的情况。如果没有分支半成品代码会和完好的代码混在一起万一想运行一下完整项目却被半成品代码卡住非常尴尬。我第一天就在main上开了一个feature/day1-git分支后面的需求各自再开分支只保留稳定的代码进入main。这样永远有一条安全的主线任何开发中的破坏性改动都不会污染它。创建分支的命令很直接git branch feature/day1-git git checkout feature/day1-git更高效的是直接创建并切换git checkout -b feature/day1-git强制写成完整拼写有利于肌肉记忆。5.2 常用 Git 命令速查与合并演示第一天我整理了一张命令表贴在项目笔记的第一页内容是使用场景命令说明查看状态git status显示当前改动查看历史git log --oneline简洁显示提交记录添加暂存git add 文件名只暂存指定文件提交git commit -m 描述创建存档点推送git push上传到远程仓库拉取git pull下载远程改动查看分支git branch -a列出所有本地和远程分支切换分支git checkout 分支名切换到已有分支新建并切换git checkout -b 分支名创建并切换合并git merge 分支名将指定分支合入当前分支暂存改动git stash临时收走未提交改动恢复暂存git stash pop恢复临时改动合并操作演示一下假设我在feature/user-login分支上完成了登录模块提交后切回main执行git checkout main git merge feature/user-login如果两个分支的改动互不干扰Git 会自动合并如果两个分支修改了同一个文件的同一段代码就会报冲突。冲突文件里会出现、、这样的标记分别表示当前分支、分隔线、对方分支的内容。需要手动删除标记并保留正确内容再重新提交。5.3 减少冲突的四个实操习惯冲突不可能完全避免但可以大幅减少。我这四招非常有效。第一坚持小块提交。一个接口写完、自测通过就提交一次不要把三天的工作攒成一次大提交。改动越小合并时被冲突覆盖的概率越低。第二开工前先同步。每次在分支上开发前先切回main拉取最新代码再把main合并进自己的开发分支。这样你的分支不会落后主线太远。第三提交信息写成“给未来的自己看”的样子。别说“修改一些东西”要写“实现用户登录接口并处理异常”。苍穹外卖项目至少要开发一两周到时候回看提交历史好的提交信息能让你立刻定位问题。第四解决完冲突必须重新编译运行。很多冲突从文本上看没问题但合并后代码逻辑可能已经乱了不跑一遍就提交等于埋雷。6. 苍穹外卖里的本地图片上传为什么一天前就要避开 Git6.1 常见错误把上传目录写在项目里面苍穹外卖的项目过程中有一个很经典的环节本地上传图片。比如商家后台上传菜品图片、添加分类图标这些图片最终要显示在管理端和小程序端。跟着教程操作时很多人会把图片保存到项目的src/main/resources/static/upload之类的目录里。问题马上来了图片都是二进制文件一旦你运行开发环境测试上传几张大的菜品图工作区就会出现一大堆没有意义的变化。如果你没注意直接git add .这些图片就被加进了仓库。一次两次还好传几次之后仓库体积会迅速膨胀别人再克隆项目时要下载大量无关图片速度感人。更麻烦的是墨盒路径如果写的是本地绝对路径比如D:/upload/xxx.png别人的电脑上根本没有这个目录项目在别人那里跑起来后图片全部 404。这类问题一旦出现查起来很费劲因为它不是代码逻辑错误而是运行环境差异。6.2 正确的本地图片存储方案与虚拟映射我建议的方案是把上传目录放到项目外部并通过配置项动态指定路径。项目里只保留代码逻辑不保留上传后的图片文件。具体做法是在application.yml里加一个自定义参数sky: upload-path: D:/data/sky-upload/然后在代码里读取这个路径将上传图片保存到该目录。前端访问图片时在后端做一个虚拟路径映射把/upload/**请求映射到这个本地目录。这样图片存在项目之外项目本身的 Git 记录不会因为上传图片而变脏其他同事克隆代码后只需修改自己的上传路径配置即可。如果只是为了开发阶段测试也可以把上传目录放在项目target目录下因为target本来就是构建产物通常已经被.gitignore屏蔽不会污染仓库。但注意target目录会被 Maven 清理重启后可能丢失只适合临时测试。6.3 误提交大文件之后怎么补救已经误提交了怎么办我第一天因为手滑把一个 300MB 的数据库备份文件提交进了本地仓库。好在还没有推到远程处理起来很简单第一步把文件从 Git 跟踪中移除但保留在本地磁盘上git rm --cached 数据库备份文件第二步把该路径写进.gitignore防止再次被跟踪。第三步提交这次删除操作。这样以后推送不会被这个文件影响。注意git rm --cached只是让文件不再被 Git 跟踪文件本身还会留在工作目录里不会误删。如果你的误提交已经推送到远程仓库了情况会复杂一些。单纯删除后面提交的版本历史记录里仍然有这个文件仓库体积依然大。想彻底清理历史需要使用git filter-branch或相关工具改写历史。这种事我劝大家别在第一天尝试特别是远程仓库已经有别人使用时改写历史会影响大家最好的策略就是一开始用.gitignore挡好把坑堵在源头。7. 第一天复盘与后续安排7.1 我的第一天下班检查清单为了防止“以为学会了其实没有”我给自己列了一个检查清单。每项都有明确的完成标志检查项状态我用的验证命令Git 安装成功完成git --version配置用户名和邮箱完成git config --global --list生成 SSH 密钥完成ls ~/.ssh添加公钥到远程平台完成ssh -T gitgitee.com初始化本地仓库完成git log --oneline绑定远程仓库完成git remote -v成功推送初始代码完成在 Gitee 页面看到代码创建并切换分支完成git branch -a体验一次分支合并完成手动创建一个测试文件并合并配置.gitignore完成git status不再出现 target 目录建议你也照着这张表逐项打钩。不要凭感觉判断“差不多会了”每项都跑一遍命令拿到预期输出这才是真会了。7.2 接下来几天我会按什么顺序推进第一天的 Git 基础打完之后我已经能预估后面几天的节奏。第二天我会把苍穹外卖的后端项目完整跑起来完成数据库脚本导入确认前端能调通后端接口。第三天开始处理登录模块和 JWT 令牌机制这是整个项目的门槛。再往后就是分类管理、菜品管理、用户端点餐、订单流程这些主流程功能。每完成一个模块我都计划提交一次代码并在提交信息里写明完成的内容。等整个项目做完时回看提交记录就能看到一条非常清晰的成长线。这也是 Git 给我的额外价值——它不只是工具还是项目进度的记录仪。第一天真正值钱的东西不是装好了 Git而是我逼自己想明白了一个道理Git 不在乎你写得好不好只在乎你有没有留好退路。有了这个意识后续几天无论写得多乱总能回到一个稳定版本重新来。刷到这个文章的你如果也在刷苍穹外卖别急着跳过 Git 直接开跑。花一天时间把这些基础操作理顺后面每一天都会顺手很多。