feat(docs): add Netlify deployment guide and data encoding demos
- Add Netlify deployment section with form handling and functions examples - Replace old Git demos with new interactive components - Add comprehensive data encoding visualization demos - Update comparison table with Netlify information
This commit is contained in:
@@ -1,348 +1,558 @@
|
||||
# Git:代码的时光机
|
||||
::: tip 🎯 核心问题
|
||||
**写代码时最怕什么?** 写错了想回退、改崩了想重来、多人同时改同一个文件...这些头疼的事,Git 都能帮你搞定!它就像是代码世界的"时光机",让你随时回到过去,又能和队友在各自的"平行宇宙"里安全开发。
|
||||
:::
|
||||
|
||||
> 💡 **学习指南**:这一章专门写给完全没用过 Git 的人。我们不会上来就让你背命令,而是先搞清楚"Git 到底在帮你解决什么问题",再一步步把命令和概念串起来。读完后,你应该能独立完成:本地提交、创建分支、推送到 GitHub。
|
||||
|
||||
---
|
||||
|
||||
## 0. 最常用的 5 个场景(直接照抄)
|
||||
## 0. 先问一个问题:你有没有经历过这些噩梦?
|
||||
|
||||
如果你只想"立刻能用",先把这块过一遍:每个场景都是现实工作中最常见的 Git 流程。
|
||||
**场景一:版本地狱**
|
||||
|
||||
<GitScenariosDemo />
|
||||
你写论文或者写代码,改到一半发现改错了,想回到三天前的版本——但你找不到了。
|
||||
|
||||
---
|
||||
|
||||
## 1. 为什么要学 Git?三大痛点
|
||||
|
||||
### 1.1 痛点一:版本混乱
|
||||
|
||||
你是否经历过这种绝望?
|
||||
|
||||
```text
|
||||
论文_初稿.doc
|
||||
论文_修改版.doc
|
||||
论文_最终版.doc
|
||||
论文_最终版_打死不改版.doc
|
||||
论文_绝对是最后一次修改版.doc
|
||||
```
|
||||
项目_v1.zip
|
||||
项目_v2_修改版.zip
|
||||
项目_v3_最终版.zip
|
||||
项目_v3_最终版_真的最终版.zip
|
||||
项目_v3_最终版_打死不改了.zip
|
||||
```
|
||||
|
||||
**Git 的解决方案**:不需要复制副本,一个文件夹搞定所有历史版本。想回到哪次修改,一键恢复。
|
||||
每次存一个新副本,硬盘越来越乱,而且你根本记不住哪个版本改了什么。
|
||||
|
||||
### 1.2 痛点二:无法后悔
|
||||
**场景二:协作噩梦**
|
||||
|
||||
::: tip 💡 这个场景你一定遇到过
|
||||
写代码写了 3 小时,突然发现之前的思路更好,但已经改不回去了...或者删错了一段代码,想找回原来的版本。
|
||||
你和队友同时改同一个文件:
|
||||
- 你改了第 10 行,添加了登录功能
|
||||
- 队友改了第 10 行,修复了一个 Bug
|
||||
- 你们用邮件互发代码,结果合并时一个人的改动被另一个人覆盖了
|
||||
- 没人知道最后哪段代码是对的
|
||||
|
||||
有了 Git,这种情况永远不会发生。每次重要节点都能"存档",出问题随时"读档"重来。
|
||||
:::
|
||||
**场景三:没有"后悔药"**
|
||||
|
||||
### 1.3 痛点三:协作冲突
|
||||
|
||||
你和队友同时改同一个文件:
|
||||
|
||||
- 你改了 A 文件的第 10 行
|
||||
- 队友改了 A 文件的第 15 行
|
||||
- 怎么合并?谁覆盖谁?
|
||||
|
||||
**Git 的解决方案**:智能合并,自动处理大部分冲突。只有当你们真的改了同一行代码时,才需要手动决定用谁的。
|
||||
你在生产环境部署了新代码,结果出 Bug 了,想紧急回退到上一个稳定版本——但你不知道怎么回退,只能手忙脚乱地找备份。
|
||||
|
||||
---
|
||||
|
||||
## 2. 核心概念:三区模型
|
||||
**Git 就是为了解决这三个问题而生的。**
|
||||
|
||||
Git 的设计哲学其实很像**寄快递**。
|
||||
Git 是一个**版本控制系统**(Version Control System)。它的本质是:**把你每一次"存档"操作都记录下来,形成一条完整的历史时间线,让你可以随时回到任意一个历史节点。**
|
||||
|
||||
<GitThreeAreasDemo />
|
||||
|
||||
### 2.1 三个区域是什么?
|
||||
|
||||
::: tip 📦 用快递理解 Git
|
||||
想象你在寄快递:
|
||||
|
||||
- **工作区(Working Dir)** = 你的**书桌**。你在这里整理要寄的东西,想怎么乱改都行。
|
||||
- **暂存区(Staging Area)** = **快递盒**。你把要寄的文件放进去(`git add`),准备打包。
|
||||
- **仓库(Repository)** = **快递柜**。一旦你封箱寄出(`git commit`),这个版本就被永久记录下来了。
|
||||
:::
|
||||
|
||||
| 区域 | 作用 | 对应命令 | 状态 |
|
||||
| ---------- | ------------------ | --------------------- | ------------- |
|
||||
| **工作区** | 你当前正在改的代码 | `git status` 查看修改 | 红色 = 未暂存 |
|
||||
| **暂存区** | 准备提交的文件 | `git add` 添加 | 绿色 = 已暂存 |
|
||||
| **仓库** | 永久保存的历史版本 | `git commit` 提交 | 只读,不能改 |
|
||||
|
||||
::: tip 💡 关键理解
|
||||
只有提交到**仓库**的内容才是安全的。工作区里没提交的内容,丢了就真丢了。所以经常`git commit`是好习惯!
|
||||
:::
|
||||
不夸张地说,Git 是现代软件开发最重要的工具之一。几乎所有的公司、所有的开源项目都在用它。
|
||||
|
||||
---
|
||||
|
||||
## 3. 基础工作流:存档三步走
|
||||
## 1. Git 和 GitHub 是一回事吗?
|
||||
|
||||
日常开发中,你 90% 的时间都在重复这三个动作。
|
||||
很多初学者会混淆这两个概念,先澄清一下:
|
||||
|
||||
<GitWorkflowDemo />
|
||||
| | Git | GitHub |
|
||||
| :--- | :--- | :--- |
|
||||
| **是什么** | 一个运行在你电脑上的版本控制工具 | 一个存放 Git 仓库的网站(云端) |
|
||||
| **在哪里** | 你的本地电脑 | 互联网上 |
|
||||
| **能独立使用吗** | ✅ 可以,只管理本地历史 | ❌ 需要配合 Git 使用 |
|
||||
| **类比** | 你本地的日记本 | 存日记的云盘 |
|
||||
|
||||
### 3.1 第一步:修改代码(工作区)
|
||||
简单说:**Git 是工具,GitHub 是托管服务。** 就像 Word 是工具,OneDrive 是云盘一样,两者配合使用,但并不是同一个东西。
|
||||
|
||||
在工作区写写画画,想怎么改就怎么改。这时候修改只在你本地,还没记录。
|
||||
除了 GitHub,类似的服务还有 GitLab、Gitee(国内)等。
|
||||
|
||||
### 3.2 第二步:挑选文件(git add → 暂存区)
|
||||
---
|
||||
|
||||
::: tip 🤔 为什么要先 add 再 commit?
|
||||
你可能问:为什么不能直接 commit 所有修改?
|
||||
## 2. 核心概念:三个区域
|
||||
|
||||
**答案**:因为有时候你不想一次性提交所有改动。
|
||||
这是整个 Git 最重要的设计,理解了这三个区域,你就理解了 Git 的灵魂。
|
||||
|
||||
- 今天改了 5 个文件,但只想提交其中 3 个(完成了一个功能)
|
||||
- 另外 2 个文件还在调试中,不想现在提交
|
||||
Git 把你的文件状态分成三层:
|
||||
|
||||
`git add` 让你有选择权:决定这次提交包含哪些文件。
|
||||
:::
|
||||
**工作区(Working Directory)**
|
||||
就是你的**普通文件夹**,你现在看到的、正在编辑的所有文件都在这里。你随便改,Git 会感知到你改了什么,但不会做任何记录。
|
||||
|
||||
**常用命令**:
|
||||
**暂存区(Staging Area / Index)**
|
||||
这是一个**"预备提交"的中转站**。你可以把工作区里想要保存的文件"放进"暂存区,就像把快递放进快递盒——还没寄出去,但已经选好了要寄什么。
|
||||
|
||||
**仓库(Repository)**
|
||||
这是**永久存档的历史记录库**,藏在 `.git` 文件夹里。每次你执行 `git commit`,暂存区里的内容就会被封存进仓库,形成一条不可篡改的历史记录。
|
||||
|
||||
👇 **动手点点看**:依次点击命令按钮,观察文件在三个区域之间的流转。
|
||||
|
||||
<GitCommitFlow />
|
||||
|
||||
### 为什么要"两步走"(add + commit)?
|
||||
|
||||
很多初学者会问:为什么不能直接一键保存,非要先 `add` 再 `commit`?
|
||||
|
||||
**因为现实开发中,你经常不想把所有改动都一起提交。**
|
||||
|
||||
举个例子:你今天改了 5 个文件:
|
||||
- `login.js`:完成了登录功能(想提交)
|
||||
- `style.css`:调整了登录页样式(想提交)
|
||||
- `debug.log`:临时调试输出(**不想**提交)
|
||||
- `experiment.js`:正在测试的新功能,还没完成(**不想**提交)
|
||||
- `todo.txt`:你的个人备忘(**不想**提交)
|
||||
|
||||
如果没有暂存区,你要么把这 5 个文件全部提交(提交记录很混乱),要么一个都不提交。
|
||||
|
||||
有了暂存区,你可以精确控制:`git add login.js style.css`,只把这两个文件放进快递盒,然后 `commit`,这次提交就清清楚楚地记录"登录功能完成"。
|
||||
|
||||
---
|
||||
|
||||
## 3. 第一次使用 Git:初始化和基础工作流
|
||||
|
||||
### 3.1 安装和初始化
|
||||
|
||||
安装好 Git 后(macOS 自带,Windows 去 git-scm.com 下载),打开终端,进入你的项目文件夹:
|
||||
|
||||
```bash
|
||||
# 添加单个文件
|
||||
git add index.html
|
||||
# 在当前文件夹初始化一个 Git 仓库
|
||||
git init
|
||||
|
||||
# 添加所有修改
|
||||
git add .
|
||||
# Git 会创建一个隐藏的 .git 文件夹,所有历史记录存在里面
|
||||
# 输出:Initialized empty Git repository in .../your-project/.git/
|
||||
```
|
||||
|
||||
# 查看哪些文件被暂存了
|
||||
第一次使用还需要告诉 Git 你是谁(这个信息会附在每次提交记录上):
|
||||
|
||||
```bash
|
||||
git config --global user.name "你的名字"
|
||||
git config --global user.email "你的邮箱"
|
||||
```
|
||||
|
||||
### 3.2 日常工作流:三步存档
|
||||
|
||||
初始化之后,日常开发 90% 的操作就是反复执行这三步:
|
||||
|
||||
**第一步:查看状态**
|
||||
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
|
||||
### 3.3 第三步:封箱提交(git commit → 仓库)
|
||||
这是你用得最多的命令,没有之一。它告诉你:
|
||||
- 你在哪个分支上
|
||||
- 哪些文件被修改了(红色 = 未暂存)
|
||||
- 哪些文件在暂存区里(绿色 = 已暂存,等待提交)
|
||||
|
||||
给这次修改起个名字(比如"修复了登录 Bug"),永久存档。
|
||||
|
||||
**重要:commit message 要写清楚!**
|
||||
**第二步:把文件放进暂存区**
|
||||
|
||||
```bash
|
||||
# ❌ 不好的写法
|
||||
git commit -m "update"
|
||||
# 添加单个文件
|
||||
git add login.js
|
||||
|
||||
# ✅ 好的写法
|
||||
git commit -m "feat: 添加用户登录功能"
|
||||
git commit -m "fix: 修复首页在 iOS 的显示问题"
|
||||
git commit -m "docs: 更新 README 的部署说明"
|
||||
# 添加多个文件
|
||||
git add login.js style.css
|
||||
|
||||
# 添加当前文件夹里所有修改过的文件(用 . 表示"全部")
|
||||
git add .
|
||||
```
|
||||
|
||||
::: tip 💡 commit message 规范
|
||||
推荐用**类型+描述**的格式:
|
||||
> ⚠️ 初学者常见误区:`git add .` 非常方便,但会把所有修改都加进去,包括你不想提交的临时文件。养成精确 add 的习惯,或者用 `.gitignore` 排除不想追踪的文件(后面会讲)。
|
||||
|
||||
- `feat:` 新功能
|
||||
- `fix:` 修复 bug
|
||||
- `docs:` 文档更新
|
||||
- `style:` 代码格式(不影响功能)
|
||||
- `refactor:` 重构(不改变功能)
|
||||
- `test:` 测试相关
|
||||
- `chore:` 构建/工具相关
|
||||
**第三步:提交,写上说明**
|
||||
|
||||
这样以后翻历史记录,一眼就知道每次提交做了什么。
|
||||
:::
|
||||
```bash
|
||||
git commit -m "feat: 添加用户登录功能"
|
||||
```
|
||||
|
||||
`-m` 后面引号里的内容叫做 **commit message**(提交说明)。这是写给未来的自己和队友看的,要写得有意义。
|
||||
|
||||
### 3.3 Commit Message 怎么写才专业?
|
||||
|
||||
```bash
|
||||
# ❌ 没用的写法——看了不知道做了什么
|
||||
git commit -m "update"
|
||||
git commit -m "fix"
|
||||
git commit -m "改了一些东西"
|
||||
|
||||
# ✅ 好的写法:类型 + 冒号 + 一句话描述
|
||||
git commit -m "feat: 添加用户登录功能"
|
||||
git commit -m "fix: 修复首页在 iOS Safari 上的白屏问题"
|
||||
git commit -m "docs: 更新 README 中的部署说明"
|
||||
git commit -m "refactor: 将 UserService 拆分为独立模块"
|
||||
git commit -m "style: 统一代码缩进为 2 空格"
|
||||
```
|
||||
|
||||
**常用前缀含义:**
|
||||
|
||||
| 前缀 | 含义 |
|
||||
| :--- | :--- |
|
||||
| `feat:` | 新功能(feature) |
|
||||
| `fix:` | 修复 Bug |
|
||||
| `docs:` | 文档改动 |
|
||||
| `style:` | 代码格式调整(不影响功能) |
|
||||
| `refactor:` | 代码重构(功能不变,结构优化) |
|
||||
| `chore:` | 构建、工具、依赖相关 |
|
||||
| `test:` | 测试相关 |
|
||||
|
||||
养成这个习惯,几个月后翻历史记录,一眼就知道每次提交做了什么。这在团队协作中尤其重要。
|
||||
|
||||
### 3.4 查看历史记录
|
||||
|
||||
```bash
|
||||
# 详细格式(每次提交的完整信息)
|
||||
git log
|
||||
|
||||
# 简洁格式(每行一条,推荐日常使用)
|
||||
git log --oneline
|
||||
|
||||
# 示例输出:
|
||||
# a1b2c3d (HEAD -> main) feat: 添加用户登录功能
|
||||
# 9f3e1b2 init: 项目初始化
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 平行宇宙:分支(Branch)的魔法
|
||||
## 4. 平行宇宙:分支(Branch)
|
||||
|
||||
这是 Git 最强大的功能!
|
||||
**分支**是 Git 最强大、也是最让初学者困惑的功能。但理解了它之后,你会发现这个设计非常优雅。
|
||||
|
||||
::: tip 🌌 用游戏理解分支
|
||||
想象你在玩游戏,前面有个大 Boss(上线新功能),你怕打不过导致游戏结束(系统崩溃)。
|
||||
### 4.1 分支是什么?用"平行宇宙"来理解
|
||||
|
||||
这时候,你可以开一个**分支(Branch)**,相当于**复制了一个平行世界**:
|
||||
想象你在玩一个角色扮演游戏,游戏里有一个关键选择:
|
||||
- 选择 A:去挑战大 Boss(开发新功能)
|
||||
- 选择 B:继续稳定当前局面(主线不动)
|
||||
|
||||
- 在**平行世界**(新分支)里打 Boss,输了也不怕,因为主世界(主分支)没影响
|
||||
- 打赢了就把成果"合并"回主世界
|
||||
- 多个队友可以在各自的平行世界开发,互不干扰
|
||||
:::
|
||||
如果你直接在主存档上做选择 A,万一失败了,整个游戏进度就毁了。
|
||||
|
||||
<GitBranchMergeDemo />
|
||||
但如果你**复制一个存档**,在副本里去挑战 Boss:
|
||||
- 打赢了?把副本的成果合并回主存档
|
||||
- 打输了?主存档完全没有影响,删掉副本重来
|
||||
|
||||
### 4.1 主分支 vs 开发分支
|
||||
**Git 分支就是这个"副本存档"机制。**
|
||||
|
||||
| 分支类型 | 作用 | 特点 |
|
||||
| ------------------- | -------------- | ------------------------------------ |
|
||||
| **main/master** | 稳定的线上版本 | 只有测试通过的代码才能进来 |
|
||||
| **dev/feature-xxx** | 你的试验田 | 这里炸了地球也没关系,不影响主分支 |
|
||||
| **hotfix-xxx** | 紧急修复 | 生产出 bug 时,从 main 开分支快速修复 |
|
||||
在 Git 里,`main`(或 `master`)分支是你的"主存档",永远保持稳定可用。当你要开发新功能时,你从 main 创建一个新分支,在那里开发、测试,完成后再合并回 main。
|
||||
|
||||
### 4.2 分支操作流程
|
||||
### 4.2 分支的可视化演示
|
||||
|
||||
**创建分支并切换**:
|
||||
👇 **动手点点看**:依次点击命令按钮,观察下方分支图如何分叉、延伸、最终合并。重点关注 HEAD 标签的位置变化——它始终指向"你当前在哪里"。
|
||||
|
||||
<GitBranchVisual />
|
||||
|
||||
### 4.3 分支操作详解
|
||||
|
||||
**创建并切换到新分支:**
|
||||
|
||||
```bash
|
||||
# 创建新分支
|
||||
git branch feature-login
|
||||
# 方式一:先创建,再切换(两步)
|
||||
git branch feature-login # 创建分支
|
||||
git checkout feature-login # 切换过去
|
||||
|
||||
# 切换到新分支
|
||||
git checkout feature-login
|
||||
|
||||
# 或者一步到位:创建并切换
|
||||
# 方式二:一步到位(推荐)
|
||||
git checkout -b feature-login
|
||||
|
||||
# 输出:Switched to a new branch 'feature-login'
|
||||
```
|
||||
|
||||
**在分支上开发**:
|
||||
|
||||
```bash
|
||||
# 在 feature-login 分支上改代码...
|
||||
git add .
|
||||
git commit -m "feat: 添加登录表单"
|
||||
创建分支后,你的命令行提示符会显示当前分支名,比如:
|
||||
```
|
||||
user@mac ~/project (feature-login) $
|
||||
```
|
||||
|
||||
**合并回主分支**:
|
||||
**查看所有分支:**
|
||||
|
||||
```bash
|
||||
# 切回主分支
|
||||
git branch
|
||||
|
||||
# 输出(* 表示当前所在分支):
|
||||
# * feature-login
|
||||
# main
|
||||
```
|
||||
|
||||
**在分支上正常开发:**
|
||||
|
||||
```bash
|
||||
# 在 feature-login 分支上,改代码、add、commit,和平时完全一样
|
||||
git add login.js
|
||||
git commit -m "feat: 添加登录表单 HTML 结构"
|
||||
|
||||
git add login.js api.js
|
||||
git commit -m "feat: 完成登录接口对接"
|
||||
```
|
||||
|
||||
这些提交只在 `feature-login` 分支上,`main` 分支完全不知道你做了什么。
|
||||
|
||||
**切回主分支,合并:**
|
||||
|
||||
```bash
|
||||
# 切回 main
|
||||
git checkout main
|
||||
|
||||
# 合并 feature-login
|
||||
# 把 feature-login 的所有改动合并进来
|
||||
git merge feature-login
|
||||
|
||||
# 删除已合并的分支(可选)
|
||||
# 合并完成后,可以删掉这个分支(可选)
|
||||
git branch -d feature-login
|
||||
```
|
||||
|
||||
::: tip 💡 什么时候用分支?
|
||||
**个人开发**:
|
||||
### 4.4 什么时候该开分支?
|
||||
|
||||
- 要尝试新想法,不确定会不会搞崩现有代码 → 开分支
|
||||
- 修一个复杂 bug,需要多次实验 → 开分支
|
||||
| 场景 | 建议 | 理由 |
|
||||
| :--- | :--- | :--- |
|
||||
| 开发一个新功能 | ✅ 开分支 | 功能完成前不影响主线,随时可以放弃 |
|
||||
| 修复线上紧急 Bug | ✅ 从 main 开 `hotfix-xxx` 分支 | 修复完直接合并上线,不带入未完成的功能 |
|
||||
| 和队友并行开发 | ✅ 各自开分支 | 互不干扰,完成后统一通过 Pull Request 合并 |
|
||||
| 只改一个错别字 | ❌ 直接在 main 改 | 风险极低,没必要额外开分支 |
|
||||
|
||||
**团队开发**:
|
||||
### 4.5 团队常用的分支策略
|
||||
|
||||
- 每个功能一个分支,互不干扰
|
||||
- 开发完提 Pull Request,队友 review 后再合并
|
||||
:::
|
||||
在实际项目中,团队通常会约定好分支的命名和用途:
|
||||
|
||||
| 分支名 | 用途 | 特点 |
|
||||
| :--- | :--- | :--- |
|
||||
| `main` / `master` | 生产环境的稳定代码 | 只有测试通过的代码才能进来,不能直接推送 |
|
||||
| `dev` / `develop` | 日常集成分支 | 所有功能分支先合并到这里,测试通过再上 main |
|
||||
| `feature/xxx` | 具体功能开发 | 如 `feature/user-login`,完成后合并到 dev |
|
||||
| `hotfix/xxx` | 紧急修复 | 从 main 创建,修完直接合并回 main 和 dev |
|
||||
|
||||
---
|
||||
|
||||
## 5. 常用命令速查表
|
||||
## 5. 与队友协作:远程仓库
|
||||
|
||||
| 命令 | 作用 | 人话解释 | 使用频率 |
|
||||
| ----------------------- | ---------- | ------------------------------ | --------------------- |
|
||||
| `git init` | 初始化 | "在这里建个新仓库" | 项目开始时用一次 |
|
||||
| `git status` | 查看状态 | "现在乱不乱?有没有东西没提交?" | ⭐⭐⭐⭐⭐ 极高频 |
|
||||
| `git add .` | 添加所有 | "把桌上所有文件都扔进快递盒" | ⭐⭐⭐⭐⭐ 每次提交前 |
|
||||
| `git add file.txt` | 添加单个 | "只要这个文件" | ⭐⭐⭐⭐ 选择性添加 |
|
||||
| `git commit -m "..."` | 提交 | "封箱!贴上标签,写上这次改了啥" | ⭐⭐⭐⭐⭐ 完成功能时 |
|
||||
| `git log` | 查看历史 | "翻翻以前的日记" | ⭐⭐⭐ 回顾历史 |
|
||||
| `git checkout -b dev` | 创建新分支 | "我要去平行宇宙 dev 探险了" | ⭐⭐⭐⭐ 开新功能 |
|
||||
| `git checkout main` | 切换分支 | "回地球(主分支)看看" | ⭐⭐⭐⭐ 切换任务 |
|
||||
| `git merge dev` | 合并分支 | "把平行宇宙的成果带回地球" | ⭐⭐⭐ 完成功能 |
|
||||
| `git branch` | 查看分支 | "现在有哪些平行世界?" | ⭐⭐⭐ 查看状态 |
|
||||
| `git branch -d feature` | 删除分支 | "这个平行世界不需要了,删掉" | ⭐⭐ 合并后清理 |
|
||||
| `git push` | 推送 | "把本地存档上传到云端" | ⭐⭐⭐⭐⭐ 团队协作 |
|
||||
| `git pull` | 拉取 | "把云端最新存档下载到本地" | ⭐⭐⭐⭐⭐ 团队协作 |
|
||||
到目前为止,你学的都是**本地**的 Git 操作——所有历史记录都存在你自己的电脑上。要和队友共享代码,你需要一个**远程仓库**,也就是 GitHub、GitLab 这样的云端存储。
|
||||
|
||||
---
|
||||
### 5.1 远程仓库的工作原理
|
||||
|
||||
## 6. 进阶:解决冲突与远程协作
|
||||
可以把远程仓库理解为**团队共用的"公共存档"**:
|
||||
|
||||
### 6.1 冲突(Conflict)是什么?
|
||||
- 每个人在本地写代码、commit
|
||||
- 写完后 `push`(上传)到远程仓库
|
||||
- 队友 `pull`(下载)远程仓库的最新内容到自己本地
|
||||
- 这样大家的代码就保持同步了
|
||||
|
||||
当你和队友**同时修改了同一个文件的同一行代码**,Git 就会懵:"我该听谁的?"这就是**冲突(Conflict)**。
|
||||
👇 **动手点点看**:依次点击命令,体验从关联远程仓库、推送、到拉取队友更新的完整流程。
|
||||
|
||||
<GitConflictDemo />
|
||||
<GitSyncDemo />
|
||||
|
||||
### 6.2 怎么解决冲突?
|
||||
### 5.2 第一次推送项目到 GitHub
|
||||
|
||||
**Step 1**:打开冲突文件,会看到这样的标记:
|
||||
**第一步**:在 GitHub 上创建一个新仓库(点击右上角 + → New repository),不要勾选初始化选项。
|
||||
|
||||
```text
|
||||
<<<<<<< HEAD
|
||||
你的代码
|
||||
=======
|
||||
队友的代码
|
||||
>>>>>>> feature-branch
|
||||
```
|
||||
|
||||
**Step 2**:手动选择要保留的代码,或合并两者:
|
||||
|
||||
```text
|
||||
# 保留你的代码 → 删除队友的部分和标记
|
||||
# 保留队友的 → 删除你的部分和标记
|
||||
# 合并两者 → 综合两边的代码
|
||||
```
|
||||
|
||||
**Step 3**:删除所有标记,保存文件
|
||||
|
||||
**Step 4**:重新提交
|
||||
**第二步**:回到本地终端,关联远程仓库:
|
||||
|
||||
```bash
|
||||
git add 解决冲突的文件
|
||||
git commit # Git 会自动生成合并提交
|
||||
# 把本地仓库和 GitHub 上的仓库关联起来
|
||||
# "origin" 是远程仓库的别名,是约定俗成的名字(也可以改,但没必要)
|
||||
git remote add origin https://github.com/你的用户名/仓库名.git
|
||||
|
||||
# 确认关联成功
|
||||
git remote -v
|
||||
# 输出:
|
||||
# origin https://github.com/你的用户名/仓库名.git (fetch)
|
||||
# origin https://github.com/你的用户名/仓库名.git (push)
|
||||
```
|
||||
|
||||
::: tip 💡 避免冲突的最佳实践
|
||||
**第三步**:推送本地内容到远程:
|
||||
|
||||
- **频繁沟通**:队友改同一个文件前,先打个招呼
|
||||
- **小步提交**:不要攒着大量代码最后才提交,增加冲突概率
|
||||
- **分支隔离**:不同功能用不同分支,减少直接冲突
|
||||
- **用 Pull Request**:合并前让队友 review,提前发现问题
|
||||
:::
|
||||
```bash
|
||||
# 第一次推送,-u 的意思是"以后 git push 时,默认推到 origin 的 main 分支"
|
||||
git push -u origin main
|
||||
|
||||
### 6.3 远程仓库(Remote)
|
||||
# 之后每次推送只需要:
|
||||
git push
|
||||
```
|
||||
|
||||
**远程仓库**(比如 GitHub/GitLab)就是**云端的备份中心**。
|
||||
### 5.3 日常协作的命令
|
||||
|
||||
<GitRemoteDemo />
|
||||
**推送(你改了东西,要让队友看到):**
|
||||
```bash
|
||||
git push
|
||||
```
|
||||
|
||||
**核心操作**:
|
||||
**拉取(队友改了东西,你要同步):**
|
||||
```bash
|
||||
git pull
|
||||
```
|
||||
|
||||
| 操作 | 命令 | 作用 |
|
||||
| ------------ | ---------------------------------------------- | ------------------------ |
|
||||
| **关联远程** | `git remote add origin https://github.com/...` | 第一次连接云端 |
|
||||
| **推送** | `git push -u origin main` | 把本地存档上传 |
|
||||
| **拉取** | `git pull` | 把云端最新存档下载并合并 |
|
||||
| **克隆** | `git clone https://github.com/...` | 复制整个仓库到本地 |
|
||||
`git pull` 实际上是两个命令的组合:
|
||||
1. `git fetch`:先去远程仓库下载最新的提交记录
|
||||
2. `git merge`:把下载回来的内容合并到你当前的分支
|
||||
|
||||
::: tip 💡 push 和 pull 的区别
|
||||
**第一次从 GitHub 获取别人的项目:**
|
||||
```bash
|
||||
# 把整个远程仓库复制到本地(只需要做一次)
|
||||
git clone https://github.com/某人/某项目.git
|
||||
|
||||
- **push**:你的本地代码 → 云端(你改了东西,要同步给队友)
|
||||
- **pull**:云端代码 → 你的本地(队友改了东西,你要同步下来)
|
||||
# clone 会自动建立与远程的关联,之后直接 push/pull 就行
|
||||
```
|
||||
|
||||
**最佳实践**:每天开始工作前先`git pull`,下班前`git push`,这样减少冲突。
|
||||
:::
|
||||
### 5.4 push 和 pull 的方向
|
||||
|
||||
```
|
||||
你的电脑(本地仓库) ←→ GitHub(远程仓库)
|
||||
|
||||
git push: 本地 → 远程 (你改了东西,上传给队友)
|
||||
git pull: 远程 → 本地 (队友改了东西,下载到你这里)
|
||||
git clone: 远程 → 本地 (第一次完整复制整个仓库)
|
||||
```
|
||||
|
||||
> **最佳实践**:每天开始工作前先 `git pull`,拿到最新代码;下班或完成一个功能后 `git push`,及时备份并让队友看到你的进展。
|
||||
|
||||
---
|
||||
|
||||
## 7. 总结:Git 的核心思想
|
||||
## 6. 进阶:处理冲突
|
||||
|
||||
Git 不是简单的"版本备份",而是一个**完整的代码协作系统**:
|
||||
冲突是协作中不可避免的,但也没那么可怕。
|
||||
|
||||
| 特性 | 解决的问题 | 生活类比 |
|
||||
| ------------ | ------------------------------- | --------------------- |
|
||||
| **版本管理** | 代码改错了怎么办? | 时光机,随时回退 |
|
||||
| **分支** | 多人同时改同一个文件怎么办? | 平行宇宙,互不干扰 |
|
||||
| **暂存区** | 这次提交不想包含所有修改怎么办? | 快递盒,挑拣要寄的东西 |
|
||||
| **远程协作** | 怎么和队友共享代码? | 云备份,随时随地同步 |
|
||||
| **冲突处理** | 真的改到同一行了怎么办? | 智能合并 + 手动协调 |
|
||||
### 6.1 冲突是怎么发生的?
|
||||
|
||||
**学习建议**:
|
||||
当你和队友**同时修改了同一个文件的同一行**,在合并时 Git 不知道该用谁的版本,就会产生冲突。
|
||||
|
||||
1. **先用起来**:不要等"完全理解"再用,一边用一边理解
|
||||
2. **从简单开始**:个人项目先掌握`add/commit/push/pull`,团队项目再学分支
|
||||
3. **看 Git 图形化工具**:SourceTree、GitHub Desktop 等,可视化帮助理解
|
||||
4. **遇到问题不要慌**:Git 的设计就是为了让你能安全地尝试,大不了`git reset`
|
||||
举个例子:
|
||||
- 你在 `login.js` 第 5 行写了:`const timeout = 3000`
|
||||
- 队友同时在同一行写了:`const timeout = 5000`
|
||||
- 当你 `git pull` 或 `git merge` 时,Git 发现了这个矛盾,就会"暂停"并告诉你:我不知道该用哪个,你来决定。
|
||||
|
||||
### 6.2 冲突文件长什么样?
|
||||
|
||||
Git 会在冲突的地方插入特殊标记:
|
||||
|
||||
```javascript
|
||||
function login() {
|
||||
const url = '/api/login'
|
||||
|
||||
<<<<<<< HEAD
|
||||
const timeout = 3000 // 你的版本
|
||||
=======
|
||||
const timeout = 5000 // 队友的版本
|
||||
>>>>>>> feature/update-timeout
|
||||
|
||||
return fetch(url, { timeout })
|
||||
}
|
||||
```
|
||||
|
||||
- `<<<<<<< HEAD` 到 `=======` 之间:是你当前分支的内容
|
||||
- `=======` 到 `>>>>>>> xxx` 之间:是合并过来的内容
|
||||
|
||||
### 6.3 如何解决冲突?
|
||||
|
||||
**第一步**:打开冲突文件,找到所有 `<<<<<<<` 标记(通常 VS Code 等编辑器会自动高亮)
|
||||
|
||||
**第二步**:决定保留哪段代码,然后手动编辑文件,删掉所有标记符号(`<<<<<<<`、`=======`、`>>>>>>>`)。
|
||||
|
||||
比如决定用 5000(队友的版本):
|
||||
```javascript
|
||||
function login() {
|
||||
const url = '/api/login'
|
||||
const timeout = 5000 // 采用队友的修改
|
||||
return fetch(url, { timeout })
|
||||
}
|
||||
```
|
||||
|
||||
**第三步**:重新提交
|
||||
|
||||
```bash
|
||||
# 标记冲突已解决
|
||||
git add login.js
|
||||
|
||||
# 完成合并提交(Git 会自动生成合并提交信息)
|
||||
git commit
|
||||
```
|
||||
|
||||
### 6.4 减少冲突的好习惯
|
||||
|
||||
- **勤 pull**:开始工作前同步最新代码,减少"你落后太多"的情况
|
||||
- **小步提交**:不要写了一周代码才一次性提交,频繁小提交更容易发现和解决冲突
|
||||
- **分支隔离**:不同功能用不同分支,减少对同一行代码的竞争
|
||||
- **沟通**:要改公共文件(比如 `config.js`)前,跟队友打个招呼
|
||||
|
||||
---
|
||||
|
||||
## 附录:名词速查表
|
||||
## 7. 常用命令速查
|
||||
|
||||
| 名词 | 英文 | 用人话解释 |
|
||||
| -------- | ---------- | ------------------------------------- |
|
||||
| **仓库** | Repository | 存放所有版本历史的数据库 |
|
||||
| **提交** | Commit | 一次完整的版本记录,像存档点 |
|
||||
| **分支** | Branch | 独立的开发线,像平行宇宙 |
|
||||
| **合并** | Merge | 把一个分支的改动整合到另一个分支 |
|
||||
| **冲突** | Conflict | 同一行代码被修改多次,Git 不知道选哪个 |
|
||||
| **暂存** | Stage | 把修改加入"准备提交"的列表 |
|
||||
| **远程** | Remote | 云端的仓库副本(GitHub/GitLab) |
|
||||
| **克隆** | Clone | 复制整个远程仓库到本地 |
|
||||
| **推送** | Push | 本地 → 远程,上传代码 |
|
||||
| **拉取** | Pull | 远程 → 本地,下载代码 |
|
||||
| **检出** | Checkout | 切换到某个分支或版本 |
|
||||
| **HEAD** | - | 当前所在的分支/版本的指针 |
|
||||
<GitCommandCheatsheet />
|
||||
|
||||
---
|
||||
|
||||
## 8. 实战:加入一个团队项目的完整流程
|
||||
|
||||
这是你加入新团队或新项目时的标准操作流程,可以直接照抄:
|
||||
|
||||
```bash
|
||||
# ① 第一天:把项目 clone 到本地(只做一次)
|
||||
git clone https://github.com/team/project.git
|
||||
cd project
|
||||
|
||||
# ② 每天开始工作:先拉取最新代码,确保你的代码是最新的
|
||||
git pull origin main
|
||||
|
||||
# ③ 创建自己的功能分支(不要直接在 main 上改)
|
||||
git checkout -b feature/user-profile
|
||||
|
||||
# ④ 正常开发...写代码...
|
||||
|
||||
# ⑤ 完成一个小功能点后,立即提交(不要攒着)
|
||||
git add src/UserProfile.vue
|
||||
git commit -m "feat: 完成用户头像上传功能"
|
||||
|
||||
git add src/UserProfile.vue src/api/user.js
|
||||
git commit -m "feat: 完成用户资料编辑接口"
|
||||
|
||||
# ⑥ 把自己的分支推送到远程,让队友能看到
|
||||
git push origin feature/user-profile
|
||||
|
||||
# ⑦ 在 GitHub 上创建 Pull Request(PR),请求合并到 main
|
||||
# (这步在 GitHub 网页上操作)
|
||||
|
||||
# ⑧ 等队友 Code Review,按反馈修改,继续 commit + push
|
||||
|
||||
# ⑨ PR 合并后,回到 main,更新本地,删掉功能分支
|
||||
git checkout main
|
||||
git pull
|
||||
git branch -d feature/user-profile
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. .gitignore:哪些文件不应该被追踪?
|
||||
|
||||
有些文件你**不想**提交到 Git 仓库里,比如:
|
||||
- `node_modules/`:依赖包,体积巨大,可以用 `npm install` 重新生成
|
||||
- `.env`:环境变量文件,里面可能有数据库密码、API Key,**绝对不能上传到公开仓库**
|
||||
- `*.log`:日志文件
|
||||
- `.DS_Store`:macOS 自动生成的隐藏文件
|
||||
- `dist/`、`build/`:编译产物,可以重新构建
|
||||
|
||||
在项目根目录创建一个 `.gitignore` 文件,写上不想追踪的文件规则:
|
||||
|
||||
```gitignore
|
||||
# 依赖包
|
||||
node_modules/
|
||||
|
||||
# 环境变量(重要!密码不能提交)
|
||||
.env
|
||||
.env.local
|
||||
|
||||
# 构建产物
|
||||
dist/
|
||||
build/
|
||||
|
||||
# 系统文件
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# 日志
|
||||
*.log
|
||||
```
|
||||
|
||||
GitHub 上有各种语言和框架的 .gitignore 模板:[github.com/github/gitignore](https://github.com/github/gitignore)
|
||||
|
||||
---
|
||||
|
||||
## 名词速查表
|
||||
|
||||
| 名词 | 英文 | 解释 |
|
||||
| :--- | :--- | :--- |
|
||||
| **仓库** | Repository (Repo) | 存放项目所有版本历史的数据库,在 `.git` 文件夹里 |
|
||||
| **提交** | Commit | 一次完整的版本记录,像游戏存档点,附有说明和时间戳 |
|
||||
| **分支** | Branch | 独立的开发线,像平行时间线,互不影响 |
|
||||
| **合并** | Merge | 把一个分支的改动整合到另一个分支 |
|
||||
| **冲突** | Conflict | 同一行代码被多人修改,Git 不知道该用哪个,需要手动解决 |
|
||||
| **暂存** | Stage / Index | 把修改放入"准备提交"列表的操作 |
|
||||
| **远程** | Remote | 云端的仓库副本(GitHub / GitLab / Gitee) |
|
||||
| **克隆** | Clone | 把整个远程仓库完整复制到本地 |
|
||||
| **推送** | Push | 把本地提交上传到远程仓库 |
|
||||
| **拉取** | Pull | 把远程最新内容下载并合并到本地 |
|
||||
| **HEAD** | HEAD | 当前所在分支/提交的指针,表示"你现在在哪里" |
|
||||
| **origin** | origin | 远程仓库的默认别名(约定俗成的名字) |
|
||||
| **stash** | Stash | 临时保存还没 commit 的改动,切换任务时用 |
|
||||
| **PR / MR** | Pull Request / Merge Request | 请求把你的分支合并进主分支,通常需要队友 review |
|
||||
|
||||
Reference in New Issue
Block a user