# Git 与 GitHub 学习及 LeiFlow 项目管理策略

> 整理日期：2026 年 8 月 20 日<br>
> GitHub 账号：`leiflowAI`<br>
> 适用项目：公众号文章、个人定位分析、资产分析、微信小程序、个人网站、AI 课程及视频内容

## 一、总体结论

最优策略不是在“本地文件夹、Obsidian、Git、GitHub”之间四选一，而是明确分工：

> **Obsidian 管思考，Git 管版本，GitHub 管远端代码与协作，敏感资料和大型媒体单独保管。**

## 二、通过类比理解本地文件夹、Obsidian、Git 和 GitHub

把 LeiFlow 事业想象成一个作战体系：

| 工具 | 类比 | 主要职责 |
|---|---|---|
| 本地文件夹 | 办公室文件柜 | 存放所有文件 |
| Obsidian | 参谋部与知识地图 | 连接定位、研究、文章、复盘 |
| Git | 带时间戳的作战日志 | 记录每次修改，能比较、回退 |
| GitHub | 异地指挥中心与项目展厅 | 保存 Git 仓库、协作、部署、展示 |
| iCloud | 文件同步运输车 | 让不同设备看到同一批文件 |
| 备份硬盘/Time Machine | 战略储备库 | 在误删、硬盘故障后恢复数据 |

特别注意：

- iCloud“同步当前状态”，误删也可能同步。
- Git“记录历史版本”，适合文字和代码。
- GitHub“保存远端 Git 仓库”，也提供协作和部署。
- 大视频、客户录音、客户资料不能简单依赖 GitHub。

Git 官方把一次提交定义为对项目状态的一次快照；`git add` 是选择哪些变化进入下一次快照，`git commit` 才是正式归档。[Pro Git：记录变更](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository)

### Git 的核心概念

继续用作战类比：

- `repository / repo`：一个独立任务的完整档案。
- 工作区：你桌上正在修改的材料。
- `git add`：把准备归档的文件放进“呈批夹”。
- `git commit`：签字归档，形成一个可追溯版本。
- `branch`：从当前方案分出一条试验路线。
- `merge`：确认试验可用，合并回正式方案。
- `push`：把本地档案送到 GitHub。
- `pull`：从 GitHub 取回最新档案。
- `.gitignore`：明确哪些文件永不归档。

一句话记忆：

> **改文件 → 看变化 → 选变化 → 做快照 → 传远端。**

对应命令：

```bash
git status
git diff
git add 文件名
git commit -m "说明这次完成了什么"
git push
```

## 三、当前 LeiFlow 文件体系分析

### 1. Obsidian 已经是知识中枢

`leiflow-obsidian` 当前大约有 192 个文件，其中约 155 个为 Markdown 文件，已经形成：

> 学习思考 → 写作输出 → 保险主业 → 复盘反哺

`leiflow-writing`、`leiflow-reflect` 和视频脚本已经通过符号链接连接到 Obsidian。

但是，整个 Obsidian 库里同时存在：

- 客户沟通资料；
- 客户录音；
- 财务风险诊断 PDF；
- 核保预判和配置方案；
- 个人定位、文章与视频稿。

因此：

> **不要把整个 Obsidian 库推到 GitHub，即使是私人仓库。**

私人 GitHub 仓库只允许本人和授权人员访问，但仍然是外部托管系统；私人仓库不能代替专业的客户资料管理与加密备份。[GitHub 仓库可见性说明](https://docs.github.com/en/repositories/creating-and-managing-repositories/about-repositories)

### 2. 项目管理建议

| 项目 | 当前特点 | 建议 |
|---|---|---|
| `leiflow-website` | 文件少、结构直观 | 最适合第一个 Git 练习，先建私人仓库 |
| `leiflow-mini` | 微信小程序代码 | 建立私人 GitHub 仓库，先排查密钥和配置 |
| `leiflow-dailywork` | 文章、定位文档和图片 | 建立私人内容仓库，管理定稿与发布素材 |
| `leiflow-asset invest` | 包含还贷工具和资产分析内容 | 代码进 Git，真实资产数据不进 GitHub |
| `leiflow-video` | 包含代码、脚本和大量视频素材 | 拆分代码与媒体，代码进 Git，素材进媒体存储 |
| `leiflow-cases` | 含客户视频、录音、方案 | 禁止上传 GitHub |
| `leiflow-vpn` | 网络配置类文件 | 禁止上传 GitHub |
| `leiflow-writing` | 公众号方法和链接目录 | 内容以 Obsidian 为源头 |
| `leiflow-workbench` | 技能、模板、交付文档 | 可建立私人 Git 仓库 |

## 四、结合五类工作的最优分工

```mermaid
flowchart LR
    A["灵感、学习、定位研究"] --> B["Obsidian 知识中枢"]
    B --> C["定稿与脱敏"]
    C --> D["文章内容仓库"]
    C --> E["个人网站仓库"]
    C --> F["小程序仓库"]
    D --> G["GitHub 私人仓库"]
    E --> G
    F --> G

    H["客户资料、真实资产数据"] --> I["加密业务存储与备份"]
    J["原始视频、录音、渲染文件"] --> K["媒体硬盘或云盘"]
```

### 1. 公众号文章

- 灵感、素材、草稿、复盘：放 Obsidian。
- 准备发布的最终稿：复制到 `leiflow-dailywork`。
- `leiflow-dailywork` 用 Git 记录每一期的修改。
- 未发布内容先使用私人 GitHub 仓库。
- 将来只把精选已发布文章开放展示。

建议：

> Obsidian 是草稿源头，内容仓库是发布版本档案。

### 2. 个人定位分析

定位是不断迭代的认知，最适合放在 Obsidian。正式版本文档由 Git 记录 V1.0、V1.1、V2.0，不再依赖大量“最终版、最终版2”文件名。

### 3. 资产分析

分成两部分：

- 分析方法、计算公式、网页代码、脱敏示例：进入 Git。
- 真实账户、负债、身份证明、银行流水、数据库：不进入 GitHub。

`debt-planner` 已经有 Git 和一个非 GitHub 远端，不需要立即迁移；先学会看清现有历史和远端关系。

### 4. 微信小程序

`leiflow-mini` 应当使用 Git，并建立私人 GitHub 仓库。

推送前重点排除：

- `project.private.config.json`
- 密钥、AppSecret、Token
- 本地环境配置
- 客户档案和导出数据
- 云数据库备份

### 5. 个人网站

`leiflow-website` 是最好的 Git 入门项目：

- 文件少，容易理解。
- 每次改文案或页面都能马上看到效果。
- 出错容易回退。
- 后续可直接连接自动部署。
- 成熟后可以公开，成为技术能力和个人品牌展示。

## 五、一个任务对应一个仓库

不要建立一个巨大的 `leiflow-all`。

> **一个可以独立运行、独立发布或独立承担责任的项目，就是一个 Git 仓库。**

建议最终形成：

```text
leiflow-website        # 网站，可逐步公开
leiflow-mini           # 小程序，私人
leiflow-content        # 定稿文章与发布素材，私人
leiflow-debt-planner   # 资产分析工具，私人
leiflow-video-tools    # 视频生成代码和模板，私人
leiflow-workbench      # AI技能与工作流，私人
```

以下永远不要成为 GitHub 仓库：

```text
leiflow-cases
leiflow-vpn
客户原始录音和视频
真实家庭资产数据
密钥、Token、AppSecret
```

视频仓库也不要直接上传大型媒体。Git 不擅长比较视频、音频和大型二进制文件；GitHub 建议大型二进制使用 Git LFS，并建议把程序生成文件放在 Git 之外。[GitHub仓库限制](https://docs.github.com/en/repositories/creating-and-managing-repositories/repository-limits)、[Git LFS说明](https://docs.github.com/en/repositories/working-with-files/managing-large-files/about-git-large-file-storage)

## 六、Git 在 Mac 上的安装与结构

当前 Mac 已经安装：

```text
git version 2.50.1
```

GitHub Desktop、Obsidian、VS Code 也都已经安装，因此不需要重新安装 Git。

Git 的结构不是“另外建立一个总文件夹”，而是：

```text
Mac 上安装一次 Git 程序
        │
        ├── leiflow-website/
        │      ├── .git/          ← 这个项目的版本数据库，隐藏目录
        │      ├── .gitignore     ← 不允许进入 Git 的文件
        │      ├── README.md
        │      └── index.html
        │
        └── leiflow-mini/
               ├── .git/
               ├── .gitignore
               ├── README.md
               └── miniprogram/
```

每执行一次：

```bash
git init
```

Git 就会在当前项目内部创建一个隐藏的 `.git` 文件夹。它里面保存：

- 提交历史；
- 分支；
- 文件版本；
- 远端地址；
- 暂存区信息。

`.git` 相当于这个项目自己的“黑匣子”。删除 `.git` 不会删除项目文件，但会丢失这个项目的全部 Git 历史。

## 七、Git 是否必须用终端

不必须。可以使用：

1. GitHub Desktop：最直观，适合入门。
2. VS Code：修改代码时顺手提交。
3. 终端：最清楚、能力最完整。

它们底层调用的都是同一个 Git。

建议：

> **前两周用 GitHub Desktop 理解流程，同时只学六个终端命令。**

```bash
git status                 # 查看现在是什么状态
git diff                   # 查看具体改了什么
git add 文件名              # 选择进入本次归档的内容
git commit -m "修改说明"    # 生成一次本地版本
git log --oneline          # 查看历史
git push                   # 上传到 GitHub
```

GitHub Desktop 是操作面板，终端是直接下命令，两者不会产生两套仓库。

## 八、本地 Git 和 GitHub 的关系

```mermaid
flowchart LR
    A["本地项目文件夹"] --> B["本地 .git 版本库"]
    B -->|"git push"| C["GitHub 远端仓库"]
    C -->|"git pull"| B
    C --> D["分享、协作、部署、展示"]
```

即使断网，本地 Git 仍然可以：

- 查看修改；
- 提交版本；
- 建立分支；
- 恢复历史。

只有 `push`、`pull`、`clone` 等操作需要连接 GitHub。

## 九、`leiflowAI` 账号下的仓库规划

建议先建立：

```text
github.com/leiflowAI/leiflow-website
github.com/leiflowAI/leiflow-mini
```

初始都设置为 Private。

### `leiflow-website`

先设为私人，检查完成后可以改为公开。网站可以进一步使用 GitHub Pages 或其他平台部署。

GitHub 可以保存和发布网站源文件，但“GitHub 仓库”和“用户看到的网站”不是一回事：

- 仓库：保存源代码。
- 部署：把源代码生成可访问的网站。

### `leiflow-mini`

保持私人仓库。GitHub 负责保存小程序代码，但不能代替微信小程序后台发布。正式上线仍要经过：

```text
本地开发
→ Git 提交
→ GitHub 备份
→ 微信开发者工具上传
→ 微信后台审核与发布
```

上传前需要排除：

```text
project.private.config.json
.env
.env.*
密钥、AppSecret、Token
客户资料
云数据库导出文件
```

## 十、AI 课程是否适合建立 GitHub 仓库

适合，但 GitHub 应当管理“课程生产工程”，而不是充当完整的卖课平台。

建议建立私人仓库：

```text
leiflow-ai-course
```

适合放：

```text
leiflow-ai-course/
├── README.md
├── syllabus/             # 课程大纲
├── lessons/              # 每节课程文字稿
├── exercises/            # 练习
├── prompts/              # 提示词模板
├── demos/                # 演示代码
├── slides-source/        # PPT源稿或Markdown
├── checklists/           # 检查清单
└── CHANGELOG.md          # 课程更新记录
```

不要放：

- 原始视频和大型成片；
- 学员姓名、作业和联系方式；
- 客户案例原始资料；
- 未经授权的书籍、课程材料；
- API Key、账号密码；
- 真实保险和资产资料。

推荐“两库策略”：

- `leiflow-ai-course`：私人，完整课程生产资料。
- `leiflow-ai-course-samples`：将来公开，放体验课、公开提示词和示例代码。

视频放网盘、视频平台或课程平台，GitHub 只保存脚本、字幕、代码和版本说明。

## 十一、Fork、Clone 和 Download ZIP 的区别

### Fork：在 GitHub 上复制

假设别人有：

```text
github.com/other/ai-course
```

点击 Fork 后，GitHub 上会出现：

```text
github.com/leiflowAI/ai-course
```

这只是复制到自己的 GitHub 账号，尚未下载到 Mac。

类比：

> Fork 是把别人的整套作战方案复制到你自己的云端办公室。

### Clone：下载成 Git 仓库

要下载到本地，需要执行：

```bash
git clone https://github.com/leiflowAI/ai-course.git
```

或者在 GitHub Desktop 里选择 Clone Repository。

这时 Mac 上才会出现：

```text
ai-course/
├── .git/
├── README.md
└── 其他文件
```

Clone 会下载项目文件和 Git 历史，并自动建立远端联系。

### Download ZIP：只下载文件

点击 Download ZIP：

- 会下载当前文件；
- 不包含 `.git` 历史；
- 不能直接正常 `pull`、`push`；
- 更像拿到一份普通复印件。

因此：

> **想继续开发就 Clone；只想看文件就 Download ZIP。**

## 十二、Fork 后的完整关系

```mermaid
flowchart TD
    A["原作者 GitHub 仓库"] -->|"Fork"| B["leiflowAI 账号下的仓库"]
    B -->|"Clone"| C["你的 Mac 本地仓库"]
    C -->|"Commit"| C
    C -->|"Push"| B
    B -->|"Pull Request"| A
```

通常还会有两个远端名称：

```text
origin    你的 Fork：leiflowAI/项目名
upstream  原作者的仓库
```

- 从 `upstream` 获取原作者更新。
- 向 `origin` 上传自己的修改。
- 如果想把修改贡献回去，再提交 Pull Request。

## 十三、最快上手路线

### 第一阶段：只在网站项目学习本地 Git

先掌握六个动作：

```bash
git status
git diff
git add 文件名
git commit -m "更新首页个人定位文案"
git log --oneline
git restore --staged 文件名
```

练习任务：

1. 给网站首页改一句介绍。
2. 查看修改前后差异。
3. 提交一次。
4. 再改一次。
5. 查看两次提交历史。
6. 恢复或比较旧版本。

### 第二阶段：通过 GitHub Desktop 连接私人仓库

1. 添加 `leiflow-website` 本地仓库。
2. 创建 GitHub 私人仓库。
3. Publish/Push 到 GitHub。
4. 每次修改前 Fetch/Pull，修改后 Commit/Push。

GitHub 官方也以 GitHub Desktop 的“分支—提交—发布—Pull Request”作为入门路线。[GitHub Git入门](https://docs.github.com/en/get-started/learning-to-code/getting-started-with-git)

### 第三阶段：再学习分支

只有在下面这些场景使用分支：

- 网站大改版；
- 小程序增加新功能；
- 尝试新的文章结构；
- AI 修改范围较大，尚未确认效果。

例如：

```bash
git switch -c feature/new-homepage
```

小改错别字、日常保存文章，不必每次建分支。

## 十四、当前确定的双路线实操计划

是的：`LeiFlow-website` 和 `LeiFlow-mini` 是两个独立项目，建议在 GitHub 上分别建立两个对应仓库。

但它们不是“同时自动出现”的。需要先理解三个独立对象：

```mermaid
flowchart LR
    A["本地普通文件夹"] -->|"git init"| B["本地 Git 仓库"]
    B -->|"git remote add origin"| C["GitHub 远端仓库"]
    B -->|"git push"| C
    C -->|"git pull"| B
```

### 三个独立对象

1. **本地普通文件夹**：保存网站、小程序或课程的实际文件。
2. **本地 Git 仓库**：普通文件夹执行 `git init`、生成隐藏的 `.git` 后形成。
3. **GitHub 远端仓库**：位于 GitHub 服务器上的独立仓库。

本地文件夹和 GitHub 仓库不会因为名称相同就自动产生联系。真正建立联系的是：

```bash
git remote add origin GitHub仓库地址
```

其中：

- `remote`：远端仓库；
- `origin`：给这个远端地址取的默认简称；
- GitHub 仓库地址：明确告诉本地 Git 要连接到哪里。

建立连接之后，仍然要通过下面的命令传输已经提交的版本：

```bash
git push
git pull
```

因此，完整逻辑不是“两边同名就自动连接”，而是：

```text
先建立本地 Git 仓库
+
先建立 GitHub 远端仓库
+
用 origin 保存远端地址
+
通过 Push / Pull 传输版本
```

普通 `git push` 本身不会凭空创建 GitHub 仓库。使用 GitHub Desktop 的 Publish repository 或 GitHub CLI 时，看起来像是“一步自动创建”，实际仍然是工具先调用 GitHub 创建远端仓库，再建立 `origin`，最后执行 Push。

### 两种先后顺序

为了同时理解两个方向，采用以下两条路线各练习一次：

```mermaid
flowchart TD
    A["路线一：GitHub 优先"] --> B["在 GitHub 创建 leiflow-ai-course"]
    B --> C["Clone 到 Mac 本地"]
    C --> D["本地修改、Commit、Push"]

    E["路线二：本地优先"] --> F["本地已有 leiflow-website / leiflow-mini"]
    F --> G["检查 .gitignore 并完成本地 Commit"]
    G --> H["在 GitHub 创建空仓库"]
    H --> I["建立 origin 连接并 Push"]
```

这两条路线最后得到的结构完全相同：

```text
本地 Git 仓库
↕ Push / Pull
GitHub 远端仓库
```

区别只在于第一步从哪一端开始。

### 路线一：AI Course 采用 GitHub 优先

当前选择先做 AI Course。建议 GitHub 仓库名称统一使用小写：

```text
leiflow-ai-course
```

本地已经存在一个空文件夹：

```text
/Users/yulei/leiflow-ai-course
```

因为它目前是空的，可以把 GitHub 仓库直接 Clone 到这个位置。

#### 第一步：在 GitHub 创建仓库

登录 `leiflowAI`，选择 New repository，并填写：

```text
Owner：leiflowAI
Repository name：leiflow-ai-course
Visibility：Private
Add a README file：勾选
.gitignore template：None
License：None
```

这里可以勾选 README，因为采用的是 GitHub 优先路线。GitHub 会用 README 生成第一次远端提交，随后 Clone 会把这段历史完整下载到本地。

#### 第二步：Clone 到现有空文件夹

GitHub 仓库创建完成后，在终端执行：

```bash
git clone https://github.com/leiflowAI/leiflow-ai-course.git /Users/yulei/leiflow-ai-course
```

Clone 会一次完成：

- 下载 GitHub 上的 README 和提交历史；
- 在本地文件夹中创建 `.git`；
- 自动把 GitHub 仓库连接为 `origin`；
- 自动建立本地 `main` 与远端 `main` 的关系。

#### 第三步：验证 Clone 结果

```bash
cd /Users/yulei/leiflow-ai-course
git status
git remote -v
git log --oneline
ls -la
```

应当看到：

- `git status` 显示位于 `main` 分支；
- `git remote -v` 显示 `leiflowAI/leiflow-ai-course.git`；
- `git log --oneline` 显示创建 README 的第一次提交；
- `ls -la` 能看到隐藏的 `.git` 文件夹。

#### 第四步：完成第一次本地修改和 Push

在 README 中补充一段 AI 课程说明，然后执行：

```bash
git status
git diff
git add README.md
git commit -m "完善 AI 课程项目说明"
git push
```

刷新 GitHub 页面，如果能看到新的 README 内容和提交记录，就完成了完整闭环：

```text
GitHub 创建
→ Clone 到本地
→ 本地修改
→ Commit
→ Push 回 GitHub
```

### 路线二：网站和小程序采用本地优先

#### 网站当前状态

`leiflow-website` 当前已经：

- 存在 `.git`；
- 存在 `.gitignore`；
- 已有一次本地提交；
- 当前工作区干净；
- 尚未连接 GitHub 远端。

因此，网站不需要再次执行 `git init`，也不需要重新提交全部文件。后续步骤是：

1. 在 GitHub 创建名为 `leiflow-website` 的 Private 空仓库。
2. 不要勾选 README、`.gitignore` 和 License。
3. 在本地建立远端连接并 Push。

```bash
cd /Users/yulei/leiflow-website
git remote -v
git remote add origin https://github.com/leiflowAI/leiflow-website.git
git push -u origin main
```

#### 小程序当前状态

`leiflow-mini` 当前已经：

- 存在 `.git`；
- 位于 `main` 分支；
- 尚无任何 Commit；
- 尚无 GitHub 远端；
- 尚无 `.gitignore`；
- 所有项目文件都处于未跟踪状态。

因此，小程序的安全顺序是：

```text
先建立 .gitignore
→ 检查配置文件和敏感信息
→ 完成第一次本地 Commit
→ 在 GitHub 创建 Private 空仓库
→ 建立 origin
→ Push
```

暂时不要在小程序目录直接执行 `git add .`。

## 十五、关于 `.git` 和 `.gitignore` 的增补说明

### 1. 为什么有些项目没有 `.gitignore`

终端执行：

```bash
git init
```

正常情况下只创建 `.git` 文件夹，不会自动创建 `.gitignore`。

如果某个项目同时出现了 `.gitignore`，它通常是之前由以下来源之一创建：

- 项目脚手架或模板；
- GitHub Desktop；
- VS Code 或其他开发工具；
- AI 编程工具；
- 人工创建。

### 2. 两者的结构区别

```text
项目文件夹
├── .git/          # Git自动创建的版本数据库
├── .gitignore     # 人工制定的“不纳入Git”名单
├── README.md
└── 其他项目文件
```

`.git`：

- 由 `git init` 创建；
- 是一个文件夹；
- 保存提交历史、分支和版本信息；
- 不应该手动编辑里面的内容。

`.gitignore`：

- 是一个普通文本文件；
- 通常需要自己创建；
- 告诉 Git 哪些文件不要追踪；
- 不会删除被忽略的本地文件。

它们以 `.` 开头，在 Mac Finder 里属于隐藏文件。可以按：

```text
Command + Shift + .
```

显示或隐藏。

### 3. 当前三个项目的实际状态

| 本地项目 | `.git` | `.gitignore` | 当前状态 |
|---|---:|---:|---|
| `leiflow-mini` | 有 | 没有 | 已初始化，尚未第一次提交 |
| `leiflow-docs` | 有 | 没有 | 已初始化，尚未第一次提交 |
| `leiflow-website` | 有 | 有 | 已有本地提交，当前工作区干净 |

网站现有的 `.gitignore` 内容是：

```gitignore
.DS_Store
*.key
```

含义：

- `.DS_Store`：忽略 Mac 自动生成的目录信息文件。
- `*.key`：忽略所有以 `.key` 结尾的密钥文件。

### 4. 小程序建议的 `.gitignore`

```gitignore
# Mac自动生成文件
.DS_Store

# 微信开发者工具私人配置
project.private.config.json

# 环境变量和密钥
.env
.env.*

# 依赖目录
node_modules/
miniprogram_npm/
cloudfunctions/**/node_modules/

# 日志文件
*.log
```

提交前还要人工检查：

```text
miniprogram/envList.js
project.config.json
```

确认里面没有 AppSecret、Token、密码或客户数据。

### 5. Docs 建议的 `.gitignore`

```gitignore
# Mac自动生成文件
.DS_Store

# 临时文件
*.tmp
*.bak
```

创建 `.gitignore` 后，先检查再提交：

```bash
git status
git add .
git status
```

第二次 `git status` 是为了确认“即将提交的文件”是否正确。确认后才执行：

```bash
git commit -m "初始化 LeiFlow 文档库"
```

### 6. `.gitignore` 的时机

`.gitignore` 最好在第一次 `git add` 和 `git commit` 之前建立。

如果某个文件已经被 Git 跟踪，后来再把它写进 `.gitignore`，Git 不会自动停止跟踪它。当前 Mini 和 Docs 都还没有第一次提交，正是建立 `.gitignore` 的最佳时机。

## 十六、项目管理原则（阶段总结）

1. **Obsidian 继续做唯一知识中枢**，不整体上传 GitHub。
2. **从 `leiflow-website` 开始学 Git**，因为最小、最直观、风险最低。
3. **代码项目一项目一仓库，默认私人**。
4. **公众号草稿在 Obsidian，定稿进入内容仓库**。
5. **客户资料、真实资产数据、VPN 配置永不进入 GitHub**。
6. **视频代码进 Git，原始视频和渲染文件进媒体存储**。
7. **避免依赖现有符号链接做 Git 备份**：Git 通常只记录链接本身，不会把链接目标中的文章一起上传。
8. **GitHub 不是备份全部人生资料的网盘，而是经过筛选的项目版本库。**

## 十七、AI Course 的 GitHub 优先实操复盘

> 实操日期：2026 年 8 月 20—21 日<br>
> GitHub 账号：`leiflowAI`<br>
> 仓库：`leiflow-ai-course`<br>
> 本地目录：`/Users/yulei/leiflow-ai-course`

这次实操选择了“GitHub 优先”路线：先在 GitHub 建立远端仓库，再 Clone 到 Mac 本地。

```mermaid
flowchart LR
    A["GitHub 创建私人仓库"] --> B["GitHub 创建 README"]
    B -->|"git clone"| C["Mac 本地仓库"]
    C --> D["修改 README"]
    D --> E["Add + Commit"]
    E -->|"Push"| B
```

### 1. 为什么 GitHub 空仓库下会显示两组命令

GitHub 创建一个完全空的仓库后，会给出两类快速设置命令。

第一类是在本地创建新仓库再推送：

```bash
echo "# leiflow-ai-course" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/leiflowAI/leiflow-ai-course.git
git push -u origin main
```

适合：

- 本地已有普通文件夹；
- 本地还没有 `.git`；
- 准备采用本地优先路线。

第二类是推送已经存在的本地 Git 仓库：

```bash
git remote add origin https://github.com/leiflowAI/leiflow-ai-course.git
git branch -M main
git push -u origin main
```

适合：

- 本地已经执行过 `git init`；
- 本地已经有 Commit；
- 只是尚未连接 GitHub。

本次目标是练习“GitHub 优先 → Clone”，因此这两组命令都没有采用。实际操作是先在 GitHub 创建 `README.md` 和第一次提交，再执行 Clone。

### 2. Clone 到本地

```bash
git clone https://github.com/leiflowAI/leiflow-ai-course.git /Users/yulei/leiflow-ai-course
```

Clone 不只是下载文件，它会一次完成：

- 创建本地项目文件夹；
- 下载远端文件；
- 下载 Git 提交历史；
- 创建隐藏的 `.git`；
- 自动添加名为 `origin` 的远端地址；
- 建立本地 `main` 与远端 `origin/main` 的跟踪关系。

验证命令：

```bash
cd /Users/yulei/leiflow-ai-course
ls -la
git status
git remote -v
git log --oneline
```

初次 Clone 成功时得到：

```text
本地：main
远端：origin/main
状态：working tree clean
文件：.git、README.md
```

### 3. 第一次修改、提交和上传

修改 README 后执行：

```bash
git status
git diff
git add README.md
git status
git commit -m "docs: 补充 AI 课程目标"
git log --oneline --decorate -3
git push
```

各步骤含义：

| 命令 | 作用 |
|---|---|
| `git status` | 查看哪些文件发生变化 |
| `git diff` | 查看具体改了哪些行 |
| `git add README.md` | 把 README 放入本次提交的暂存区 |
| 第二次 `git status` | 检查即将提交的文件是否正确 |
| `git commit` | 在本地生成正式版本记录 |
| `git push` | 把本地新提交上传到 GitHub |

### 4. Commit 是叠加历史，不是两份互相冲突的文件

第一次提交添加了初始 README，第二次提交又增加课程目标。GitHub Desktop 点击某条 Commit 时，只显示“这一次增加或删除了什么”，不是显示 README 的最终全文。

```text
第一次提交：增加3行
+
第二次提交：增加4行
=
最新README：共7行
```

因此，历史列表中的两次提交是前后叠加关系，不是两个账号各有一份互相冲突的 README。

## 十八、账号登录、提交作者和远端仓库是三件事

这次实操中最重要的认识之一，是 Git 和 GitHub 存在三套彼此独立的身份信息。

```mermaid
flowchart TD
    A["Git提交作者"] --> A1["user.name + user.email"]
    B["GitHub上传权限"] --> B1["HTTPS凭据或SSH密钥"]
    C["上传目标"] --> C1["origin远端地址"]
```

| 问题 | 由什么决定 |
|---|---|
| Commit 显示是谁写的 | `user.name` 和 `user.email` |
| GitHub 是否允许 Push | 登录凭据、Token 或 SSH Key |
| 内容 Push 到哪里 | `origin` 保存的远端地址 |
| 仓库属于谁 | GitHub 上的仓库所有者 |

### 1. 为什么切换 GitHub Desktop 账号后，旧 Commit 仍显示 `yuleiww`

Commit 生成时，作者姓名和邮箱已经写入提交对象。之后切换 GitHub Desktop 登录账号，不会自动改写已经存在的 Commit。

当最后一次提交还没有 Push 时，可以安全修正作者：

```bash
cd /Users/yulei/leiflow-ai-course
git config user.name "leiflowAI"
git config user.email "leiflow@agent.qq.com"
git commit --amend --reset-author --no-edit
git log -1 --format=fuller
```

这里不使用 `--global`，表示身份只应用于当前仓库，避免影响 `yuleiww` 账号下的其他项目。

参数含义：

- `--amend`：修改最后一次提交；
- `--reset-author`：使用当前仓库配置的姓名和邮箱；
- `--no-edit`：保留原提交说明和文件内容。

Amend 后 Commit 编号改变是正常现象，因为作者信息也是 Commit 内容的一部分。

### 2. 为什么第一次终端 Push 没有同步

终端停在：

```text
Username for 'https://github.com':
```

这不是网络速度问题，而是 HTTPS 远端在等待身份验证。此时 Push 尚未完成，本地通常会显示：

```text
main...origin/main [ahead 1]
```

含义是本地比 GitHub 多一个提交，但尚未上传。GitHub 终端操作不能使用普通网页登录密码，需要 Token、凭据管理器或 SSH。

### 3. GitHub Desktop 在本次实操中的作用

GitHub Desktop 用图形界面完成了：

- 从 `yuleiww` 退出；
- 登录 `leiflowAI`；
- 添加本地 `leiflow-ai-course` 仓库；
- 识别本地领先一个提交；
- 点击 `Push origin` 完成上传。

GitHub Desktop 不是必需工具，它只是 Git 的图形操作面板。终端和 GitHub Desktop 操作的是同一个本地 `.git`。

## 十九、为 `leiflowAI` 配置专用 SSH

由于同一台 Mac 同时使用 `yuleiww` 和 `leiflowAI` 两个 GitHub 账号，为 `leiflowAI` 配置了专用 SSH 密钥和账号别名，避免终端误用另一个账号。

```mermaid
flowchart LR
    A["Mac本地仓库"] --> B["SSH别名 github-leiflowai"]
    B --> C["专用私钥 id_ed25519_leiflowAI"]
    C --> D["GitHub账号 leiflowAI"]
```

### 1. 已有环境检查

Mac 原来已经存在：

```text
~/.ssh/id_ed25519
~/.ssh/id_ed25519.pub
~/.ssh/config
```

原密钥归属未确认，因此没有覆盖或复用，而是新建专用密钥。

### 2. 生成专用密钥

```bash
ssh-keygen -t ed25519 -C "leiflow@agent.qq.com" -f ~/.ssh/id_ed25519_leiflowAI
```

生成：

```text
私钥：~/.ssh/id_ed25519_leiflowAI
公钥：~/.ssh/id_ed25519_leiflowAI.pub
```

安全规则：

- 私钥绝不上传、复制或发送给任何人；
- 公钥 `.pub` 可以添加到 GitHub；
- 建议为私钥设置口令；
- 输入口令时终端不显示字符是正常现象。

### 3. SSH 账号别名配置

在保留原 VPN 配置的基础上，`~/.ssh/config` 增加：

```sshconfig
# GitHub account: leiflowAI
Host github-leiflowai
    HostName github.com
    User git
    AddKeysToAgent yes
    UseKeychain yes
    IdentityFile ~/.ssh/id_ed25519_leiflowAI
    IdentitiesOnly yes
```

关键配置含义：

- `Host github-leiflowai`：自定义账号别名；
- `HostName github.com`：实际仍连接 GitHub；
- `IdentityFile`：只使用 `leiflowAI` 专用私钥；
- `IdentitiesOnly yes`：不尝试其他账号密钥；
- `UseKeychain yes`：由 Mac 钥匙串保存密钥口令。

### 4. 把密钥加入 SSH Agent 和 Mac 钥匙串

```bash
eval "$(ssh-agent -s)"
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_leiflowAI
ssh-add -l
```

`Agent pid 12345` 中的数字只是进程编号，每次启动都可能不同。例如出现 `Agent pid 29906` 完全正常。

### 5. 把公钥添加到 GitHub

复制公钥：

```bash
pbcopy < ~/.ssh/id_ed25519_leiflowAI.pub
```

GitHub 网页路径：

```text
leiflowAI头像
→ Settings
→ SSH and GPG keys
→ New SSH key
```

填写：

```text
Title：Yulei MacBook Pro - leiflowAI
Key type：Authentication Key
Key：粘贴公钥
```

粘贴内容应是一整行，以 `ssh-ed25519` 开头，以密钥注释邮箱结尾。

### 6. 测试 SSH 身份

```bash
ssh -T git@github-leiflowai
```

成功结果：

```text
Hi leiflowAI! You've successfully authenticated, but GitHub does not provide shell access.
```

其中：

- `Hi leiflowAI!`：GitHub识别到正确账号；
- `successfully authenticated`：身份认证成功；
- `does not provide shell access`：GitHub只提供Git服务，不提供普通服务器终端，这是正常说明。

### 7. 把仓库远端从 HTTPS 改成 SSH

原地址：

```text
https://github.com/leiflowAI/leiflow-ai-course.git
```

修改命令：

```bash
cd /Users/yulei/leiflow-ai-course
git remote set-url origin git@github-leiflowai:leiflowAI/leiflow-ai-course.git
git remote -v
```

修改后：

```text
origin  git@github-leiflowai:leiflowAI/leiflow-ai-course.git (fetch)
origin  git@github-leiflowai:leiflowAI/leiflow-ai-course.git (push)
```

验证下载与上传通道：

```bash
git fetch origin
git status
git push
```

成功状态：

```text
Your branch is up to date with 'origin/main'.
Everything up-to-date
```

`Everything up-to-date` 不是没有执行，而是说明 SSH Push 已成功连接，只是当时没有新的提交需要上传。

## 二十、AI Course 的 `.gitignore` 实操

VMark 编辑器在仓库中生成了本地辅助目录：

```text
.vmark/
```

它不属于课程内容，不应该提交到 GitHub。因此，在项目根目录创建 `.gitignore`：

```gitignore
# Mac系统文件
.DS_Store

# VMark编辑器本地数据
.vmark/
```

随后提交并上传：

```bash
cd /Users/yulei/leiflow-ai-course
git add .gitignore
git commit -m "chore: 忽略本地编辑器文件"
git push
git status
```

最终理想状态：

```text
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean
```

## 二十一、以后是否每个仓库都要重新配置 SSH

不需要。SSH 密钥服务于“一台设备上的一个 GitHub 账号”，不是服务于某一个仓库。

```mermaid
flowchart TD
    A["Mac + leiflowAI：配置一次SSH"] --> B["leiflow-ai-course"]
    A --> C["leiflow-website"]
    A --> D["leiflow-mini"]
    A --> E["未来其他leiflowAI仓库"]
```

| 配置 | 需要次数 |
|---|---|
| Mac 安装 Git | 一台 Mac 一次 |
| 给 `leiflowAI` 生成 SSH 密钥 | 一台 Mac、一个账号一次 |
| 在 GitHub 登记公钥 | 每把密钥一次 |
| 设置 `github-leiflowai` 别名 | 一台 Mac 一次 |
| 每个仓库设置 `origin` | 每个仓库一次 |
| `git push -u origin main` | 每个分支第一次一次 |
| 日常 Pull、Commit、Push | 每次工作循环 |

### 1. GitHub 优先的新仓库

以后在 `leiflowAI` 下建立远端仓库，直接使用专用别名 Clone：

```bash
git clone git@github-leiflowai:leiflowAI/仓库名.git
```

例如：

```bash
git clone git@github-leiflowai:leiflowAI/leiflow-ai-course-samples.git
```

Clone 会自动建立正确的 SSH `origin`，不再生成密钥或重新登记公钥。

### 2. 本地优先的网站仓库

在 GitHub 建立 Private 空仓库后：

```bash
cd /Users/yulei/leiflow-website
git remote add origin git@github-leiflowai:leiflowAI/leiflow-website.git
git push -u origin main
```

以后只需：

```bash
git pull --ff-only
git push
```

### 3. 本地优先的小程序仓库

小程序应先建立 `.gitignore`、检查敏感文件并完成第一次本地 Commit，然后连接：

```bash
cd /Users/yulei/leiflow-mini
git remote add origin git@github-leiflowai:leiflowAI/leiflow-mini.git
git push -u origin main
```

不得提交：

- `project.private.config.json`；
- AppSecret、Token、密码；
- 客户资料；
- 云数据库导出文件；
- `.env` 和其他敏感环境配置。

## 二十二、日常最简终端工作流

完成一次性配置后，日常工作不再复杂。

```mermaid
flowchart LR
    A["Pull领取最新版本"] --> B["本地编写和保存"]
    B --> C["Status + Diff检查"]
    C --> D["Add选择文件"]
    D --> E["Commit本地归档"]
    E --> F["Push上传GitHub"]
```

开始工作前：

```bash
cd /Users/yulei/leiflow-ai-course
git pull --ff-only
```

### 22.1 带注释的日常安全版命令

下面这组命令适合日常直接对照执行。示例使用 AI 课程仓库；如果操作小程序或网站，只需替换第一行的文件夹名称。

```bash
# 1. 进入本地项目文件夹
cd ~/leiflow-ai-course

# 2. 开始工作前，先安全地领取 GitHub 上的最新提交
git pull --ff-only
# 作用：把远端的新提交同步到本地。
# --ff-only 表示“只允许快进更新”；如果本地和远端已经分叉，Git 会停止并提示，而不会擅自合并。
# 注意：它不是“只下载有变化的文件”，也不是上传命令。

# 3. 查看整个仓库目前的状态
git status
# 作用：查看哪些文件被修改、哪些是新文件、哪些已经进入暂存区，以及本地分支是否落后或领先远端。

# 4. 查看还没有放入暂存区的具体修改
git diff
# 作用：逐行检查工作区的变化；绿色通常表示新增，红色通常表示删除。

# 5. 选择这一次准备提交的文件（请把 README.md 换成真实文件名）
git add README.md
# 作用：把指定文件放入暂存区，相当于把它装进“本次归档箱”。
# 初学阶段优先写具体文件名，比直接使用 git add . 更稳妥。

# 6. 检查已经放入暂存区、即将提交的具体内容
git diff --staged
# 作用：预览下一次 Commit 到底会包含什么。

# 7. 再检查一次文件清单
git status
# 作用：确认暂存区里只有这一次真正想提交的文件。

# 8. 创建一个本地版本记录
git commit -m "docs: 补充第一课课程大纲"
# 作用：把暂存区内容保存成一次本地 Commit；引号内写清楚“这次完成了什么”。

# 9. 把本地新 Commit 上传到 GitHub
git push
# 作用：上传尚未推送的 Commit；它不会把所有本地文件重新完整上传一遍。

# 10. 上传后验证结果
git status
# 理想结果：working tree clean，并且本地分支与 origin/main 一致。

git log --oneline --decorate -5
# 作用：查看最近 5 次提交，并确认 main 与 origin/main 是否指向同一个 Commit。
```

这组命令可以记成一条流水线：

```text
进入仓库 → Pull 领取 → Status 检查 → Diff 审稿
         → Add 装箱 → Diff --staged 验箱 → Commit 本地归档
         → Push 上传 → Status / Log 验收
```

### 22.2 常用检查和安全撤销命令

```bash
# 查看当前所在分支
git branch --show-current

# 查看本地仓库连接到了哪个 GitHub 仓库
git remote -v

# 查看最近 5 次提交，以及本地和远端分支的位置
git log --oneline --decorate -5

# 把误放进暂存区的文件取出来，但保留文件中的本地修改
git restore --staged README.md

# 查看暂存区是否已经清空，或还剩下哪些文件
git status
```

其中，`git restore --staged README.md` 可以理解为“把文件从本次归档箱中拿出来”，不会删除你已经写入文件的内容。取出后可以继续修改，也可以重新选择要提交的文件。

### 22.3 首次连接仓库时才需要的命令

下面这些不是每天都要执行，而是在新建或首次连接仓库时使用。

GitHub 优先：把 GitHub 上已经存在的仓库第一次下载到本地。

```bash
# 只在第一次把仓库下载到本地时执行
git clone git@github-leiflowai:leiflowAI/leiflow-ai-course.git
```

本地优先：本地项目已经存在，需要第一次连接 GitHub 空仓库。

```bash
# 只在当前项目还不是 Git 仓库时执行一次
git init

# 把默认分支统一命名为 main
git branch -M main

# 只添加一次远端连接；请替换为当前项目真实仓库名
git remote add origin git@github-leiflowai:leiflowAI/leiflow-mini.git

# 第一次上传，并让本地 main 记住对应的远端分支
git push -u origin main
```

第一次成功执行 `git push -u origin main` 后，日常上传只需运行 `git push`。

### 22.4 初学阶段的安全边界

1. 优先使用 `git add 具体文件名`。只有确认 `.gitignore` 已经设置好，并且用 `git status` 检查过全部文件后，才使用 `git add .`。
2. 如果 `git pull --ff-only` 拒绝执行，说明本地与远端可能已经分叉。先停止操作并查看 `git status`，不要直接强制推送。
3. `git restore 文件名` 会丢弃该文件尚未提交的本地修改，它和 `git restore --staged 文件名` 不是一回事。
4. `git reset --hard` 和 `git clean -fd` 可能直接丢失未提交内容。初学阶段不要自行执行，确有需要时先备份并检查目标。
5. 遇到报错时，先保留终端原始信息，再运行 `git status` 和 `git remote -v`，通常就能判断问题发生在文件、分支还是远端连接。

### 22.5 命令作用速查表

| 命令 | 类比 | 主要作用 | 是否会上传到 GitHub |
|---|---|---|---|
| `git pull --ff-only` | 领取云端最新版 | 安全同步远端新提交；遇到分叉就停止 | 否 |
| `git status` | 查看工作台清单 | 检查修改、暂存、未跟踪文件和分支状态 | 否 |
| `git diff` | 查看未装箱稿件 | 检查尚未暂存的逐行变化 | 否 |
| `git add 文件名` | 把文件装进归档箱 | 选择下一次 Commit 要包含的文件 | 否 |
| `git diff --staged` | 开箱验货 | 检查即将提交的内容 | 否 |
| `git commit -m "说明"` | 本地盖章归档 | 创建一次本地版本记录 | 否 |
| `git push` | 把归档送到云端 | 上传本地新 Commit | 是 |
| `git log --oneline --decorate -5` | 查看最近档案目录 | 检查最近提交及本地、远端分支位置 | 否 |
| `git restore --staged 文件名` | 从归档箱取出文件 | 取消暂存，但保留本地修改 | 否 |

推荐习惯：

1. 开始工作前先 Pull；
2. Commit 前查看 Status 和 Diff；
3. 初学阶段优先 `git add 文件名`，避免把无关文件一起加入；
4. 一次 Commit 只表达一个明确变化；
5. Commit 说明写“完成了什么”，不要只写“修改”“更新”；
6. 工作结束后 Push；
7. Push 后再次运行 `git status`，确认本地与远端一致。

GitHub Desktop 可以保留作为查看历史、差异和紧急认证的图形辅助工具，但不是日常上传下载的必经环节。终端已经能够独立完成 Clone、Pull、Commit、Push、分支、合并和故障排查。

## 二十三、更新后的最终结论

1. **Git 的复杂配置主要发生在第一次。** 安装、身份、远端和 SSH 配置完成后，日常只有 Pull、修改、Commit、Push。
2. **GitHub Desktop 和终端不是两套仓库。** 它们操作的是同一个本地 `.git`，可以交替使用。
3. **Commit 作者、GitHub认证账号和 `origin` 是三件独立的事。** 出现账号不一致时分别检查，不能混为一谈。
4. **`leiflowAI` 的专用 SSH 已经是一项可复用基础设施。** 网站、小程序、AI课程及未来仓库都复用 `github-leiflowai`，无需重复生成密钥。
5. **GitHub 优先适合新项目，Clone 一次即可。** 本地优先适合已经存在的项目，建立空远端后连接 `origin`。
6. **每个独立项目一个仓库，默认 Private。** 需要展示或协作时再有选择地公开。
7. **敏感资料、大型视频和本地密钥不进入 GitHub。** `.gitignore` 应在第一次 Commit 前建立。
8. **LeiFlow 的推荐工作体系保持不变：Obsidian 管思考，Git 管版本，GitHub 管远端项目，敏感资料与大型媒体单独保管。**
