Git 和 GitHub 配合使用快速上手
从"改崩了找不回"到"每次改动都能随时回去":Git 是本地的存档器,GitHub 是云端的备份与协作广场。本文把安装、第一次提交、分支合并、提 PR、解冲突、遇错急救全走一遍,每条命令都能照抄。
📅 更新于 2026-09-13
本文校对于 Git @ 2.55.0(2026-06-29 发布)· 官方源:git-scm.com/docs 与 docs.github.com/en/get-started
0030 秒速览:三句话 + 一张处境表
读完这一篇,你能独立做完一件事:在自己电脑上建一个项目文件夹,让它记住每一次改动、随时能翻回任意一个版本,再把它推到 GitHub 上备份、分享、和别人一起改。全程照着命令敲即可,不需要先会编程。
① Git 是装在你电脑上的"存档器",GitHub 是放存档的"云盘 + 协作广场"——两个是不同的东西,不联网也能用 Git 干活;② 一次改动要走三个区:你先改文件(工作区),再挑出要存的(暂存区),最后才按存档键(提交);git status 随时告诉你每份改动停在哪一区;③ 没推到 GitHub 的历史随便改,推上去的历史只用"加一笔"的方式修——这条边界能防止你覆盖掉队友的代码。
先看几个数字,有个量级概念
如果你只有一个下午,按这个顺序走
装 Git、填上你的署名、选一种方式让 GitHub 认得你。做完这一节,后面所有命令才不会卡在"你是谁"上。见 03。
建一个 hello-git 文件夹,写一个文件,提交,推到 GitHub,然后在网页上看到它。这是全篇唯一的"闭环",走通它你就有了肌肉记忆。见 04。
开分支 → 改 → 推送 → 开 Pull Request → 合入 → 删分支。见 07。走通这一条,日常 90% 的场景你就都能应付了。
按你现在的处境,直接跳到这一节
| 你现在的状态 | 直接看 | 为什么先看它 |
|---|---|---|
| 完全没装过,命令行也没怎么用过 | 03 怎么装好并登录 | 先把工具装对,否则后面每条命令都报错 |
| 想赶紧看到"东西真的上云了" | 04 最小例子 | 10 分钟闭环,先有成就感再谈原理 |
| 已经装好,想每天用得顺 | 05 每天敲哪几条 | 日常 90% 时间只用那 8 条命令 |
| 要和别人一起改同一个项目 | 07 网页按钮在哪 + 08 冲突怎么办 | 协作的分岔点全在"开 PR"和"解冲突"这两处 |
| 刚把代码改崩了,想立刻回去 | 09 出错怎么救 | 改崩了也有救,但用错命令会把小事故变成大事故 |
| 打算让 AI 大改一遍代码 | 10 让 AI 改代码前先存档 | AI 时代最便宜的保险,就两步 |
| 看到一句英文报错,不知道什么意思 | 15 报错与排错 | 8 条高频报错的"症状 → 原因 → 解药" |
| 只想查某条命令怎么写 | 12 命令速查表 | 按场景分组的打印级速查,不用重读全文 |
说清 Git 和 GitHub 各干什么、一次改动要经过哪三个区;独立走完"建仓库 → 提交 → 推上云";开分支、合并、开 PR、解冲突;在改崩之后选对"回退"还是"加一笔撤销";以及看报错时知道先执行 git status。本文讲的是日常够用的 Git 与 GitHub,不涉及 Git 内部实现、持续集成与自动部署(英文缩写 CI/CD)流水线和团队权限配置。
01Git 和 GitHub 到底是什么关系?
一句话:Git 是装在你电脑上的版本管理工具——"版本管理"就是替你记录一个文件夹里每一次改动,让你随时能翻回任意一个版本;GitHub 是托管这些记录的网站——把 Git 管的文件夹放到云端,方便备份、分享和多人协作。你在自己电脑上用 Git 干活,再决定要不要把成果推到 GitHub。
它不是什么(先破三个最容易搞混的理解)
以为"用 GitHub 就是装了 Git",断网就干不了活。
没有网络,你照样能用 Git 提交、回滚、开分支、看历史。GitHub 只是 Git 文件夹最常用的"云端家"之一,同类的还有 GitLab、Gitea,甚至你完全可以不用任何网站。
以为上传上去的只是"文件的最新版",跟把文件拖进网盘一样。
谁在什么时候、为什么改了哪一行,都能查、能翻回去。网盘只有最新版,覆盖了就没了。
以为改完文件它自己就记下来了,像编辑器自动保存。
你必须亲手做两步——git add(挑出这次要存的改动)和 git commit(把它存成一个版本)。你不说,它就不记。
先认识五个词,后面就不用猜了
| 你会反复看到的词 | 用日常语言说就是 | 本文哪里会用到它 |
|---|---|---|
| 仓库(repository) | 一个被 Git 接管的项目文件夹,里面装着文件 + 它的全部历史 | 建仓库、克隆仓库,见 04 |
| 提交(commit) | 一次"存档":给整个项目拍一张带备注的快照 | 每天最常做的动作,见 05 |
| 分支(branch) | 从主线岔出去的一条平行开发线,在里面怎么改都不影响主线 | 做新功能、试方案,见 06 |
| 远端(remote) | 你本地仓库在云端的那份副本,通常起名叫 origin | 推上去、拉下来,见 04 |
| 合并请求(Pull Request,简称 PR) | GitHub 上的"请把我这条分支合进主线"的申请,同时是评审区 | 协作的标准动作,见 07 |
它是什么(两句官方定义)
Git 官网对它的定义是:free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency。翻译成日常话:它是免费开源、每个人电脑上都有一份完整历史的版本管理工具——"分布式"这个词的意思是,每个克隆下来的人都拿到一份完整仓库,不是只有一个中央服务器说了算。
GitHub 官方文档说:At the heart of GitHub is an open-source version control system (VCS) called Git.——这里 VCS 是"版本控制系统"的英文缩写,整句的意思是:GitHub 的核心就是一个叫 Git 的开源版本控制系统,它负责把本地成果托管、展示出来,并加上评审、议题、自动化这些协作功能。
Git 在本地到底存了什么?
一个 Git 项目就是你的项目文件夹 + 顶层一个隐藏的 .git 文件夹。.git 就是它的"大脑",里面装着项目的完整历史、一份"当前文件清单"(官方叫 index,索引),以及指向历史各个节点的分支指针。你不用去读它,但要知道两件事:删掉 .git,这个文件夹就退化成普通文件夹,历史全没了;拷贝整个文件夹(含 .git)就等于拷贝了全部历史。
历史是由三种"积木"搭起来的:文件内容块(某个文件在某一刻写了什么)、目录结构块(哪个文件夹里放着哪些文件)、提交(指向一份目录结构,并指向它的上一个提交——无数个提交串成一条链,就是历史长河)。所以"提交"不等于"保存文件",而是给整个项目拍一张带备注的照片,照片按时间串成链。
一次改动要走过哪三个区?
工作区(改)→ git add → 暂存区(挑)→ git commit → 本地仓库(存)→ git push → GitHub(分享)。git status 随时告诉你每份改动现在停在哪个区。
02为什么不用"压缩包 + 网盘"?
如果你只是一个人写点小脚本,Git 最直接的价值是"后悔药";一旦这件事要备份、分享、找人帮忙、长期维护,Git + GitHub 就变成标配。先看你熟悉的老办法能撑到哪一步。
"每天存一个压缩包"到底哪里不够用
- 每天一个
project-2026-09-13.zip,硬盘越堆越多,还分不清哪个是哪个 - 想知道"上周三到底改了哪一行"只能靠记忆
- 两个人同时改,合并靠手动复制粘贴
- 想同时试两个方案,只能再复制一份整个文件夹
- 每次提交只记录"变化",历史再长也不会成倍膨胀
git log查出谁、何时、为什么改了哪一行- 分支并行开发,合并自动完成,冲突会标出来让你逐处决定
- 开分支几乎零成本,试错不污染主线
没有 Git 的四个真实困境
| 困境 | 你会遭遇什么 | 有 Git 之后怎么做 |
|---|---|---|
| 改崩了找不回 | 调样式调了一下午,越想回到上午的版本,发现早被覆盖了 | 一条命令回到任意一次提交,见 09 |
| 换电脑代码丢了 | 代码只在这台电脑里,U 盘拷来拷去还丢过 | git clone 一条命令全量拿回,还带完整历史,见 05 |
| 协作靠微信传文件 | 你改 A 文件、朋友改 B 文件,最后靠压缩包合并到想哭 | 各开各的分支,用 PR 评审后再合入,见 07 |
| AI 改代码不敢放手 | AI 一次改 20 个文件,肉眼根本看不过来 | 先提交存档,再让 AI 改,逐行看差异,坏了整单撤销,见 10 |
GitHub 额外给了什么(Git 本地做不到的)
| 能力 | 它是什么 | 对你的实际用处 |
|---|---|---|
| 云端备份 | 把仓库推到 GitHub 上存一份 | 换电脑、重装系统都不怕 |
| Pull Request 协作流 | 改代码 → 发起合并申请 → 对方评审 → 合入 | 团队协作的标准动作,见 07 |
| Issues 与项目主页 | 记需求、报 bug、展示作品的地方 | 找工作时 GitHub 主页就是你的"代码简历" |
| Actions 自动化 | 推送代码后自动跑测试、自动部署网站 | 本篇不展开,先知道有这回事即可 |
什么时候其实不需要它
诚实一点:Git 不是所有场景都值得用。下面这些情况,用更简单的工具反而更省事——但只要你开始改代码并想留住每一次变化,它立刻变得划算。
| 场景 | 更合适的选择 | 为什么 |
|---|---|---|
| 仓库里只放图片、视频等大文件 | 网盘 / 对象存储 | Git 不擅长存二进制大文件,仓库会被撑大 |
| 一个人写一次性的小脚本 | 本地随手存一份也行 | 没有"版本"需求时,开仓库是多余动作 |
| 多人同时编辑同一份在线文档 | 在线文档的协同编辑 | 文字类实时协作不是 Git 的强项 |
| 需要按行级细粒度审查的代码改动 | 正是 Git + PR | 这才是它的主场,别用别的凑 |
03怎么在 Mac 上装好,并让 GitHub 认得你?
目标:让你的电脑能跑 git 命令,并且 GitHub 知道"这次提交是你做的"。按顺序做完大约 15 分钟,全程不需要管理员权限(也就是不用加 sudo)。
开始前:先打开"终端"
按 Command + 空格,输入"终端"(英文是 Terminal),回车,会弹出一个黑窗口。下面所有命令都在这个窗口里逐行粘贴执行:看到输出符合预期,再贴下一行。
第 1 步:装上 Git(macOS 优先用 brew)
先看系统里是不是已经有了:
git --version
# 有输出如 git version 2.4x 就说明已安装,可跳到第 2 步
如果提示"找不到命令",用 brew 装。brew 是 macOS 上最常用的软件包管理器——可以理解成命令行版的"应用商店",专门装这类命令行工具:
# 安装 Git(大概几分钟,有进度条别关窗口)
brew install git
# 装完再验证一次
git --version
# 期望看到:git version 2.4x 或更高(本文校对时官方最新稳定版是 2.55.0)
macOS 自带一份 Git(藏在 Xcode 命令行工具里),版本常常偏旧,和 git-scm.com 官方文档对不上号。用 brew install git 拿到的更新,出问题时能搜到的答案也更新。
附:这台 Mac 还没有 brew 怎么办
先检查有没有:
brew --version
# 有版本号输出就说明已安装,直接回第 1 步继续
# 若提示 command not found,去 brew.sh 官网复制那行安装命令
# (官网只有一行安装命令,从官网复制最安全,不要从博客复制)
brew 的安装过程可能需要几分钟,并要求你按回车确认,看到 Installation successful! 即可。装完关掉终端重开一个,再执行 brew install git。还有一个应急选项:执行 xcode-select --install 会装上苹果官方的命令行工具(含一份 Git),但版本偏旧,适合应急。
第 2 步:告诉 Git 你是谁(只需做一次)
每一次提交都会盖上"作者"戳,所以要先写上名字和邮箱(邮箱建议用你注册 GitHub 的那个):
git config --global user.name "你的名字"
git config --global user.email "你的邮箱@example.com"
# 检查是否写成功
git config --global --list
# 期望看到 user.name 和 user.email 两行
这里的 --global 表示"对这台电脑上的所有仓库生效",所以只需要做一次。
Git 的 user.name 只是提交记录里的署名,和 GitHub 登录用户名不是一回事,写中文昵称也没问题。真正决定你有没有权限推送的,是下一步的登录凭证。
第 3 步:让 Git 和 GitHub 相认——三种方式选一种
从 2021 年 8 月 13 日起,GitHub 不再接受用登录密码做 Git 操作的认证了(这是官方公告里写明的)。也就是说,你必须用下面三种中的一种,别再用密码试了。新手推荐方式 A。
| 方式 | 你要做什么 | 适合谁 / 代价 |
|---|---|---|
| A. GitHub 官方命令行 gh | 装一个官方小工具,登录时按提示在浏览器里点一下授权 | 推荐新手:一条命令搞定,还能顺便建仓库(见 04) |
| B. HTTPS + 令牌(Token) | 在网页上生成一串令牌,第一次推送时当密码用,让系统记住 | 不装额外工具也能用;令牌要自己保管好 |
| C. SSH 密钥 | 在本机生成一对密钥,把公钥贴到 GitHub 上 | 长期频繁推送的人顺手;初次配置多两步 |
方式 A(推荐新手):装 gh,一路按提示走
# 方式 A(推荐新手):装 GitHub 官方命令行 gh,一路按提示登录
brew install gh
gh auth login
# 按提示选 GitHub.com → HTTPS → Yes(记住凭证)→ 用浏览器授权码登录
# 登录成功后验证
gh auth status
# 期望看到:Logged in to github.com as 你的用户名
顺便说一句:gh auth login 会帮你把 Git 的凭证也配好,之后你甚至可以用 gh 直接在命令行建仓库、开 PR,不必开浏览器。
方式 B:不用 gh,用令牌 + macOS 钥匙串
令牌(Personal Access Token,官方缩写 PAT)是一串长得像密码的字符,用来代替登录密码。先告诉 macOS 帮你记住它:
# 方式 B:不用 gh,用系统钥匙串记住令牌
git config --global credential.helper osxkeychain
# 之后第一次 push 时输入 GitHub 用户名 + 令牌(不是登录密码),
# macOS 会把它存进"钥匙串",以后不再反复要密码。
令牌到底点哪里生成?(GitHub 官方现在推荐另一种)
这是旧教程最容易过期的地方,注意看:GitHub 官方文档现在明确说推荐用"细粒度令牌"(fine-grained token),而不是老的 classic 令牌。两者入口都在同一个地方,但能选的权限粒度不同。按下面点:
登录 GitHub 网页 → 右上角头像 → Settings → 左侧栏最下方 Developer settings → Personal access tokens。下面分两个入口:Fine-grained tokens(推荐)和 Tokens (classic)(老式)。
Name 写"我的 Mac 推送用";Expiration 选 90 天(到期再换,养成习惯)。权限只给能读写你需要的仓库这一档就够——最小权限最安全。如果走 classic 入口,就是勾 repo 这一组,别全勾。
点 Generate 后,页面只会显示一次,立刻复制。下次 git push 要密码时:用户名填你的 GitHub 用户名,密码粘贴这串令牌。macOS 会存进钥匙串,以后免输。
关掉页面就再也看不到完整令牌了(只能吊销重建)。建议存进系统的"钥匙串访问"或密码管理器,不要存备忘录、不要截图发群。
方式 C:SSH 密钥(以后可能会想换)
如果你打算长期频繁推送,可以在本机生成一对密钥:一把私钥留在自己电脑上(绝不外传),一把公钥贴到 GitHub 上。官方文档现在默认推荐用 ed25519 这种密钥算法(你不需要懂它的数学原理,照抄即可):
# 1. 生成一对密钥(一路回车即可,密码短语可留空)
ssh-keygen -t ed25519 -C "你的邮箱@example.com"
# 2. 把公钥复制到剪贴板(macOS 自带 pbcopy)
pbcopy < ~/.ssh/id_ed25519.pub
# 3. 去 GitHub 网页:头像 → Settings → SSH and GPG keys → New SSH key,粘贴保存
# 4. 验证(看到 successfully authenticated 即成功)
ssh -T git@github.com
# 5. 如果仓库原本绑的是 HTTPS 地址,一条命令换成 SSH
git remote set-url origin git@github.com:你的用户名/仓库名.git
第 4 步:一次配好三个全局开关
这三个开关能省掉后面很多莫名其妙的麻烦,建议照抄:
# macOS 用户:提交时自动把换行符转成 LF,避免和 Windows 协作者互相"整行标红"
git config --global core.autocrlf input
# 新仓库默认分支叫 main(和 GitHub 新建仓库保持一致)
git config --global init.defaultBranch main
# 让中文文件名在 git status 里正常显示,而不是 \350 这种转义
git config --global core.quotepath false
| 开关 | 它管什么 | 不配会怎样 |
|---|---|---|
core.autocrlf input | 提交时把换行符统一成 LF(macOS 与 Linux 用的换行符;Windows 用的是 CRLF) | 和 Windows 用户协作时,整个文件会被标成"每一行都改了" |
init.defaultBranch main | 新建仓库时初始分支叫什么 | Git 到 2.55 为止默认仍叫 master(官方说 Git 3.0 会改成 main),和 GitHub 网页的默认名对不上,容易推错分支 |
core.quotepath false | 文件名里的非 ASCII 字符怎么显示 | 中文文件名在 git status 里变成一堆 \350 转义,看不懂 |
验证:4 条命令确认环境 OK
git --version
# → git version 2.x
git config --global --list
# → 能看到 user.name / user.email / credential.helper 等
gh auth status
# → Logged in(如果你装了 gh;没装则跳过这条)
echo "env-ok"
# → 终端本身工作正常(排错用,确认你没贴错窗口)
令牌等于你账号的钥匙。需要别人帮忙时只贴报错文字,打码任何令牌、密码、私钥。不小心发出去了,立刻去 GitHub 的 Settings → Developer settings 里吊销它、重建一个。
官方也提供图形客户端 GitHub Desktop(desktop.github.com),点按钮就能完成克隆、提交、推送。但建议至少跟着本篇走一遍命令行——以后看任何教程、问 AI 都通用。
04最小例子:10 分钟把第一个仓库推上 GitHub
这一节是一条完整闭环:本地建仓库 → 写文件 → 提交 → 推到 GitHub → 在网页上看到它。全程照抄,路径里的中文换成你自己的名字即可。
在桌面建个练习文件夹,进去,让 Git 接管它。执行完 ls -a 应该能看到 .git。
新建 hello.txt,add 挑进暂存区,commit 按下存档键并写备注。
网页点 New repository,名字填 hello-git,不要勾选 Add a README——空仓库最省心,下一步可以直接推。
绑定远端地址后推送,刷新 GitHub 网页,能看到 hello.txt 就成功了。
步骤 1:本地初始化
# ---- 步骤 1:本地初始化 ----
mkdir ~/Desktop/hello-git
cd ~/Desktop/hello-git
git init
# 期望:Initialized empty Git repository ...
ls -a
# 期望:能看到 .git 目录(Git 的"大脑")
步骤 2:写文件 + 第一次提交
# ---- 步骤 2:写文件 + 第一次提交 ----
echo "Hello, Git!" > hello.txt
git status
# 期望:hello.txt 显示为 Untracked(Git 还不认识它)
git add hello.txt
git status
# 期望:hello.txt 变成 new file(已进暂存区)
git commit -m "第一次提交:你好 Git"
# 期望:[main ...] 1 file changed ...
git log --oneline
# 期望:看到你刚写的提交备注(历史链上有第一张照片了)
步骤 4:绑定 GitHub 并推送
# ---- 步骤 4:绑定 GitHub 并推送 ----
# 把下面地址里的"你的用户名"换成你自己的(仓库页绿色按钮 Code 里能复制)
git remote add origin https://github.com/你的用户名/hello-git.git
git branch -M main
git push -u origin main
# 期望:出现 Writing objects / 100%,最后有 "branch 'main' set up to track"
# 验证:刷新 GitHub 仓库网页,看到 hello.txt 和提交备注即成功!
| 命令里的这截 | 它在说什么 | 新手最容易错在哪 |
|---|---|---|
remote add origin <地址> | 给"云端那份仓库"起个名字叫 origin,并记住它的网址 | 网址复制错、或对同一个仓库重复执行(见下方提示框) |
branch -M main | 把当前分支强制改名为 main | 改名不是必须的,只是让本地和 GitHub 默认分支对齐 |
push -u origin main | 把本地的 main 分支推上去,并记住"以后 git push 就推它" | 只有第一次需要 -u,之后直接 git push |
变体:如果建仓库时勾了 README 怎么办
上面要求建"空仓库"是有原因的:空仓库没有任何提交,直接推不会冲突。如果你已经勾了 README(远端比本地多一次提交),二选一:
# 方案 A(推荐新手):删掉重建一个空仓库,最干净
# GitHub 仓库页 → Settings → 最下方 Delete this repository
# 重建时不要勾 Add a README,然后按本章步骤 4 推送
# 方案 B:把远端的 README 先拉下来合并,再推(多学一招 pull)
git remote add origin https://github.com/你的用户名/hello-git.git
git branch -M main
git pull origin main --allow-unrelated-histories
# 会弹出编辑器让你写合并备注:直接 :wq 保存退出即可
git push -u origin main
# 验证:网页上同时看到 hello.txt 和 README.md
--allow-unrelated-histories 是什么意思
本地历史和远端历史"没有共同祖先"(两边各有各的第一次提交),Git 默认拒绝合并。这个参数就是告诉 Git:"我知道它们没关系,硬合。"只在这种"空库碰 README"的场景用,日常不用。
捷径:装了 gh 的话,一行命令建仓 + 推送
# 在项目目录里执行:自动在 GitHub 建仓库 + 绑定 + 推送当前分支
gh repo create hello-git --public --source=. --push
# --public 建公开仓(练习用);想私有就换 --private
# --source=. 表示用当前目录;--push 表示建完直接推 main
# 验证:命令会打印出仓库网址,浏览器打开能看到文件即成功
先学手动流程(init → remote add → push),因为它解释了"本地和远端是怎么连上的";gh 捷径只是把三步合成一步,原理一样。面试、排错、帮别人时,手动流程永远通用。
这说明这个远端已经绑过了。先 git remote -v 看看绑的是谁,绑错了就 git remote remove origin 再重新 add,不要重复 add。
05每天到底该敲哪几条命令?
日常 90% 的时间,你只会用到 8 个命令。记住这个循环:改(编辑)→ 看(status/diff)→ 存(add/commit)→ 同(pull/push)→ 查(log)。
每天开工三件套:status / pull / branch
# 看当前状态:我在哪个分支?哪些文件改了?处在哪个区?
git status
# 开工先同步远端,避免在旧代码上白干(等价于 fetch + merge,见术语表)
git pull
# 看本地有哪些分支,星号是当前所在
git branch
# 看远端有哪些更新可用(不合并,只看看)
git fetch origin
读懂 git status:它其实只说四件事
| 你在输出里看到 | 人话翻译 | 下一步怎么办 |
|---|---|---|
| Untracked(未跟踪,红色) | 新建的文件,Git 还不认识它 | git add 文件名 把它介绍给 Git |
| Changes not staged(改了但没暂存,红色) | 老文件被改了,但还没挑进暂存区 | git add 挑进去,或 git restore 丢弃 |
| Changes to be committed(已暂存,绿色) | 已经进了暂存区,就差按存档键了 | git commit -m "备注" |
| nothing to commit, working tree clean | 干干净净,什么都没改 | 让 AI 大改前必须看到这句,见 10 |
# 典型输出逐行翻译
git status
# On branch main → 你在 main 分支上
# Your branch is up to date → 本地和 GitHub 一样新,不用 pull
# Untracked files: → 下面是新建的、Git 不认识的文件
# new-feature.html → 执行 git add new-feature.html 收编它
# modified: style.css → 老文件被改了,add 后才能提交
把 git status 的完整输出原样贴给 AI(或发到群里问),比只说"出错了"高效 10 倍。Git 的提示信息写得很好,最后一两行通常直接告诉你该执行什么命令。
改完代码的标准收尾:diff → add → commit → push
# 改了哪些行?提交前必看一眼,防止把调试垃圾带进去
git diff
# 只想看大概(哪些文件改了、加减几行)
git diff --stat
# 把改动挑进暂存区(可以只挑部分文件)
git add index.html style.css
# 全部挑进去(含新建/修改;删除文件要用 -A 才会收录删除动作)
git add -A
# 拍照存档:备注写清楚"做了什么",别写"更新""修改"这种空话
git commit -m "首页 hero 加副标题与难度徽标"
# 同步到 GitHub(第一次推某分支要加 -u,后面直接 push 即可)
git push
"提交备注"到底该写什么?
三个月后回来翻历史时,备注是你唯一的线索。判断标准很简单:它能不能让未来的你说出"这次改了什么"。
fix、更新、111、改一下——一周后你自己都看不出这次动了什么,更不敢回退。
登录页手机号校验放宽到 19 号段、首页 hero 补充副标题,方便新手一眼看懂用途——一句话说清"做了什么",必要时加一句"为什么"。
查历史:log 是你的"监控录像"
# 紧凑版历史(一行一条,最常用)
git log --oneline -10
# 谁改了某文件、每次改了什么
git log --oneline -- hello.txt
# 图形化看分支分叉合并(--graph + --all + 装饰)
git log --graph --oneline --all -15
# 看某次提交到底改了哪些行
git show 提交号前7位
| 命令 | 它回答什么问题 | 什么时候用 |
|---|---|---|
git log --oneline -10 | 最近发生了什么? | 每天开工时扫一眼,或提交前确认基线 |
git log --oneline -- 文件 | 这个文件是谁、什么时候改的? | 怀疑某个文件的改动来历时 |
git log --graph --oneline --all | 分支是怎么分叉又合上的? | 合并前后确认图形符合预期 |
git show <提交号> | 这一次提交具体改了哪些行? | 定位某次改动,或评审历史提交 |
git diff / git diff --stat | 我还没提交的改动长什么样? | 每次 add 之前 |
场景 1:给个人作品加云备份
目标:电脑里有个写了一半的网页,推到 GitHub 备份,换电脑也能继续。
cd ~/Desktop/我的作品
git init
git add -A
git commit -m "备份:作品当前进度"
# GitHub 网页建空仓库 my-work(不要勾 README),再执行:
git remote add origin https://github.com/你的用户名/my-work.git
git branch -M main
git push -u origin main
# 验证 1:刷新仓库网页,文件都在;换电脑执行 git clone 同一地址即可继续
git remote -v
# 验证 2:看到 fetch / push 两行都是你的仓库地址,说明绑定正确
git status
# 验证 3:显示 up to date,本地和云端一致,可以安心关机
clone:把别人的仓库整份搬回家
# 把 GitHub 上的仓库(含完整历史)下载到本地
git clone https://github.com/用户名/仓库名.git
cd 仓库名
git log --oneline -5
# 能看到完整历史,说明这是"全量搬家"而不只是下载最新文件
哪些文件不该进仓库?用 .gitignore 说清楚
密码、令牌、系统垃圾(.DS_Store,macOS 自动生成的目录信息文件)、依赖目录(node_modules,装依赖时下载的库文件)都不该进仓库。在仓库根目录建一个 .gitignore 文件,每行写一条"别管它"的规则:
# .gitignore 示例:# 开头是注释,每行一条规则
cat > .gitignore << 'EOF'
.DS_Store
node_modules/
dist/
.env
*.log
EOF
git add .gitignore
git commit -m "添加 .gitignore 忽略系统文件与密钥"
如果 .env 已经提交过一次,再写进 .gitignore 也拦不住。要先把它从跟踪里摘掉(本地文件保留),再提交:
git rm --cached .env
git commit -m "从跟踪中移除 .env(文件保留在本地)"
06分支和合并:怎么开一条"平行宇宙"再合回来?
分支就是一条从主线岔出去的平行开发线。你在分支里随便改、随便提交,主线毫发无损;满意了再把它合回主线。它便宜到几乎零成本,所以"想试个方案"的正确反应是开分支,而不是复制整个文件夹。
开分支 → 改 → 合回:完整走一遍
# 新建并切换到功能分支(起名用英文小写+连字符)
git switch -c feature/hero-subtitle
# 在分支上改代码、提交(和主线互不干扰)
git add -A
git commit -m "hero 区补充副标题"
# 切回主线看看:刚才的改动不在这里,互不影响
git switch main
# 把分支的成果合回主线(先切到 main 再 merge)
git merge feature/hero-subtitle
# 合完确认无误,删掉已完成的分叉
git branch -d feature/hero-subtitle
分支相关命令速查
| 你想干的事 | 命令 | 注意 |
|---|---|---|
| 看看有哪些分支 | git branch | 前面带星号的是你当前所在的分支 |
| 新建一条分支并切过去 | git switch -c 分支名 | 一步到位,最常用 |
| 切换到已有分支 | git switch 分支名 | 切之前最好 git status 确认工作区干净 |
| 把某条分支合进当前分支 | git merge 分支名 | 先切到"接收方"分支,再执行 merge |
| 删掉已合入的分支 | git branch -d 分支名 | -d 会检查是否已合入;-D 是强制删,慎用 |
| 看看远端有哪些分支 | git branch -r | 带 origin/ 前缀的就是云端分支 |
旧教程里的 checkout,现在该用 switch + restore
以前切换分支和还原文件都用 git checkout,一个命令干两件不相干的事。现在官方推荐拆成两个语义更清楚的命令:git switch(切换分支)+ git restore(还原文件)。老命令还能用,但新写法更不容易手滑——切分支时误丢文件改动,正是 checkout 时代最常见的翻车。
merge 和 rebase,我该用哪个?
merge(合并) | rebase(变基) | |
|---|---|---|
| 它做什么 | 把两条分支的历史汇合,多产生一次"合并提交" | 把你分支上的提交"挪"到主线最新处重新演一遍 |
| 历史长什么样 | 保留真实的分叉与汇合,稍乱但诚实 | 一条直线,很干净 |
| 提交编号会变吗 | 不会 | 会——每个提交都会被重写成新的编号 |
| 什么时候用 | 默认用它:团队协作、公共分支一律用它 | 只用在"自己还没推送过"的小分支上,整理成直线 |
| 红线 | 会多出合并提交,不要为小事滥用 | 绝不对已推送的公共分支用,协作者的分支会对不上 |
# 安全流程:先更新主线,再把自己的分支变基到最新,解决冲突,最后合并
git switch main
git pull
git switch feature/hero-subtitle
git rebase main
# 若有冲突:按提示改完 → git add → git rebase --continue
# 想放弃变基:git rebase --abort(回到变基前状态)
场景 3:同时试两个方案,互不干扰
目标:首页想试"深色版"和"浅色版"两套 hero,哪个顺眼留哪个。
git switch -c try/dark-hero
# 改成深色版,提交存档
git add -A
git commit -m "尝试:深色 hero"
git switch main
git switch -c try/light-hero
# 改成浅色版,提交存档
git add -A
git commit -m "尝试:浅色 hero"
# 对比后决定要深色版:
git switch main
git merge try/dark-hero
git branch -d try/dark-hero try/light-hero
# 验证:git log --graph --oneline --all 能看到完整尝试轨迹
不会(前提是已经合入)。删分支只是删掉"指向某个提交的指针",提交本身还在历史里;真删错了,还能用 git reflog 找回来,见 09。
07GitHub 网页上那几个按钮在哪、点了会发生什么?
一个人用叫"备份",多人用才叫"协作"。GitHub 官方推荐的轻量协作流程叫 GitHub Flow:一条分支做一件事,评审通过再合入主线。先认清网页上你真正会点的几个位置。
建仓库:New repository 页面上你只需要动三处
填仓库名(英文、连字符,如 hello-git)。它会成为网址的一部分。
公开或私有。个人练习用公开即可;免费版私有仓库也不限量,别为这个纠结。
先不要勾。勾了会立刻产生一次提交,导致你第一次推送时需要额外处理(见 04 的变体)。
从开分支到 PR 被合入:GitHub Flow 六步
| 第几步 | 你在哪操作 | 确切要做什么 |
|---|---|---|
| ① 同步主线并开分支 | 终端 | git switch main && git pull,再 git switch -c fix/错别字。分支名让人一眼看懂你要干嘛 |
| ② 本地改完并推到远端 | 终端 | git add -A → git commit -m "修复首页错别字" → git push -u origin fix/错别字。注意推的是你的分支,不是 main |
| ③ 开 Pull Request | 仓库网页 | 推送后仓库页会出现一条黄色提示条,点 Compare & pull request,写清标题和说明:改了什么、为什么、怎么验证 |
| ④ 评审:评论、改代码、再推 | PR 页面 + 终端 | 评审人在 PR 里逐行留言;你在本地继续改、继续 push 到同一分支,PR 会自动更新,不用重开 |
| ⑤ 合入 | PR 页面 | 点 Merge pull request → Confirm merge |
| ⑥ 清理 | PR 页面 + 终端 | 网页上点 Delete branch;本地 git switch main && git pull,再 git branch -d fix/错别字 |
那几个容易吓到新手的标签页
| 网页上的入口 | 它是干什么的 | 你什么时候真会用 |
|---|---|---|
| Code | 看文件、复制仓库地址(绿色按钮就在这里) | 刚建完仓库,要复制地址绑定远端时 |
| Pull requests | 所有"求合并"的申请与评审记录 | 开 PR、当评审人时 |
| Issues | 记需求、报 bug 的清单 | 想到一个待办但暂时不做时 |
| Actions | 推送后自动跑测试/部署的机器人 | 本篇不展开,先知道它在这 |
| Settings(仓库级) | 改仓库名、删仓库、管分支保护 | 建错仓库要删掉时(最下方 Delete this repository) |
评审人视角:怎么审别人的 PR(第一次当评审人看这里)
被邀请评审时不用慌,按这个顺序看,最多 10 分钟:
改了什么、为什么改、怎么验证,三段齐了再往下看;缺了就先留言让对方补。
只看红绿两色的差异,问自己三个问题:改动和标题一致吗?有没有混入无关文件?有没有调试垃圾和密钥?
可疑的改动别只靠眼睛,把对方分支拉到本地验证,比看 10 遍都靠谱。
坏例子:"这里不太好"。好例子:"第 42 行的固定宽度在 375px 下会溢出,建议改成 max-width,参考第 05 章做法"。
# 评审时把对方分支拉到本地验证(三步)
git fetch origin 对方分支名
git switch -c review/对方分支名 origin/对方分支名
# 本地运行验证,没问题回网页点 Approve,有问题在对应行留言
# 验完切回自己的活:git switch main + git branch -d review/对方分支名
给别人的仓库做贡献:fork + PR
没有别人仓库的写权限时,先 Fork(复刻一份到自己名下),改完从你的复刻版向原仓库发 PR。原作者的仓库通常记作 upstream(上游),你的复刻记作 origin:
# 1. 网页点 Fork,把仓库复制到自己名下
# 2. clone 自己名下那份到本地
git clone https://github.com/你的用户名/原仓库.git
cd 原仓库
# 3. 把原作者地址记为 upstream,方便以后同步更新
git remote add upstream https://github.com/原作者/原仓库.git
git remote -v
# 期望看到 origin(你的复刻)+ upstream(原作者)两组地址
# 4. 开分支改完推到 origin,再去网页向 upstream 发 PR
# 原作者更新后,把你的复刻同步到最新(定期做一次)
git switch main
git fetch upstream
git merge upstream/main
git push origin main
PR 说明模板(复制就用)
好的 PR 说明让评审人 1 分钟看懂。每次开 PR 时按这个填:
# PR 标题:动词 + 对象(一句话)
修复首页 hero 在小屏幕下换行错乱
# 正文按四段写:
改了什么:hero 副标题加 max-width,小屏字体降到 26px
为什么改:iPhone SE 下副标题溢出,横向出现滚动条
怎么验证:本地 375px 宽度截图 + git diff 确认只动了两处
风险:纯样式,无逻辑改动,可直接合入
格式:动词 + 对象 + 原因/效果。如 首页 hero 补充副标题,方便新手一眼看懂用途、修复登录页 19 号段校验失败,回归测试通过。英文团队常用 fix: / feat: / docs: 前缀,见 12 速查表。
08和别人改了同一个文件,冲突了怎么办?
冲突(merge conflict)指的是:同一文件的同一处被两个人改成了不同样子,Git 无法替你决定听谁的,于是停下合并、让你来选。它不是错误,是 Git 在守规矩——它宁可停下来问,也不擅自丢掉某个人的改动。
冲突处理三步
# 第 1 步:看哪些文件冲突了
git status
# 冲突文件会标为 both modified
# 第 2 步:打开文件,找冲突标记,手动留想要的部分,把标记行删干净,保存
# 第 3 步:告诉 Git 冲突解完了,继续合并
git add 冲突的文件
git commit
# 验证:git status 干净,git log 能看到合并提交
冲突标记长什么样?
打开冲突文件,你会看到三段线把两种版本夹在中间:
<<<<<<< HEAD
<p>欢迎来到我的主页</p>
=======
<p>欢迎来到我的个人主页</p>
>>>>>>> feature/hero-subtitle
| 标记 | 它圈出的是 | 你该怎么做 |
|---|---|---|
<<<<<<< HEAD 到 ======= 之间 | 你当前分支上的版本 | 二选一,或把两段内容手工融合成一段 |
======= 到 >>>>>>> 分支名 之间 | 要被合进来的那个版本 | 同上 |
| 三行标记本身 | 不是代码,是分隔符 | 必须全部删掉,否则文件里就真的多出这几行字符 |
解冲突的原则:看不懂就别删
看不懂对方那段代码是干嘛的,先问再删。宁可把两段都留下、跑起来验证,也不要"看着像重复就删一行"。删之前 git stash 存个现场更保险。冲突文件直接全选"用我的"、不看对方改了什么,是新手最容易造成"队友的活白干"的操作。
怎么少遇到冲突
| 习惯 | 为什么有效 | 什么时候用 |
|---|---|---|
开工前先 git pull | 让本地基线尽量新,减少"你改的时候别人也改了" | 每天开工第一件事 |
| 一条分支只做一件事 | 改动的文件越集中,和别人的重叠面越小 | 每次开分支前想清楚范围 |
| 小步提交、早点推送 | 冲突发现得越早,处理成本越低 | 每完成一个可运行的小步骤 |
| 别多人同时改同一个文件的同一段 | 分工按文件/模块切,而不是按行切 | 分活的时候 |
09出错了怎么救?先记住"改写历史"和"加一笔"
基本功够用后,这几招解决"改错了、合乱了、现场脏了"的实战问题。先记住结论:没推到 GitHub 的历史随便改;推上去的历史只用"加一笔"的方式修。
第 1 招:stash——手头有没做完的活,老板喊你先修线上 bug
# 把没做完的改动暂时"塞进抽屉",工作区恢复干净
git stash push -m "做到一半的首页改版"
git status
# → 工作区干净了,可以放心切分支去修 bug
# bug 修完回来,把抽屉里的活取出来继续
git stash pop
# 抽屉里东西多时先列清单再取
git stash list
第 2 招:reset 和 revert——"撤销"分两种,别用反
把最新一次提交直接抹掉,历史里就像它从没发生过。只许用在"还没推送"的本地提交上;推送过的提交这么干,协作者的分支会原地爆炸。
新建一次"撤销上次改动"的提交,历史完整保留,谁都能看懂来龙去脉。已推送的提交一律用它。
git reset --hard HEAD~1
# 把最新一次提交直接抹掉
# 只许用在"还没 push"的本地提交!
# push 过的提交这么干,协作者会原地爆炸
git revert HEAD
# 新建一次"撤销上次"的提交
# 历史完整保留,谁都能看懂来龙去脉
# push 过的提交一律用它
# 三种 reset 力度(按需选用,默认 --mixed)
git reset --soft HEAD~1
# 回到"已暂存、未提交"状态(改动还在暂存区里)
git reset HEAD~1
# 回到"未暂存"状态(改动还在工作区,最常用)
git reset --hard HEAD~1
# 改动彻底丢弃!执行前务必 git status + git diff 确认
| 写法 | 提交不见了,改动还在哪 | 典型用途 |
|---|---|---|
--soft | 回到暂存区(已挑好、未存档) | 想重新组织这次提交,但保留所有改动 |
不写(默认 --mixed) | 回到工作区(改回来了、没挑) | 最常用:拆提交、补文件 |
--hard | 哪都不在,改动真的没了 | 只在确认不要这些改动时;未提交的改动连 reflog 都救不回 |
1)git status 确认没有别人没同步的活;2)确认这些提交没推送过;3)重要改动先另存或先 git stash。丢了就是真丢了,Git 也救不回未提交的改动。
第 3 招:cherry-pick——只要别人分支里的一两个提交
# 把某次提交"摘"到当前分支(比如只拿一个修 bug 的提交)
git cherry-pick 提交号
# 摘错了?撤销这次摘取(原理同 revert,加一笔修复)
git cherry-pick --abort
第 4 招:tag——给重要版本贴"标签"
# 给当前版本打个 v1.0 标签(发版、上线、交作业都好用)
git tag v1.0
git push origin v1.0
# 标签默认不会跟着 push 走,必须单独推一次
git tag
# 列出所有标签
第 5 招:reflog——Git 的终极后悔药
reset --hard 用错了、分支误删了,别慌:reflog 记录了"当前指针"每一次移动,即使提交看起来丢了也能找回来。
# 场景:误删了分支 feature/hero-subtitle,想找回来
git reflog
# 输出类似:abc1234 HEAD@{3}: commit: hero 区补充副标题
# 找到误删分支最后一次提交的编号,基于它重建分支
git switch -c feature/hero-subtitle abc1234
# 验证:git log --oneline -3,熟悉的提交回来了
# 场景:reset --hard 回退过头了,想回到回退前的位置
git reflog
# 找到回退前 HEAD 所在的提交号,比如 def5678
git reset --hard def5678
# 验证:git log 确认历史恢复;文件内容也回来了
reflog 默认只保留约 90 天,而且只存在你这台电脑上(不会同步到 GitHub)。所以它是"近期事故"的急救包,不是长期保险——长期保险靠的是勤推送。
第 6 招:alias——给长命令起外号
# 以后 git st 就等于 git status,git lg 等于漂亮的历史图
git config --global alias.st status
git config --global alias.co switch
git config --global alias.lg "log --graph --oneline --all -15"
git st
git lg
第 7 招:场景 2——改崩了,一键回到 1 小时前
目标:调样式把页面调碎了,想回到上一次提交时的样子。分两种情况:
# 情况 A:改完还没 commit(工作区是脏的),只想丢弃某个文件的改动
git status
# 确认要丢弃的是 style.css
git restore style.css
git status
# 验证:style.css 回到上次提交时的内容,其他文件不受影响
# 情况 B:已经 commit 了几次,想整体回到上一个提交(且还没 push)
git log --oneline -5
# 找到想回去的那个提交号,比如 abc1234
git reset --hard abc1234
# 验证:git log 确认当前指针已指向目标;页面恢复正常
# 如果已经 push 过:改用 git revert HEAD(加一笔撤销,见本章)
一张表:我到底该用哪个?
| 你的处境 | 用这个 | 为什么不是别的 |
|---|---|---|
| 活没干完,要临时切去修别的东西 | git stash / git stash pop | 不改历史,抽屉式暂存,随时取回 |
| 刚提交,发现漏了一个文件(未推送) | git commit --amend 或 git reset --soft HEAD~1 | 本地历史可以整理,但要先确认没推送 |
| 错误的提交已经推送到公共分支 | git revert <提交号> | 加一笔撤销,协作者的历史不用重写 |
| 想要另一个分支里的某一次修复 | git cherry-pick <提交号> | 只摘那一个提交,不必合整条分支 |
| 要标记一个发版节点 | git tag v1.0 + git push origin v1.0 | 标签是固定别名,给人看;记得单独推 |
| 误删分支 / 回退过头 | git reflog 找到编号再重建/回退 | 它是记录"指针移动"的日志,90 天内有效 |
| 只想丢弃某个文件的未提交改动 | git restore 文件名 | 范围最小,不碰其他文件和历史 |
10让 AI 大改代码前,Git 该怎么配合?
这是 AI 编程时代最重要的一条 Git 习惯:把 Git 当"存档点",让 AI 改之前先存一次,改完用差异逐行审,坏了整单撤销。它便宜、可靠,而且是你对 AI 保持掌控感的最直接手段。
标准流程:存档 → 交给 AI → 审差异 → 决定去留
# AI 动手前:工作区必须是干净的(先把手头活提交了)
git status
# 必须看到 nothing to commit, working tree clean 才继续
git commit -m "存档:AI 重构前基线" --allow-empty
# 即使没改动也打个空提交当书签(可选但好用)
# ---- 把项目交给 AI 改 ----
# AI 改完后:先看它动了哪里,再决定要不要
git diff --stat
git diff
# 满意 → git add -A + git commit -m "AI 重构:xxx"
# 不满意 → git restore . 全部丢弃(还没 add 时)
# 已经 add 但没 commit → git reset 回到未暂存再 restore
# 已经 commit 了 → git reset --hard 回到基线提交号(本地未 push 才可用)
| AI 改完的状态 | 一条命令收拾干净 | 代价 |
|---|---|---|
改了但还没 add | git restore . | 无,改动只是被丢弃 |
已经 add 但没 commit | git reset 再 git restore . | 无,两步都在工作区层面 |
已经 commit(未推送) | git reset --hard 基线提交号 | 这一步提交被抹掉,确认不要才用 |
已经 commit 且推送了 | git revert 提交号 | 加一笔撤销,历史保留 |
AI 每完成一个"可运行"的小步骤就提交一次(小步快跑)。这样即使第 5 步改坏了,也只需回退一步,而不是回到解放前。反过来,把 20 个文件的改动攒在一次提交里,你就失去了逐段取舍的能力。
11新手最容易踩的坑有哪些?
新手 90% 的崩溃集中在下面这几个坑,每个都按"症状 → 原因 → 解药"给全。
7 个高频坑:症状 → 解药
原因:用了 HTTPS 地址却没配好凭证。
解药:用
gh auth login,或配好 credential.helper osxkeychain,见 03。git log 有记录,网页刷新却看不到。原因:只提交没推送——提交只是本地存档,推送才是上传。
解药:执行
git push。原因:忘了写
.gitignore。解药:补上规则后执行
git rm -r --cached node_modules(本地文件保留),再提交。原因:没开分支,实验直接做在主线。
解药:养成开分支的习惯;已经炸了且未推送就
git stash 或 reset 回退,已推送就用 git revert。原因:远端比你新(队友先推了),Git 不肯覆盖。
解药:先
git pull 合并(有冲突就解冲突),再推送。千万别条件反射加 --force。ghp_ 开头的字符串被推送了。原因:没配
.gitignore,且提交前没看差异。解药:立刻去 GitHub 吊销旧令牌、换新的;本地
git rm --cached 摘掉并补 .gitignore。已推送的密钥视为已泄露,必须换。main。原因:切分支前没看
git status。解药:别删提交——
git switch -c 新分支名 把这次提交"带"到新分支,再切回 main 用 git reset HEAD~1 撤掉(未推送才可用)。detached HEAD(头指针分离)是什么,慌了怎么办
某天 git status 告诉你处在 detached HEAD:意思是你的当前指针直接停在某个提交号上,而不是停在一条分支上。此时提交的东西不属于任何分支,一离开就"飘"了。解法:立刻执行 git switch -c 抢救分支名 建一条分支接住它,再慢慢处理。平时都用分支名切换就不会遇到它。
唯独这两件事,绝对不要做
- 推送被拒就硬推,覆盖队友的代码
- 删除
.git目录"重来"(历史全丢) - 冲突文件直接全选"用我的",不看对方改了什么
- 先看状态,再决定怎么走
- 重要现场先存档(stash 或另起分支备份)
- 再 pull / 解冲突 / revert,用"加一笔"修复
# ❌ 不要这样做
git push --force
# push 被拒就硬推,覆盖队友代码
rm -rf .git
# 删除 .git 目录"重来"(历史全丢)
# 冲突文件直接全选"用我的",不看对方改了啥
# ✅ 先看状态,再决定怎么走
git status
git log --oneline -5
# 重要现场先存档(stash 或另起分支备份)
git stash push -m "事故现场备份"
# 再 pull / 解冲突 / revert,加一笔修复
1)绝不对已经推到 GitHub 的公共分支用 git push --force(除非全组明确约好);2)绝不删除 .git 目录"重来"(等于烧掉全部历史,改名备份都比这强)。其他误操作基本都有解。
12命令速查表(一页纸)
左边是处境,右边是命令。先收藏,用时回来翻。
安装与身份
| 场景 | 命令 | 说明 |
|---|---|---|
| 安装 Git | brew install git | macOS 首选;装完 git --version 验证 |
| 设置署名 | git config --global user.name / user.email | 每次提交盖章,只需设一次 |
| 登录 GitHub | gh auth login | 官方 gh 工具一路向导登录,最省心 |
| 记住凭证 | git config --global credential.helper osxkeychain | HTTPS 免反复输令牌(macOS 钥匙串) |
| 生成 SSH 密钥 | ssh-keygen -t ed25519 -C "邮箱" | 长期频繁推送的人用;公钥贴到 GitHub |
每日循环
| 场景 | 命令 | 说明 |
|---|---|---|
| 看状态 | git status | 任何疑惑先执行它,信息最全 |
| 看改动 | git diff / git diff --stat | 提交前必看,防带入垃圾与密钥 |
| 暂存 | git add 文件 / git add -A | 挑进暂存区;-A 含删除动作 |
| 提交 | git commit -m "备注" | 本地存档;备注写清做了什么 |
| 同步远端 | git pull / git push | 开工拉、收工推;首次推某分支加 -u |
| 查历史 | git log --oneline -10 | 紧凑历史;加 --graph --all 看分支 |
| 忽略文件 | cat > .gitignore 写入规则 | 建仓库第一天就配,见 05 |
分支与协作
| 场景 | 命令 | 说明 |
|---|---|---|
| 开分支 | git switch -c 分支名 | 新建并切换,一步到位 |
| 切分支 | git switch 分支名 | 新写法;老教程的 checkout 也能用 |
| 合分支 | git switch main + git merge 分支名 | 先切到目标分支再合入 |
| 删分支 | git branch -d 分支名 | 合完即删;-D 是强制删(慎用) |
| 取全仓 | git clone 地址 | 含完整历史的"搬家",不只是下文件 |
| 绑远端 | git remote add origin 地址 | 一个仓库通常只绑一次 |
| 换远端地址 | git remote set-url origin 新地址 | HTTPS 换 SSH(或反过来)时用 |
| 看远端绑定 | git remote -v | 排查 remote origin already exists 第一步 |
救命命令
| 场景 | 命令 | 说明 |
|---|---|---|
| 丢弃文件改动(未提交) | git restore 文件名 | 只影响该文件,其他不动 |
| 暂存手头活 | git stash push -m "备注" | 塞进抽屉;git stash pop 取回 |
| 撤销已提交(已推送) | git revert HEAD | 加一笔修复,公共历史唯一正解 |
| 回退本地提交(未推送) | git reset HEAD~1 | 改动保留在工作区;--hard 会丢改动 |
| 打版本标签 | git tag v1.0 + git push origin v1.0 | 标签要单独推一次 |
| 找回误删/回退过头 | git reflog | 约 90 天有效,且只在本机 |
| 从跟踪中摘掉文件 | git rm --cached 文件名 | 本地文件保留,只是不再被 Git 跟踪 |
commit 备注前缀(英文团队常用)
| 前缀 | 含义 | 示例 |
|---|---|---|
feat: | 新功能 | feat: 首页 hero 增加副标题 |
fix: | 修 bug | fix: 修复 19 号段校验失败 |
docs: | 只改文档 | docs: 补充安装章节的 brew 说明 |
refactor: | 重构(不改行为) | refactor: 抽取校验函数 |
chore: | 杂务(依赖/配置) | chore: 更新 .gitignore |
常见报错 → 一条命令
| 报错关键词 | 一条命令先试 | 说明 |
|---|---|---|
command not found: git | brew install git | 没装 |
not a git repository | pwd 然后 cd 进项目目录 | 你不在仓库里 |
remote origin already exists | git remote -v | 绑过了,或绑错了 |
non-fast-forward | git pull | 远端比你新,先合再推 |
Authentication failed | gh auth login | 凭证不对,改用令牌 |
Permission denied (publickey) | git remote set-url origin <HTTPS 地址> | SSH 没配好,换回 HTTPS 最快 |
CONFLICT | 打开文件找冲突标记 | 手动二选一后 add + commit |
Your branch is ahead of origin | git push | 这不是报错,是提醒你还没推 |
13术语对照表
第三列不只翻译,更告诉你什么时候用它、别把它当成什么。
| 术语 | 一句话定义 | 为什么重要 / 何时用 · 别当什么用 |
|---|---|---|
| 版本管理(version control) | 记录文件每一次改动、并能翻回任意一次的做法 | 为什么重要:它是 Git 存在的理由;别当成"自动保存"——不提交就不会记录 |
| 仓库(repository) | 一个被 Git 接管的项目文件夹,含全部历史 | 重要:它是"项目 + 历史"的整体,备份仓库等于备份一切;别当成普通文件夹——删掉 .git 就只剩没历史的文件 |
| 提交(commit) | 项目的一次快照 + 作者 + 时间 + 备注 | 何时用:每完成一个可运行的小步骤就提交;别当"保存按钮"狂点——无意义的提交会让历史没法看 |
| 分支(branch) | 指向某个提交的可移动指针,用来开辟平行开发线 | 何时用:做功能、修 bug、做实验前先开分支;别在 main 上直接改——主线要永远可运行 |
| 暂存区(staging area) | add 之后、commit 之前的待提交集合 | 重要:它让你一次只提交"相关改动",把调试垃圾挡在外面;别跳过它——直接一把 commit -a 久了会带进无关改动 |
| 远端(remote) | GitHub 上的仓库副本,通常叫 origin | 何时用:备份、分享、协作时 push/pull;别把它当"唯一正本"——Git 是分布式的,本地也是完整仓库 |
| 克隆(clone) | 把远端仓库全量复制到本地(含历史) | 何时用:换电脑、在新机器上接手项目;别当成"下载 zip"——clone 带历史、可提交可推送,zip 只是死文件 |
| 抓取 / 拉取(fetch / pull) | fetch 只下载更新,pull = fetch + 合并 | 何时用:开工先 pull 同步;想先看看再合就用 fetch;别在有未提交改动时硬 pull——先 stash 或提交 |
| 推送(push) | 把本地提交上传到远端 | 何时用:收工、想备份、想发起 PR 时;别加 --force 推公共分支——会覆盖别人的提交 |
| 合并(merge) | 把两条分支的历史汇合,多产生一次合并提交 | 重要:保留真实分叉过程,适合团队;别为小事滥用——想让历史干净可用 rebase(仅限未推送) |
| 冲突(conflict) | 同一处被改成不同样子,Git 停下来让你选 | 重要:它是保护机制不是错误;别全选"用我的"——先看懂对方改了什么 |
| 合并请求(Pull Request,PR) | GitHub 上的"求合并"申请 + 评审区 | 何时用:任何合入主线的改动都走 PR;别把它当聊天工具——标题写清改了什么、怎么验证 |
| 复刻(Fork) | 把别人的仓库复制一份到自己名下 | 何时用:给无写权限的仓库做贡献;别在复刻版里长期不管——定期从 upstream 同步原作者更新 |
| HEAD(当前指针) | "你在这里"的书签,指向你当前所在的位置 | 重要:reset / revert / switch 全围着它转;别被名字吓到——它就是个书签 |
| .gitignore | 声明"Git 别管这些文件"的规则清单 | 何时用:建仓库第一天就写(密钥/依赖/系统文件);别指望它管住已提交过的文件——要先 rm --cached 摘掉跟踪 |
| 暂存抽屉(stash) | 把未提交的改动临时收起来 | 何时用:手头活没做完、被叫去修更急的 bug 时;别把它当长期仓库——东西多了会忘,处理完及时 pop |
| 变基(rebase) | 把分支上的提交挪到主线最新处重演 | 何时用:整理自己未推送的小分支,让历史成直线;别对已推送的公共分支用——提交编号会变,协作者对不上 |
| 标签(tag) | 给某次提交贴的固定别名(如 v1.0) | 何时用:发版、上线、交作业打标记;别忘标签默认不跟 push 走——要 git push origin 标签名 单独推 |
| 回退日志(reflog) | 本机记录的"当前指针每次移动"的日志 | 何时用:误删分支、回退过头时的急救;别当长期保险——约 90 天过期且不同步到云端 |
14常见问题
brew install git 的那份。系统自带那份更新慢、和官方文档对不上号。装完 git --version 看到 2.4x 以上即可(本文校对时官方最新是 2.55.0,不必追最新,够新就行)。gh auth login 或钥匙串记住令牌,开箱即用。SSH 要生成密钥对、把公钥贴到 GitHub,多两步,但长期频繁推送的人会觉得更顺手。两种地址随时可换:git remote set-url origin 新地址。commit 是本地存档(只存你电脑),push 是把存档同步到 GitHub(云端才有)。所以"提交了但网页上看不到"不是 bug,是你还没推送。反过来 pull 则是把云端的新提交拿回本地。git rm --cached 那个文件 + 补 .gitignore 再提交;3)以后提交前坚持看一眼 git diff。彻底从历史里擦除需要专用重型工具,新手优先做前两步 + 换密钥。reset --hard、不 --force,修复用 revert。node_modules 都不该进。git clone 你的仓库地址,历史、分支、标签全回来。但注意 clone 只带代码,不带你装的环境(brew 包、npm 依赖要重装)。所以好习惯是:仓库里留一份 README.md 写清"装什么、按什么顺序装"。15报错对照表与排错四步
报错信息是英文别怕:复制红色那行,对照下表。90% 的新手报错就是这 8 条。
8 条最高频报错:症状 → 原因 → 解药
| 报错关键词 | 意思 | 解药 |
|---|---|---|
command not found: git | 这台电脑没装 Git | brew install git,见 03 |
not a git repository | 当前目录不是仓库(进错文件夹了) | pwd 确认位置,cd 进项目目录;或 git init 新建 |
remote origin already exists | 远端已经绑过,重复 add | git remote -v 查看,错了先 remove 再 add |
failed to push / non-fast-forward | 远端比你新(队友先推了) | 先 git pull(有冲突就解),再 push;不用 --force |
Authentication failed | 凭证不对(用了登录密码而非令牌) | 改用令牌,见 03;或 gh auth login 重登 |
Permission denied (publickey) | SSH 钥匙没配好 | 新手直接换 HTTPS 地址(git remote set-url);SSH 留到熟练后再配 |
Your branch is ahead of origin | 本地有提交还没推送(这不是报错,是提醒) | 执行 git push 同步即可 |
merge conflict / CONFLICT | 同一行两人改得不一样 | 打开文件找三段线标记,手动二选一后 add + commit,见 08 |
排错通用四步(背下来)
Git 报错通常最后 1–2 行是人话(以 hint: 开头的行往往直接给命令)。先 git status,再看报错全文,别只看第一行。
动手修之前 git stash push -m "排错前备份",或另起分支 git switch -c backup/排错前。修坏了还有退路。
优先级:GitHub Docs 相关页 → git-scm.com/docs → 仓库 Issues。贴给 AI 时带上 status 输出 + 完整报错 + 你刚执行的命令。
git status 干净、git log --oneline -3 符合预期、该推的推了。三个都对才算修完。
求助模板(直接复制去问 AI 或发群)
# 把下面三段输出贴出去,对方 1 分钟就能定位(记得打码令牌)
git status
git log --oneline -5
# + 你刚执行的命令 + 完整报错文字 + 你的目标(想达到什么效果)
1)Git 几乎所有操作都可逆(reflog 兜底);2)报错信息里常自带解法(找 hint:);3)你遇到的报错,全球新手每天都在遇到,官方文档和搜索引擎里一定有答案。
99一句话总结
Git 是本地的"存档器"(改 → add → commit),GitHub 是云端的"备份 + 协作广场"(push → PR → merge):真正的分界线只有一条——没推送的历史随便改,推送过的历史只用"加一笔"的方式修。记住口诀"开工拉、收工推、提交前看 diff、实验开分支、公共历史用 revert"。今天走完 04 最小例子,你就已经跨过了从"只会下载 zip"到"能管住自己代码历史"的那道坎。
学完自测:6 题全对算出师
- 不用看书写出"改完代码到推上 GitHub"的 4 条命令(答案:
add→commit→pull→push,diff是检查动作,见 05)。 - 说出
commit和push的区别(一句:前者存本地,后者同步云端)。 - 说出
reset --hard和revert分别用在什么时候(未推送的本地 vs 已推送的公共历史)。 - 独立走完一次"分支 → 推送 → PR → 合并 → 删分支"(07 的六步流程)。
- 故意制造一次冲突并亲手解掉(08 的三步)。
- 给自己的仓库写一份 50 字以上的
README(含安装与运行步骤),并推上去。
下一步练习路线(3 天)
Day 1:把最小例子亲手走通
照 04 做出 hello-git 并推上 GitHub,验证网页能看到文件。再故意改坏一个文件,用 git restore 救回来。
Day 2:分支 + .gitignore
给自己的小项目加 .gitignore,开分支做一次"实验性改动"再合回,顺手打个 v1.0 标签。
Day 3:完整 PR 协作
找朋友(或自己的第二个账号)互相 fork、发 PR、评审、合入,亲手解一次冲突。从此告别微信传压缩包。
三天走完,你就具备了"独立用 Git + 在 GitHub 上协作"的完整能力。之后遇到新命令,先查 12 速查表,再看官方文档,足够应付日常绝大多数场景。
98参考来源与证据边界
本篇的关键事实都对照官方来源核对过(均为官方文档或官方博客,排名按"讲明白"与"可核实"兼顾的顺序)。
官方一手来源
- Git 官方网站(git-scm.com)—— Git 的定义原话(free and open source distributed version control system…)、下载入口与 Pro Git 全书。
- Git 官方参考文档(git-scm.com/docs)—— 其中
git-init明确写了:初始分支名默认仍是master,官方计划在 Git 3.0 改为main,并可用init.defaultBranch配置;git-switch、git-restore是拆分后的推荐写法。 - git/git 官方仓库(github.com/git/git/releases)—— 版本锚点:本文校对时最新稳定版是 v2.55.0,官方仓库的标签时间戳为 2026-06-29。
- GitHub Docs 入门(docs.github.com/en/get-started)—— "GitHub 的核心是 Git"的定义、GitHub Flow 的六步分支工作流、Set up Git 三步。
- GitHub Docs:管理个人访问令牌(managing-your-personal-access-tokens)—— 官方当前明确建议优先用细粒度令牌(fine-grained),而不是 classic 令牌;并说明命令行下推荐改用 GitHub CLI 或 Git Credential Manager。
- GitHub Blog:Git 操作的令牌认证要求(token-authentication-requirements-for-git-operations)—— 原文:Beginning August 13, 2021, we will no longer accept account passwords when authenticating Git operations on GitHub.com.
- GitHub Docs:关于大文件(about-large-files-on-github)—— 单文件超过 50 MiB 警告、超过 100 MiB 被拒;仓库建议小于 1 GB、强烈建议小于 5 GB。(另:100 MiB 是普通仓库上限,2 GiB 是 Git LFS 的单文件上限,两者不是一回事。)
- GitHub Docs:生成 SSH 密钥(generating-a-new-ssh-key)—— 默认推荐
ssh-keygen -t ed25519,旧系统才用 RSA 4096。 - GitHub CLI 文档(gh repo create 手册、GitHub CLI quickstart)——
gh auth login、gh repo create与--source/--push的用法。 - GitHub Octoverse 2024(octoverse-2024)—— 规模数字:2023 年初开发者总数突破 1 亿,2024 年公开/私有项目总量约 5.18 亿。
本文自己做的核对
- 默认分支名:没有照抄"新仓库默认就叫 main",而是去读了 Git 官方
git-init文档原文,确认默认仍是master、Git 3.0 才改main、可用init.defaultBranch覆盖——所以文中的做法是显式配置,不是依赖默认值。 - 版本日期:2.55.0 的发布时间不是凭记忆写的,而是取官方仓库的标签时间戳(2026-06-29)核对。
- 令牌类型:核对 GitHub 官方文档时发现它已改为优先推荐细粒度令牌,而常见的旧教程只讲 classic,本文据此补上了这个区别。
- 大文件上限:核对官方文档的数据变量,确认 50 MiB / 100 MiB / 1 GB / 5 GB 四个数字;并纠正了"单次 push 2 GiB 上限"这一常见误传(2 GiB 是 Git LFS 的单文件上限)。
证据边界与时效
- 版本口径。本文校对于 Git @ 2.55.0(2026-06-29 发布),这是本文
learn:based-on的锚点。Git 的核心命令多年稳定,但默认分支名、GitHub 网页按钮文案与令牌界面可能微调——这也是本文标shelf-life=evolving的原因。 - 没有做的事。本篇没有覆盖 CI/CD 流水线、团队权限与分支保护规则、Git 内部实现(对象存储格式、打包算法);也没有提供 Windows 与 Linux 的安装步骤。
- 一处口径提醒。文中"90% 的新手报错""日常 90% 的时间"是经验性说法,不是统计结论;真正需要精确数字的地方(版本、文件上限、发布日期)都已标明出处。
- 网页描述可能过期。GitHub 的界面位置(如令牌入口、黄色提示条)本文按官方文档描述,若与你看到的页面不一致,请以 docs.github.com 当前页面为准。