跳转到内容

2.3 Git 与 GitHub:安装配置与「后悔药」四件套

这是全课两篇「重点长文」之一,篇幅约是普通课时的两倍半。建议配一杯咖啡,或者分两次读——读到「四件套」之前是配置,之后是真本事。

本节不要求你背下来。你只需要建立一个认知:出事了有救,命令长这个样子。真正的肌肉记忆会在第 5、8、9 三个项目章里一次次建立——那几章每个关键节点都会提醒你「此处先 commit 一次」。

页内目录


一、本节你会做出什么

你会拥有一个真正的 GitHub 仓库,并且亲手演练一次事故现场:把项目改坏,然后用一条命令救回来。

📷 效果位:GitHub 仓库页面 + 终端里 git log 显示的三条提交记录

演练完你会有一个新的心理状态:不怕 AI 改坏东西了。 这个状态值这 45 分钟。


二、开始前你需要

  • 已完成 2.1 认识终端,会 cdls
  • 已完成 2.2 Node.js 与 pnpm 安装指南(本节演练会用到 hello-node 项目;删了也没关系,本节会教你重新建一个练习用的)
  • 一个能收验证码的邮箱(建议用私人邮箱,不要用公司邮箱——离职会丢)

三、跟着做

3.1 为什么这是全课最重要的一节

先说一个每个 AI 编程学习者都会遇到的场景:

你的页面做得好好的。你跟 AI 说“帮我把导航栏改成深色”。 AI 改了。然后你刷新页面——整个网站白屏了。 你说“改回去”。AI 又改了一通,白屏变成了报错。 你再说“回到最开始的样子”。AI 说“好的”,然后改出了第三种坏法。

半小时后,你已经不记得原来那个能跑的版本长什么样了。

这不是 AI 笨,这是没有存档点的必然结果。AI 每次修改都可能同时动好几个文件,你靠记忆是追不回来的。

Git 解决的就是这一件事:让你随时能回到“上一个能跑的版本”。

💡 一句话记住本节价值:AI 会写代码,但只有你能决定要哪个版本。Git 就是你行使这个权力的工具。

3.2 Git 和 GitHub 到底是什么(游戏存档类比)

很多人一上来就被这两个名字搞晕。一张表讲清:

Git GitHub
是什么 装在你电脑上的软件 一个网站
类比 游戏里的存档功能 存档的云同步服务
作用 记录每一次改动,能随时回到任意存档点 把存档传到云端,换电脑能拿回来,也能发给别人看
没网能用吗 ,完全本地 不能
必须一起用吗 不必须 可以只用 Git 不用 GitHub

再补两个你会天天听到的词:

  • 仓库(repository / repo):一个被 Git 管起来的项目文件夹。项目根目录下会多出一个隐藏的 .git 文件夹,所有历史都存在里面。别删它,删了历史就没了。
  • 提交(commit):一个存档点。每个 commit 有一条你写的说明,和一串识别码(像 a3f9c21 这样的字符)。

类似的还有一个叫 GitLab / Gitee 的东西,它们和 GitHub 是同类产品。本课统一用 GitHub,因为第 11 章的部署平台(Vercel / Zeabur)都是直接连 GitHub 一键部署的。

3.3 安装 Git 并做三项配置

安装

🍎 Mac:先在终端执行一下,看看系统自带没有:

终端窗口
git --version
  • 打印出版本号(如 git version 2.4x.x)→ 已经有了,跳到配置
  • 弹出一个窗口问你要不要安装「命令行开发者工具」→ 点安装,等几分钟,装完再执行一次验证
  • 想装最新版的话,去 git-scm.com 下载安装包也行,不是必须

🪟 Windows:去 git-scm.com 下载安装包,双击运行。

安装过程有十来个选项页,全部保持默认一路 Next 即可,只有一页值得看一眼:

  • Choosing the default editor used by Git —— 默认是 Vim,这个编辑器新手很难退出。如果列表里有 Use Visual Studio Code as Git's default editor 就选它,没有就保持默认,本课的操作不会用到它。

装完关掉 PowerShell 重开一个,执行 git --version 验证。

📷 截图位 1:终端里 git --version 的输出

三项配置(只做一次,终身有效)

终端窗口
git config --global user.name "你的名字"
git config --global user.email "你的邮箱@example.com"
git config --global init.defaultBranch main

逐条解释:

  1. user.name / user.email:每个存档点都会记上“是谁存的”。写英文名或拼音都行,邮箱建议和你注册 GitHub 用的邮箱一致,这样 GitHub 才能把提交记录认成你的。
  2. init.defaultBranch main:把默认分支名设成 main。分支是什么第 5 章会碰到,这里只需要知道:新旧默认值不一样(老的叫 master),统一成 main 能避免一批莫名其妙的报错。

验证配置:

终端窗口
git config --global --list

能看到你刚填的三行就对了。

⚠️ 邮箱会公开。每个 commit 里的邮箱地址,别人能在 GitHub 上看到。介意的话可以去 GitHub 设置里开启邮箱保护,用它提供的 xxx@users.noreply.github.com 地址来填 user.email

3.4 注册 GitHub 并打通连接

注册

打开 github.com → Sign up → 填邮箱、密码、用户名。

用户名会出现在你所有项目的网址里github.com/你的用户名/项目名),也会出现在简历上,建议认真取一个:全小写英文、可以带短横线、不要带年份和生日。

注册完请立刻做一件事:开启两步验证(2FA)。Settings → Password and authentication → 按提示绑定手机 App。GitHub 现在强制要求,早开早省事。

📷 截图位 2:GitHub 注册完成后的首页

打通本地和云端的连接

本地的 Git 要能往 GitHub 推送,得先证明“我是我”。两种方式,本课推荐第一种

方式 A:SSH 密钥(推荐,配一次永久有效)

  1. 生成密钥(-C 后面换成你的 GitHub 邮箱):
终端窗口
ssh-keygen -t ed25519 -C "你的邮箱@example.com"

它会问三个问题,全部直接回车用默认值(文件位置默认、密码留空、确认留空)。

  1. 复制公钥内容:
终端窗口
cat ~/.ssh/id_ed25519.pub # Mac / Windows PowerShell 都可用

屏幕上会打印一长串以 ssh-ed25519 开头、以你的邮箱结尾的文字。整段选中复制

  1. 打开 GitHub → 右上角头像 → Settings → 左侧 SSH and GPG keysNew SSH key

    • Title:随便写,比如 我的 MacBook
    • Key:粘贴刚才复制的整段
    • Add SSH key
  2. 验证连接:

终端窗口
ssh -T git@github.com

第一次会问 Are you sure you want to continue connecting?,输入 yes 回车。看到 Hi 你的用户名! You've successfully authenticated... 就通了。

⚠️ 千万别把 id_ed25519(没有 .pub 后缀的那个)发给任何人。带 .pub 的是公钥,可以公开;不带的是私钥,等于你家钥匙。

方式 B:HTTPS + 访问令牌

如果 SSH 怎么都配不通(公司网络封了 22 端口是常见原因),改用这个:推送时 GitHub 会弹窗或在终端里要账号密码,密码处不能填登录密码,要填一个 Personal Access Token:Settings → Developer settings → Personal access tokens → Tokens (classic) → Generate new token,勾上 repo 权限,生成后立刻复制保存(页面关掉就再也看不到了)。

📷 截图位 3ssh -T git@github.com 成功的输出


后悔药四件套

下面四个命令是本节的核心。你不需要背,但要知道它们各自解决什么问题。

命令 一句话 什么时候用
commit 存档 每次做出一个“能跑的版本”之后
diff 看 AI 改了什么 AI 说“改好了”,你按下去之前
reset 读档 改坏了,救不回来了
push 传云端 一天的工作结束时,或者要部署时

3.5 后悔药第一件:commit —— 存档

第一次给一个项目开启 Git,需要三步。以后每次存档只需要最后两步。

第 0 步(每个项目只做一次):让 Git 接管这个文件夹

终端窗口
cd ~/Documents/ai-course/hello-node # 换成你的项目路径
git init

看到 Initialized empty Git repository in ... 就成功了。

第 1 步:看看现在有什么变化

终端窗口
git status

这是你用得最多的命令,它会告诉你:哪些文件改了、哪些是新增的、哪些已经准备好存档了。任何时候不确定状态,先 git status

第 2 步:把要存档的内容放进“打包箱”

终端窗口
git add -A

-A 表示把所有改动都放进去。(Git 的设计允许你挑着存,但零基础阶段永远用 git add -A 就对了。)

第 3 步:正式存档

终端窗口
git commit -m "初始化项目,页面能正常打开"

-m 后面引号里的,是这个存档点的说明。执行后会打印出改动了几个文件。

commit message 怎么写? 一条规矩就够:

写“这个版本能干什么”,不要写“我改了哪个文件”。

❌ 不好 ✅ 好
update / 修改 / 123 完成首页 Hero 区,手机端正常
改了 page.tsx 导航栏改成深色,链接跳转正常
fix bug 修复点击卡片不跳转的问题

因为将来你要回滚的时候,看到的就是这一行字。写 update 的人,一个月后面对十条 update 完全不知道该回哪一条。

查看所有存档点:

终端窗口
git log --oneline

输出类似:

a3f9c21 导航栏改成深色,链接跳转正常
7b2e488 完成首页 Hero 区,手机端正常
1c4d0f3 初始化项目,页面能正常打开

前面那串字符是提交 ID,回滚的时候要用到它。

🚫 一件必须先做的事:.gitignore

有些东西永远不该被 Git 记录

  • node_modules/——几百 MB 的可再生资源,2.2 讲过
  • .env / .env.local——装着你的 API 密钥,传到 GitHub 上等于把银行卡密码贴在马路边(第 10.1 节会讲这类事故的真实代价)
  • .DS_Store(Mac 系统文件)、构建产物 .next/ dist/

做法:在项目根目录建一个叫 .gitignore 的文件(注意开头有个点),写上这些:

node_modules/
.next/
dist/
.env
.env.local
.DS_Store

✅ 好消息:用 pnpm create next-app 创建的项目已经自带一份 .gitignore,上面这些都在里面了。你只需要知道有这么个文件、以及它为什么重要。

⚠️ 但如果你的项目是 AI 从零给你生成的,一定要主动问一句:“请给我生成一份 .gitignore”

3.6 后悔药第二件:diff —— 看 AI 到底改了什么

这是四件套里最被低估的一个。

AI 说“已经帮你改好了”的时候,它可能同时动了 5 个文件、删掉了你昨天写的一段内容,而你只在页面上看到了那一处你要的改动。diff 就是让你在按下去之前,先看清楚它到底动了什么。

终端窗口
git diff

输出长这样:

--- a/app/page.tsx
+++ b/app/page.tsx
@@ -12,7 +12,7 @@
- <h1 className="text-4xl">成都</h1>
+ <h1 className="text-6xl font-bold">遇见成都</h1>

只看两个符号就够:

符号 含义
- 开头(红色) 删掉的旧内容
+ 开头(绿色) 新增的内容

一行被修改,会显示成“删一行 + 加一行”。

只想知道动了哪些文件、不想看细节:

终端窗口
git status # 列出所有改动的文件
git diff --stat # 列出文件 + 每个文件改了几行

💡 实战用法:AI 改完之后先 git diff --stat。如果你只让它改一个按钮的颜色,结果它动了 8 个文件、改了 300 行——这就是个危险信号,先别急着相信,把 diff 结果贴回给 AI 问:“我只要求改按钮颜色,你为什么动了这些文件?”

看不懂 diff 也没关系,第六部分有一条专门的提示词,把 diff 整段丢给 AI 让它给你翻译。

📷 截图位 4:一段典型的 git diff 输出,红绿对照

3.7 后悔药第三件:reset —— 读档

真正的后悔药。分三种力度,从轻到重用:

力度一:丢掉还没 commit 的改动(最常用)

AI 刚改坏,你还没存档,想回到上一个存档点:

终端窗口
git restore .

一秒钟,所有未提交的修改全部消失,文件回到上次 commit 的样子。

等价的老写法是 git checkout .,你在网上会看到两种都有,作用一样。

力度二:回到上一个存档点(连同已提交的一起丢)

终端窗口
git reset --hard HEAD

HEAD 指“当前所在的这个存档点”。这条命令等于“把工作区彻底恢复成存档时的样子”。

力度三:回到任意一个历史存档点

终端窗口
git log --oneline # 先找到你想回去的那个 ID
git reset --hard 7b2e488 # 回到那个存档点

执行完,整个项目就是当时的样子了。刷新浏览器,那个能跑的版本回来了。

⚠️ --hard 是有破坏力的:它会永久丢弃从那个存档点之后的所有改动,不进回收站。所以:

  1. 执行前先 git status 看一眼,确认没有你舍不得的东西;
  2. 舍不得又想回滚?先 commit 一次再 reset——这样那些改动还留在历史里,用 git log 能找回来;
  3. 这也正是“频繁 commit”的意义:存档点越密,你能回退的粒度越细,损失越小。

3.8 后悔药第四件:push —— 传到云端

本地存档再多,电脑坏了也是全没。push 就是把存档同步到 GitHub。

第一次:在 GitHub 上建一个空仓库

GitHub 右上角 +New repository

  • Repository name:hello-node(和本地文件夹同名最省心)
  • Public(公开)还是 Private(私有):练习项目建议 Private,尤其是里面可能有密钥的时候
  • 下面那三个勾(Add a README / .gitignore / license)全都不要勾——勾了会和你本地的历史打架,新手在这里翻车最多

点 Create repository。

第二步:把本地和远程接上,推上去

创建完的页面上,GitHub 会直接给你几行命令。用 …or push an existing repository 那一段,长这样:

终端窗口
git remote add origin git@github.com:你的用户名/hello-node.git
git branch -M main
git push -u origin main

三条分别是:告诉本地“云端仓库在这个地址”(origin 是这个地址的代号)、把分支名统一成 main、推上去。

以后每次推送,只要一条:

终端窗口
git push

刷新 GitHub 页面,你的代码就在上面了。

📷 截图位 5:GitHub 仓库页面,能看到刚推上去的文件和 commit 说明

💡 push 的第二个价值:第 11 章部署上线时,Vercel / Zeabur 是直接连你的 GitHub 仓库的——你 push 一次,网站自动更新一次。所以这一步不是“额外的备份工作”,它就是后面的发布流程本身。

3.9 完整演练:改坏它,再救回来

这是本节唯一必须亲手做的部分。 五分钟,但它会改变你之后每一次面对 AI 的心态。

终端窗口
# 1. 进入项目(没有 hello-node 就随便建个文件夹,里面放个 txt 文件也行)
cd ~/Documents/ai-course/hello-node
# 2. 确认状态干净,然后存下第一个档
git status
git add -A
git commit -m "存档点 A:页面能正常打开"
# 3. 现在扮演一次 AI,把项目改坏
# 用编辑器打开 app/page.tsx,随便删掉几行,保存
# (或者在终端里往文件里追加垃圾内容)
# 4. 看看"AI"都干了什么
git status
git diff
# 5. 后悔了,一键还原
git restore .
# 6. 验证:diff 是空的,说明和存档点 A 一模一样了
git diff
git status

第 6 步执行完,git status 应该告诉你 nothing to commit, working tree clean

刚才发生的事:你把项目改坏了,然后一条命令,它完好如初。以后 AI 再怎么改,你都有这张底牌。

📷 截图位 6:改坏 → diff 看到红色删除行 → restore → status 显示 clean 的完整过程

3.10 日常怎么用:三条规矩 + 一张速查表

三条规矩

  1. 动大手术之前,先 commit 一次。 判断标准很简单:你打算让 AI 做的这件事,如果做砸了你会心疼,就先存档。花 10 秒,省 2 小时。
  2. 只要页面“现在是好的”,就 commit。 别等“做完整个功能再存”。存档点是免费的,密一点没有任何坏处。
  3. AI 说“改好了”,先 git diff --stat 再相信。 改动范围远超预期,就是危险信号。

第 5、8、9 三个项目章里,每个关键节点都会出现一句「此处先 commit 一次」的提示。跟着做,这套习惯会自己长出来,不用刻意背。

速查表(收藏这一张就够)

我想做的事 命令
看看现在什么情况 git status
让 Git 接管这个项目(只做一次) git init
存档 git add -A 然后 git commit -m "说明"
看 AI 改了什么 git diff(细节) / git diff --stat(概览)
看所有存档点 git log --oneline
丢掉还没存档的改动 git restore .
回到上一个存档点 git reset --hard HEAD
回到指定存档点 git reset --hard 提交ID
传到 GitHub git push(第一次要先 git remote add origin ...
从 GitHub 拉下来 git pull
把别人的项目下载下来 git clone 仓库地址

这张表也收在 [附录 A 命令行速查表],不用死记,随时回查。 分支、冲突处理、多人协作这些进阶内容在 [附录 I Git 进阶]——单人做项目用不到,等真需要时再看。

不想敲命令?可以用界面

git 的所有操作都有图形界面版本:

  • VS Code / Cursor 左侧的「源代码管理」面板:改动的文件会列出来,点一下就能看 diff(左右对照,比终端清楚),输入说明点✓就是 commit。推荐,因为你本来就开着编辑器。
  • GitHub Desktop:GitHub 官方客户端,全中文界面,更适合完全不想碰终端的人。

界面好用,但本节的命令还是要认得——因为 AI 给你的指令永远是命令形式的,你得看得懂它让你干嘛。


四、完成的标志是

  • git --version 能打印版本号
  • git config --global --list 里有我的 name 和 email
  • 我注册了 GitHub,用户名我自己满意,且开了两步验证
  • ssh -T git@github.com 提示认证成功(或我用 HTTPS + Token 成功推送过)
  • 我在项目里执行过 git init 并完成了第一次 commit
  • 我知道 .gitignore 是干什么的,也知道 .env 绝对不能提交
  • 我看过一次 git diff,认得红色是删、绿色是加
  • 我完整做过一次「改坏 → git restore . → 恢复」的演练
  • 我的项目已经推到了 GitHub,网页上能看到
  • 我知道 --hard 是有破坏力的,用之前要先 git status

五、卡住了看这里

Q:git commit 之后终端变成一个奇怪的全屏界面,打字没反应,也退不出来。 你掉进 Vim 了(commit 时忘了写 -m "说明" 就会这样)。按 Esc,然后输入 :q! 再回车,就能退出来。下次记得 -m

Q:提示 Author identity unknown / Please tell me who you are 3.3 的两条配置没做。执行 git config --global user.name "..."git config --global user.email "..." 再重试。

Q:git pushPermission denied (publickey) SSH 密钥没配好或没加到 GitHub 上。先跑 ssh -T git@github.com 看看通不通:不通就回 3.4 重做一遍,注意公钥要复制整段(包括 ssh-ed25519 开头和邮箱结尾,中间不能有换行)。公司/学校网络封 SSH 的话,改用 3.4 的方式 B。

Q:git pushremote: Repository not found 仓库地址写错了,或者你没权限。用 git remote -v 看一眼当前配的地址对不对,错了就 git remote set-url origin 正确地址 改掉。

Q:git pushUpdates were rejected because the remote contains work that you do not have locally 云端有你本地没有的东西——八成是建仓库时勾了 README。最省事的办法:删掉那个 GitHub 仓库重建一个(三个勾都不勾),再推。或者执行 git pull --rebase origin main 后再 push。

Q:git push 卡住不动,一直没反应。 第一次连接时它可能在等你输 yes 确认指纹,但提示被刷屏盖住了。试着输入 yes 回车。还不行就 Ctrl + C 停掉,先跑 ssh -T git@github.com 单独确认连接。

Q:我不小心把 .env(带密钥)提交并推上去了,删掉文件重新提交就行了吗? 不行。 Git 会记住历史,密钥依然能在历史记录里被翻出来。正确做法是:立刻去对应平台把那个 Key 作废、重新生成一个,然后再处理仓库。这是第 10.1 节的重点,那里有完整处置流程。记住核心:泄露了就换钥匙,而不是藏钥匙。

Q:git reset --hard 之后我后悔了,还能找回来吗? 如果那些改动曾经被 commit 过,能找回来:git reflog 会列出你所有操作的记录,找到对应的 ID 再 git reset --hard 那个ID。如果那些改动从来没 commit 过,那就真的没了——这就是规矩二“页面是好的就 commit”存在的理由。

Q:项目里的 .git 文件夹看不见。 它是隐藏文件夹,正常现象。Mac 访达里按 Command + Shift + . 可以显示隐藏文件;终端里 ls -la(Windows 用 ls -Force)也能看到。看到了也别动它。

Q:一个项目能推到 GitHub 的多个仓库吗?我想换个仓库。 能。git remote set-url origin 新地址 换掉地址就行,本地历史完全不受影响。


六、本节提示词

① Git 报错急救(存起来,这一条你会用很多次):

我是 Git 新手,在【Mac / Windows】上操作。
我执行的命令是:【粘贴命令】
完整报错是:
【粘贴终端全部输出】
另外这是我的状态信息:
git status 的输出:【粘贴】
git remote -v 的输出:【粘贴】
请你:
1. 用大白话说明发生了什么;
2. 给我可直接复制执行的解决命令,一条条分开;
3. **特别标注哪些命令会丢失我的代码**,如果有更安全的替代方案,先给安全的那个;
4. 告诉我怎么验证已经解决了。

② 让 AI 翻译 diff(看不懂 AI 改了什么的时候):

AI 帮我改了代码,我想在接受之前搞清楚它到底动了什么。
我原本的要求只是:【比如"把首页标题改大一点"】
这是 git diff 的输出:
【粘贴 diff 全文】
请你:
1. 用大白话逐条说明它改了哪些地方、每处的效果是什么;
2. 有没有超出我要求范围的改动?如果有,明确列出来;
3. 有没有删掉了原本有用的东西?
4. 综合判断:这次改动我该接受,还是该回滚重来?

③ 请 AI 指挥一次回滚(自己拿不准该用哪条命令时):

我的项目被改坏了,我想回到之前能正常运行的版本。
这是 git log --oneline 的输出:
【粘贴】
这是 git status 的输出:
【粘贴】
我想回到的是:【比如"标题改大之前那个版本",或直接指定某个 commit 说明】
我【有 / 没有】还没提交、但想保留的改动。
请给我一个最安全的操作步骤,每一步说明它会做什么、会不会丢东西。
如果需要我先做备份,请先告诉我怎么备份。

④ 生成 .gitignore(AI 从零生成的项目务必执行一次):

我的项目技术栈是:【比如 Next.js + TypeScript】,我在【Mac / Windows】上开发。
请给我一份完整的 .gitignore 文件内容,可以直接复制。
要求:
1. 确保依赖文件夹、构建产物、系统临时文件都被排除;
2. **确保所有可能包含密钥的文件(.env 系列)都被排除**;
3. 每一组加一行注释说明为什么要排除它。
另外帮我检查:按这份配置,有没有哪类文件是应该提交但被误排除的?

🔑 本节一句话

AI 负责写,Git 负责让你有权说“这版不要”。 从今天起,每次让 AI 动手之前,先存个档。

上一节2.2 Node.js 与 pnpm 安装指南 下一节2.4 开发必备账号清单