Files
firmware-lowlevel-development/skills/firmware-lowlevel-psp-development/references/project-and-git.md
T

7.2 KiB
Raw Blame History

PSP 项目与 Git 规则

仓库模型

  • PSP 固定工作区是当前用户的 ~/work/project/EMX2.1/AppTeam/Psp/。每个硬件项目是其普通直接子目录,目录名使用团队预先创建的实际项目名,不添加 psp- 前缀。
  • 项目目录和独立 Git 仓库由用户或团队预先创建。skill 不创建项目目录、不运行 git init、不更改初始分支,也不自行配置远端;目录缺失、软链接、嵌套在其他 worktree 中或不在固定根目录时停止。
  • 多个应用只有在硬件、GPIO、内存/分区、BSP 固件组合、Sensor/Media/ISP/PQ 和 AIPlugin 平台配置完全一致时才共用同一 PSP。
  • 保留预创建仓库的默认分支。经用户确认需要任务分支时,Etunel 任务建议使用 candidate/<SUBTASK_ID>,普通任务使用 candidate/<简短任务名>;分支名不是版本。
  • 应用仓库通过 Git submodule 把 PSP 固定在 psp/,由 submodule gitlink 锁定精确 commit;应用侧 psp.lock.json 只提供可读交接和一致性检查。

受控复制

  1. 展开当前用户的 ~,先运行 psp_project_guard.py inspect --target ~/work/project/EMX2.1/AppTeam/Psp/<项目名>,确认目标 PSP 是固定根目录的普通直接子目录、其 .git 是普通目录,并记录分支、HEAD、远端指纹和配置指纹。首次填充要求结果是 precreated-empty-repository;结果是 existing-project 时停止本节,转入“现有项目更新”。
  2. 检查参考 PSP 是普通目录、Git worktree 还是 submodule,记录精确来源。参考 worktree 脏时默认使用可追踪 HEAD;复制未提交内容必须让用户确认并标记来源不能由单一 commit 表示。
  3. 使用 psp_project_guard.py prepare --target ~/work/project/EMX2.1/AppTeam/Psp/<项目名> 复制到同一根目录下的唯一 staging,拒绝软链接、疑似凭据、缺失目标、目标根目录逃逸及非空目标。
  4. 在 staging 中修改;不接触参考 PSP 和目标 PSP。
  5. 使用 verify 按精确路径白名单检查差异和旧标识残留。
  6. 输出差异、关键继承、警告与验证结果。需求和适配方案已确认且没有阻塞项时,不再询问是否导入或提交。
  7. 使用 finalize 自动把已验证内容导入预创建空仓库。工具必须在导入前复核目标仍为空且 Git 身份未变化,导入时不复制或替换 .git;再运行 audit-final 证明业务内容与 staging 一致、分支/HEAD/远端/配置保持 prepare 基线。

目标项目本就必须存在;这里的“空”是除 .git 外没有条目。prepare 后目标出现文件或 Git 元数据变化时,保留 staging 并停止,不覆盖、删除或合并。由用户处理冲突后重新 prepare。

现有项目更新

目标已有业务内容时,不执行参考项目整体复制。确认目标路径和仓库身份,检查 worktree 与当前分支,以明确 commit/worktree 为基线完成最小修改;继续使用差异白名单、旧标识扫描和静态验证。检查通过后自动提交本任务的精确文件;若当前内容与用户声称的项目不一致,或存在重叠改动,停止并报告证据,不自行清空、替换、迁移或重新初始化。

提交和远端

  • 所有 PSP 必须在工作开始前就是独立 Git 仓库;skill 不初始化仓库、不切换默认分支、不添加或修改远端。
  • 本地 candidate commit 前输出新增、修改、删除、关键值、继承项、风险、测试和建议说明。需求和适配方案已经确认且检查通过后,自动暂存白名单内的本任务文件并创建 candidate commit,不再询问是否提交。
  • commit message 至少表达项目、适配/修复内容、BSP build ID,以及存在时的 WORK_ID/SUBTASK_ID;不写本机临时日志或烧录包路径。
  • 自动提交前核对暂存区只包含本任务文件。Git 用户身份缺失、暂存区混入其他文件、提交钩子失败或 commit 结果不明确时停止,不自动修改 Git 配置、不使用 --no-verify、不重试,也不改写历史。
  • 用户提供共享仓库地址或明确授权仓库创建流程。PSP skill 不自行选择 Git 服务、组织或远端。
  • 本地路径不能作为正式 Etunel 应用交付地址。commit 可从团队地址获取并验证后,才能声称应用可消费。
  • Git push、Etunel candidate 交接、accepted/revoked tag 创建与 push、设备烧录和产品发布分别确认;一次确认不自动覆盖后续动作。
  • 不改写已经提供给打包、设备或应用验证的 commit。修正产生新 commit,并记录其替代的旧 candidate。

状态和 tag

完整 Git commit SHA 是唯一内容身份。PSP 仓库不写自身 commit 或易过期的状态文件。

  • candidate、packaged、device_verified、app_integrated:记录在外部验证证据和 Etunel 任务中;
  • accepted:accepted/<12位commit前缀> annotated tag;
  • 已 accepted 后发现严重缺陷:保留 accepted tag,并创建 revoked/<12位commit前缀> annotated tag;
  • 未 accepted candidate 被替代:只在 Etunel 中记录 superseded 关系,不创建 revoked tag。

accepted tag 至少引用完整 PSP commit、WORK_ID、应用集成 SUBTASK_ID、应用 commit、构建/打包证据、底层负责人和确认时间。revoked tag 记录问题、影响范围和 Etunel 返工任务。创建及上传 tag 前重新确认。

正式交付构建应取得最新远端状态,证明存在 accepted 且不存在 revoked。离线或 refs 过旧时,开发构建可警告,正式交付停止。

应用侧锁定

应用层创建 psp.lock.json;PSP 仓库不创建它。最小字段见数据契约。构建时检查:

  • psp/ 已初始化且是预期仓库;
  • HEAD 与 lock 的完整 SHA、submodule gitlink 一致;
  • PSP worktree 干净且 commit 未 revoked;
  • 开发/集成构建允许 packaged candidate,正式交付要求 accepted;
  • BSP IMG 路径/hash 和允许覆盖项有效。

PSP 不修改应用开发 Skill 或应用业务。需要验证 PSP 时,在精确应用工程已由任务确定后,自动把工程中既有且仓库身份一致的 psp/ 子模块更新到候选 commit,并运行固定增量组包命令;不得顺带修改应用源码、暂存或提交应用仓库的其他变化。

更新子模块前检查应用父仓库、.gitmodules、gitlink 和 psp/ worktree。正常自动流程如下:

  1. .gitmodules 中必须唯一登记 path=psp,并且 URL 与目标 PSP 仓库身份一致;尚未初始化时自动运行项目已有的 git submodule update --init -- psp。
  2. 已初始化的 psp/ 必须干净,应用父仓库的 .gitmodules 和 psp gitlink 不能已有本任务以外的修改。
  3. 从固定工作区中的本地 PSP 仓库取得完整候选 commit,再把应用工程的 psp/ 检出到该 commit。该操作不要求先 push,也不改子模块 URL。
  4. 核对 psp/ HEAD 等于候选 commit、worktree 干净,并把父仓库显示的 gitlink 变化记入组包证据;不自动 git add 或提交应用父仓库。

子模块未登记、URL/仓库身份不一致、.gitmodules 或 gitlink 已有重叠改动、psp/ 不干净、候选 commit 无法从本地仓库取得、初始化需要新的凭据、需要改 URL 或需要提交应用仓库时停止并请用户确认。