GIT.md 9.4 KB

Git 工作流

这个仓库已经 git init,首次提交完成。下面是怎么用,以及为什么这么用。


为什么这个仓库特别适合 git

不是所有项目都值得上 git。这个仓库有三条天然契合:

特性 带来的好处
原材料只增不改 加文件几乎永远不冲突。这是最关键的——协作时最怕两个人改同一个文件
全是 Markdown diff 读得懂。改了什么、删了什么,一眼看出来,不用看二进制
索引是派生的 _index.md、derivations.jsonl 冲突了直接重生成,不用手工合并

还有一条隐藏价值:知识库的 git 历史 = 课程内容的演进史。半年后你想知道「客户画像这一页是怎么长成现在这样的」,git log -p 能看到它被五份资料逐步充实的过程。这比任何笔记都可靠。


一次性设置(已配好,换机器要重做)

git config core.quotepath false     # 中文文件名正常显示,不显示成八进制
git config user.name  "你的名字"
git config user.email "你的邮箱"

core.quotepath false 这条别漏。不配的话 git status 里全是 \346\212\200\350\203\275 这种,没法看。


日常:一次同步,一个提交

丢资料 → 说「同步」→ 跑 kb.py check → git add -A → git commit

提交前必须跑一次检查,别把死链和没出处的数字提交进去:

python 90-工具/kb.py check

提交信息规范

统一前缀加一句话,方便日后 git log --oneline 扫读:

前缀 什么时候用 例子
sync: 增量同步完成 sync: 入库 3 份行业报告,派生 9 页
retract: 源删除后的回滚 retract: 删除 2024 旧版大纲,归档 4 页
course: 课程产出 course: 银行 3 天课大纲初稿
fix: 修复体检问题 fix: 清理 12 处死链与 3 个孤儿页
rule: 改契约或技能 rule: 新增证据分级 A/B/C/D
chore: 工具改动 chore: kb.py 增加 repair 命令

不要写 "update"、"修改"、"提交一下"。三个月后自己看不懂。


多人协作:谁改什么

冲突的根源是两个人改同一个文件。按下面的分工,冲突面能压到接近零。

角色 主要改 基本不碰
资料策展人 00-原材料/ 加文件 知识库页面
做课的人 20-课程产出/、10-知识库/modules/ 别人的 topic 页
库维护者 10-知识库/topics/、entities/、_meta/ 产出目录

三个冲突高发点

文件 冲突概率 原因
_meta/manifest.json 极高 单一文件,谁同步都会改
topics/*.md 中 两个人可能同时往同一主题页补料
*/_index.md 中 每次 graph 都重写

冲突怎么解

情况一:manifest.json 冲突

不要手动合并 JSON。 它本质是磁盘状态的缓存,直接从磁盘重建就行:

git checkout --ours 10-知识库/_meta/manifest.json
python 90-工具/kb.py repair

repair 会扫磁盘算指纹、扫页面反推派生关系,把 manifest 重新建出来。恢复不了的只有「整理时间」和「已删除源的记录」,不影响使用。

情况二:页面冲突

正常解,但注意 sources: 列表要取并集,不是二选一。少一个源,将来删那个源时这页就回滚不掉。

sources:
  - "01-行业资料/报告A.pdf"     # 对方加的
  - "02-客户与需求/访谈.md"      # 你加的

情况三:_index.md 冲突

别解,直接重生成:

git checkout --theirs 10-知识库/topics/_index.md
python 90-工具/kb.py graph

它是 kb.py graph 的产物,手工合并没有任何意义。


用 git 做四件具体的事

1. 撤销一次糟糕的同步

同步完发现喂了错误的资料,整批派生页都脏了:

git reset --hard HEAD~1     # 回到上一个提交(会丢未提交的改动,先确认)

比手动删页面安全得多。

2. 看某一页是怎么长出来的

git log -p -- 10-知识库/topics/客户画像.md

能看到它第一次只是一句话,后来被几份资料逐步补成现在的样子,每次补料是谁、按什么依据。这是这个仓库最值钱的用法之一。

3. 找回被误删的页

git log --diff-filter=D --name-only -- 10-知识库/

列出所有被删过的文件,配合 git checkout <commit>^ -- <路径> 恢复。

4. 对比两周前的库

git diff HEAD~20 --stat

一眼看出这两周库长大了多少、哪些方向在长、哪些页一直没动过。


远端优先:每次开工先拉

git 服务在本机或内网,不存在外泄风险,所以这个库可以、也应该以远端为准。

但有个前提要说清

公开的只读知识库(比如那本人生指南)可以「拉一份临时副本 → 读完扔掉」,因为它只读。

这个库要写入。 拉下来的副本改完往哪推?所以不能照抄那个模式。正确的做法是:

本地保留完整工作区,但每次都从远端拉最新,改完推回去。

「远端为准」靠的不是「本地不存」,而是每次开工先把本地对齐到远端。

一条命令

python 90-工具/kb.py pull

它做四件事:

  1. 检查是不是 git 仓库、有没有配远端
  2. 工作区有未提交改动就拒绝拉取 —— 避免和 rebase 打架,并列出脏文件
  3. git pull --rebase 拉最新
  4. 对比拉取前后的提交,报出原材料新增/修改/删除/移动各几个,具体是哪些文件

输出长这样:

从 origin/master 拉取…
拉到 1 个新提交。原材料变化:新增 2 · 修改 0 · 删除 0 · 移动 0
  [NEW]     00-原材料/01-行业资料/远端新增报告.md
  [NEW]     00-原材料/03-课程素材/远端新案例.md

  下一步:让模型按 kb-sync 的流程处理上面这些变化。

拉完之后不需要额外的检测逻辑:文件真的落地了,kb.py scan 的 sha256 比对自然能发现它们。实测这比让 git 自己算 diff 更可靠 —— 它还能发现没提交的本地改动。

为什么这样最省时间

git pull 只传增量。唯一的全量传输是第一次 git clone,之后每次都是几百 KB 级别。

反过来,如果为了省磁盘只检出需要的部分(sparse-checkout),kb.py scan 就扫不到全量原材料,指纹比对直接失效 —— 省下的空间远不值得。

按仓库体积选策略

仓库体积 做法
< 500 MB 全量 + 每次 pull(默认,就是现在这套)
500 MB – 5 GB 全量 + 大文件走 git-lfs(lfs 对象按需下载,工作区里是几百字节的指针)
> 5 GB 或含大量视频 原材料单独开一个仓库,主库只放知识库与技能

绝大多数做课资料在第一档。

日常节奏

早上开工   python 90-工具/kb.py pull      # 拿到别人昨天整理的结果
白天       丢资料 → 说「同步」
晚上收工   git add -A && git commit && git push

收工不推,等于白干。 第二天别人 pull 不到,你自己换台机器也接不上。


首次配置远端

本仓库已配置好,远端是公司自建的 Gogs:

origin  https://gogs.goodpoint.top/Hyreal/course-factory.git
分支    master(跟踪 origin/master)

为什么是 master 不是 main:Gogs 建库时默认分支就是 master,而且它的 API 不允许普通用户修改组织仓库的默认分支(PATCH 返回 404)。如果本地弄个 main,别人 git clone 下来会因为找不到 master 而得到一个空目录 —— 这个坑实测踩过。 想改成 main 只有一条路:在 Gogs 网页「仓库设置 → 默认分支」里改,改完本地 git branch -m master main && git push -u origin main。

如果要在别的机器上接进来:

git clone https://gogs.goodpoint.top/Hyreal/course-factory.git

如果是自建的 Gitea / GitLab,地址形如 http://192.168.1.10:3000/team/course-factory.git。 纯本机的话,也可以直接指向本地目录的 bare 仓库:

git init --bare D:/git/course-factory.git
git remote add origin D:/git/course-factory.git
git push -u origin master

不要推到公开 GitHub —— 库里有客户名称、报价、内部方法论。


大文件

00-原材料/ 里如果有超过 50MB 的 PDF 或视频,建议用 git-lfs,否则仓库会很快膨胀到几个 GB:

git lfs install
git lfs track "00-原材料/**/*.pdf"
git lfs track "00-原材料/**/*.mp4"
git add .gitattributes

已经提交过的大文件不能再靠 lfs 瘦身,需要用 git filter-repo 重写历史。所以最好现在就决定。


和 kb.py 的分工

别把两件事搞混:

管什么
git 文件的历史版本:谁在什么时候改了什么
kb.py 当前状态的一致性:哪些源整理过、哪些页该删、索引对不对

git 回答「上周这页写的什么」,kb.py 回答「现在库里有没有过期内容」。两个都要,互相替代不了。


一条最小纪律

每次说「同步」结束后,立刻提交一次。

不要攒着。攒了三天的改动一起提交,出问题时你分不清是哪一批资料搞坏的。