ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Spec Kit git 扩展 speckit.git.feature 命令详解:特性分支创建、编号策略与分支命名模板

Spec Kit git 扩展 speckit.git.feature 命令详解:特性分支创建、编号策略与分支命名模板 Spec Kit git 扩展 speckit.git.feature 命令详解特性分支创建、编号策略与分支命名模板【免费下载链接】spec-kit Toolkit to help you get started with Spec-Driven Development项目地址: https://gitcode.com/GitHub_Trending/sp/spec-kit本文围绕 Spec Kitspec-kit中 git 扩展的核心命令speckit.git.feature展开系统讲解它如何在 SDDSpec-Driven Development规格驱动开发工作流中自动创建并切换特性分支包括分支编号的两种模式顺序号/时间戳、配置解析优先级、branch_template分支命名模板的四类占位符与校验规则以及底层脚本对编号探测、命名长度限制与无 Git 环境的降级处理机制。读完后你可以完整掌握该命令的触发方式、全部可配置参数并能结合仓库源码理解其实现细节。命令定位它只负责建分支不负责建规格speckit.git.feature是 git 扩展命令定义 描述的一条 Agent 可执行命令其 frontmatter 中声明的职责是Create a feature branch with sequential or timestamp numbering创建顺序编号或时间戳编号的特性分支文档开篇即明确了职责边界该命令只处理分支创建This command handles branch creation only而规格目录与规格文件的创建由核心的 specify 工作流完成。这一点在 git 扩展清单 中也能得到印证speckit.git.feature被注册为before_specify钩子且optional: false——也就是说当 git 扩展被安装后每次执行核心 specify 命令之前它会强制先运行为本次规格创建一条专属分支。核心 specify 模板 中同样写明Pre-Execution Checks 阶段会读取.specify/extensions.yml的hooks.before_specify配置并等待钩子执行完毕后再继续。git 扩展在 扩展 README 中的定位是一个可选、自包含的 Git 操作模块除分支创建外还提供仓库初始化、分支校验、远端检测和自动提交等能力speckit.git.feature是其中承担特性分支生命周期管理的一环。安装与启停方式来自扩展 README# 安装内置 git 扩展无需网络 specify extension add git # 禁用禁用后仍会继续创建规格只是不建分支 specify extension disable git # 重新启用 specify extension enable git扩展安装时会把 配置模板 复制为项目内的.specify/extensions/git/git-config.yml后续所有分支行为都由该文件驱动。用户输入与执行前置检查命令定义中的User Input一节直接嵌入占位符$ARGUMENTS并要求 Agent MUST consider the user input before proceeding (if not empty)——即用户随命令一起输入的文字通常是特性描述必须被纳入分支命名的考量。执行前置条件只有一条且非常具体git rev-parse --is-inside-work-tree 2/dev/null用该命令探测当前目录是否处于 Git 工作树内。如果 Git 不可用命令不会报错中断而是警告用户并跳过分支创建见下文优雅降级一节。GIT_BRANCH_NAME 环境变量覆盖精确指定分支名命令定义中的Environment Variable Override一节给出了最高优先级的分支命名通道当用户通过环境变量、参数或请求显式提供GIT_BRANCH_NAME时Agent 必须把该值注入环境后再调用脚本。此时脚本的行为是来自命令文档与 Bash 脚本实现 逐条对应使用精确值作为分支名绕过所有前缀/后缀生成逻辑--short-name、--number、--timestamp三个标志全部被忽略FEATURE_NUM的提取规则若分支名的最后一个路径段以数字或时间戳特性标记开头例如042-name、feat/042-name、jdoe/app/042-name则提取该前缀作为特性编号否则FEATURE_NUM取完整分支名。脚本内部的对应实现是extract_feature_num_from_branch先尝试匹配^[0-9]{8}-[0-9]{6}-的时间戳前缀再退化为匹配任意数字前缀^[0-9]-都匹配不到则回退为完整分支名见 create-new-feature-branch.sh 与 Python 版同构实现。值得注意的是GIT_BRANCH_NAME的精确值仍需满足 GitHub 的 244 字节分支名上限超限会直接报错退出而不是截断——因为截断一个用户精确指定的名字是不被允许的详见下文长度限制一节。分支编号模式四级配置解析顺序命令定义中的Branch Numbering Mode一节规定了编号策略顺序号或时间戳的解析顺序这是该命令最容易被忽略的配置细节检查.specify/extensions/git/git-config.yml中的branch_numbering值检查.specify/init-options.json中的feature_numbering值继承自 Spec Kit 核心检查.specify/init-options.json中的branch_numbering值已弃用仅为向后兼容未来版本将移除以上都不存在时默认为sequential。这一扩展配置优先、核心配置兜底的优先级设计有测试佐证tests/test_branch_numbering.py 验证了自 v0.10.0 起specify init的--branch-numbering命令行标志已被移除传入会报No such option分支编号完全交由 git 扩展的配置文件管理。配置模板中两种模式的语义如下来自 git-config.yml 的注释sequential生成001、002… 三位零填充顺序号timestamp生成YYYYMMDD-HHMMSS时间戳前缀。分支名模板branch_template 与 branch_prefix命令定义的Branch Name Template一节说明脚本会读取git-config.yml中可选的branch_template。为空或缺失时使用默认形态{number}-{slug}若设置了模板则必须满足两条结构约束——{slug}不得出现在{number}之前且最终路径段必须以{number}-开头。脚本会展开以下四个占位符占位符含义取值来源源码佐证{author}净化后的 Git 作者名git config user.name缺失时回退user.email的前本地部分再缺失时回退系统USER环境变量get_author_token{app}净化后的 Spec Kit 初始化目录名取仓库根目录的 basenameget_app_token{number}顺序号或时间戳见编号自动确定一节{slug}生成的短分支名--short-name指定或自动从特性描述提炼净化由clean_branch_name完成转小写、非字母数字替换为连字符、压缩连续连字符、去除首尾连字符create-new-feature-branch.sh。对 monorepo 场景文档给出模板{author}/{app}/{number}-{slug}可以生成形如jdoe/web/008-guided-tour的分支名同时保持每个项目独立的特性编号。这条能力在 tests/extensions/git/test_git_extension.py 中有专门测试test_branch_template_adds_author_and_app_namespace验证命名空间生成test_branch_template_scopes_number_after_numeric_app_namespace与test_branch_template_scopes_existing_branch_numbers验证编号探测按模板前缀隔离——即只统计同一命名空间下的分支序号避免 A 项目的分支抬高 B 项目的序号。三条模板校验规则在脚本中是硬性错误不满足直接exit 1必须包含{number}占位符——否则生成的分支不再是合法的特性分支{slug}不得出现在{number}之前——{slug}只能用于最终特性段最终路径段必须以{number}-开头。对应实现见 validate_branch_templatePython 版同逻辑见 create_new_feature_branch.py测试用例test_branch_template_requires_number_token、test_branch_template_rejects_slug_before_number、test_branch_template_requires_feature_segment_to_start_with_number分别覆盖三类错误输入。除模板外还有一个更简单的入口branch_prefix。它是纯命名空间的简写展开规则为branch_prefix/{number}-{slug}前缀以/结尾时不重复添加分隔符见 resolve_branch_template。例如配置branch_prefix: features/{app}会展开为features/{app}/{number}-{slug}配置模板注释 中的示例。优先级上branch_template高于branch_prefix模板非空时直接采用只有模板为空才回退到前缀展开。配置示例取自 git 扩展 README 的完整配置段# 分支编号策略: sequential 或 timestamp branch_numbering: sequential # 可选分支名模板。留空则使用默认 {number}-{slug} # 支持占位符: {author}, {app}, {number}, {slug} # {slug} 不得出现在 {number} 之前; 最终路径段必须以 {number}- 开头 # monorepo 示例: {author}/{app}/{number}-{slug} branch_template: # 可选的简写命名空间。留空则按 branch_template/默认行为 # 示例: features/{app} 展开为 features/{app}/{number}-{slug} branch_prefix: # git init 时使用的自定义提交信息 init_commit_message: [Spec Kit] Initial commit执行脚本调用方式与硬性规则命令定义要求 Agent 先为分支生成一个简洁短名2–4 个词分析特性描述、提取最有意义的关键词、尽量使用动词-名词结构如add-user-auth、fix-payment-bug、保留技术术语与缩写OAuth2、API、JWT。随后按平台选择脚本执行以下命令原文来自命令文档的Execution一节Bash.specify/extensions/git/scripts/bash/create-new-feature-branch.sh --json --short-name short-name feature descriptionBash时间戳模式.specify/extensions/git/scripts/bash/create-new-feature-branch.sh --json --timestamp --short-name short-name feature descriptionPowerShell.specify/extensions/git/scripts/powershell/create-new-feature-branch.ps1 -Json -ShortName short-name feature descriptionPowerShell时间戳模式.specify/extensions/git/scripts/powershell/create-new-feature-branch.ps1 -Json -Timestamp -ShortName short-name feature description文档同时给出四条IMPORTANT规则理解它们是正确驱动该命令的关键不要传--number——脚本会自动确定正确的下一个编号编号探测逻辑见下节始终带 JSON 标志Bash 为--jsonPowerShell 为-Json保证输出可被可靠解析每个特性只能运行一次该脚本——因为顺序号是探测最大值 1的副作用操作重复运行会抬高编号不要手工展开branch_template——脚本自己读取扩展配置并一致地应用模板。从脚本的--help输出create-new-feature-branch.sh可以看到完整参数面供直接手工调用时参考参数作用--json以 JSON 格式输出--dry-run只计算分支名不实际创建分支--allow-existing-branch分支已存在时切换到它而不是失败--short-name name提供自定义短名2–4 个词--number N手工指定分支编号覆盖自动探测必须为非负整数--timestamp用时间戳前缀YYYYMMDD-HHMMSS替代顺序编号环境变量GIT_BRANCH_NAME使用该精确分支名绕过所有前缀/后缀生成除 Bash 与 PowerShell 两个实现外仓库中还带有一份 Python 移植版 create_new_feature_branch.py文件头注明它是 Bash/PowerShell 双实现的 Python port并有专门的 parity 测试test_git_extension_python_parity.py保证三者行为一致适合在缺少 Bash 环境的平台上直接运行。编号是如何自动确定的不要传--number这条规则背后是一套三路取最大值的编号探测机制check_existing_branchesspecs 目录get_highest_from_specs扫描specs/下所有子目录名匹配3 位及以上数字前缀^[0-9]{3,}-且排除时间戳目录^[0-9]{8}-[0-9]{6}-的形态取最大序号。这样即便没有 Git 仓库或某次分支被删除规格目录也能保证编号不回退本地与远端分支get_highest_from_branches解析git branch -a输出剥掉当前分支标记与remotes/name/前缀后按同样规则提取。默认路径会先执行git fetch --all --prune同步远端再统计--dry-run路径则改走无副作用的git ls-remote --heads设置GIT_TERMINAL_PROMPT0防止交互提示避免试算时产生网络写操作模板命名空间隔离当配置了branch_template时脚本从模板中{number}之前的部分渲染出scope_prefix如jdoe/web/编号探测只统计该前缀下的分支——这正是 monorepo 下per-project feature numbering得以成立的原因测试test_branch_template_scopes_existing_branch_numbers覆盖了该行为。最终编号取三路最大值加 1并以printf %03d格式化为至少三位零填充数字脚本主流程。时间戳模式下则直接取date %Y%m%d-%H%M%S并且若同时传了--number会打印[specify] Warning: --number is ignored when --timestamp is used后清空编号。短名自动生成的过滤逻辑如果 Agent 没有传--short-name脚本会自己从特性描述提炼短名generate_branch_nameBash / Python 逻辑一致小写化、非字母数字转空格后逐词过滤剔除内置停用词表the、to、for、add、get、need 等 40 余个常见虚词保留长度 ≥3 的词短词仅在原文中以全大写形式出现时保留用于留住 API、DB、JWT 这类缩写恰好呼应命令文档中保留技术术语与缩写的要求取前 3 个有意义的词恰好有 4 个时取 4 个用连字符拼接。若--short-name已提供则跳过上述提炼直接对指定值做clean_branch_name净化。244 字节分支名长度限制脚本内置了 GitHub 分支名 244 字节上限的处理Bash / Python若分支名来自GIT_BRANCH_NAME且超限直接报错退出提示must be 244 bytes or fewer in UTF-8若分支名为自动生成且超限逐字符截断 slug 后缀同时去掉尾部连字符重新渲染模板并输出警告[specify] Warning: Branch name exceeded GitHubs 244-byte limit同时打印原始名与截断后的字节数若模板前缀本身就超过 244 字节截空 slug 仍超限报错Branch template prefix exceeds GitHubs 244-byte branch name limit。优雅降级没有 Git 时也能走通命令定义的Graceful Degradation一节与脚本行为一致当未安装 Git 或当前目录不是 Git 仓库时——跳过分支创建并打印警告[specify] Warning: Git repository not detected; skipped branch creation脚本实际输出会附带计算出的目标分支名见 警告分支脚本仍然输出BRANCH_NAME与FEATURE_NUM调用方可以照常引用此时编号退化为仅扫描specs/目录结合 扩展 README 的降级说明规格目录仍会创建在specs/下分支校验同样跳过远端检测返回空结果——整个 specify 流程不因缺少 Git 而中断。这与extension.yml中requires.tools: git标记为required: false的声明互为印证Git 是该扩展的软依赖。输出JSON 契约与下游消费命令定义的Output一节约定脚本以 JSON 输出两个字段BRANCH_NAME分支名例如顺序模式下003-user-auth时间戳模式下20260319-143022-user-auth模板模式下jdoe/web/003-user-authFEATURE_NUM所用的数字或时间戳前缀。脚本在 JSON 模式下优先使用jq生成无jq时回退到手工转义拼接见 输出段非 JSON 模式则输出BRANCH_NAME:/FEATURE_NUM:两行纯文本方便人工阅读。下游消费方是核心 specify 命令specify 模板 明确规定before_specify钩子成功后已创建/切换到 git 分支并输出含BRANCH_NAME和FEATURE_NUM的 JSON记下这些值供参考但分支名不决定规格目录名若用户提供了GIT_BRANCH_NAME同样要求透传给钩子。这一契约保证了分支创建与规格目录创建两个职责可以各自演进而互不耦合。延伸阅读命令定义本文主体speckit.git.feature.mdgit 扩展总览、钩子表与安装方式extensions/git/README.md扩展清单命令注册、钩子声明、配置默认值extensions/git/extension.yml配置模板/运行时配置extensions/git/config-template.yml、extensions/git/git-config.yml三个平台实现create-new-feature-branch.sh、create-new-feature-branch.ps1、create_new_feature_branch.py行为测试tests/extensions/git/test_git_extension.py、tests/test_branch_numbering.py核心侧钩子消费逻辑templates/commands/specify.md【免费下载链接】spec-kit Toolkit to help you get started with Spec-Driven Development项目地址: https://gitcode.com/GitHub_Trending/sp/spec-kit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表