跳到主要内容

版本控制问题排查指南

本指南适用于遇到 版本控制 相关问题的用户。

查看端口的版本文件

信息

以下流程适用于来自 kmpkg 注册表 的端口。有关自定义注册表中版本数据库的实现方式,请参阅 注册表 文档。

要查看特定端口的版本数据库,请执行以下步骤:

  1. 导航到 kmpkg/versions 目录;
  2. 找到该端口对应的文件夹:
    • 查找与端口名称首字母对应的文件夹。例如,fmt 端口对应的文件夹名为 f-
  3. 打开端口的版本文件:
    • 找到与端口名称相同的 JSON 文件。例如,fmt 的版本文件名为 fmt.json

端口的版本文件包含可用版本的列表,以及版本标签及其对应的 Git 树对象哈希 等详细信息。kmpkg 需要这些信息来获取特定的端口版本,只有该列表中包含的版本才能在清单文件中使用。

有关版本控制的更多细节,请参阅参考文档:

有关清单的使用细节,请参阅 清单

原因:请求不存在的包版本

当清单文件中指定的版本在 kmpkg 版本数据库中不存在时,kmpkg 无法解析该依赖项,并会输出类似以下的错误信息:

error: 未找到 fmt 版本 100.0.0 的版本数据库条目
可用版本:
10.1.1
10.1.0
10.0.0
9.1.0#1
9.1.0
9.0.0
8.1.1#2
8.1.1#1
...
有关详细信息,请参阅 `kmpkg help versioning` 或 https://pub.kumose.cc/kmpkg/users/versioning。

解决方法:

  1. 更新版本数据库:
    • 你需要的版本可能未包含在本地的版本数据库副本中。此时,执行 git pull 命令将 kmpkg 注册表 更新到最新提交;
  2. 检查可用版本:
    • 从版本数据库的可用版本列表中选择一个合适的版本;
  3. 更新清单文件:
    • 编辑 kmpkg.json 文件;
    • 将指定的版本修改为 kmpkg 注册表中存在的版本。例如,将 "version>=": "100.0.0" 改为 "version>=": "10.1.1";
  4. 执行 kmpkg install:
    • 在终端或命令提示符中再次执行 kmpkg install 命令。

原因:跨不同方案指定版本约束

kmpkg.json 文件中为依赖项指定的版本使用的版本控制方案与 kmpkg 注册表基线版本使用的方案不同时,会发生版本方案冲突。由于 kmpkg 无法跨不同方案比较版本,因此会报错。

如果声明的 version>= 约束使用的版本方案与基线版本的方案不同,kmpkg 无法判断哪个版本更大或相等。

例如,若你指定:

{
"dependencies": [
{
"name": "boost-regex",
"version>=": "1.75.0"
}
]
}

kmpkg 会输出以下错误信息:

error: boost-regex:x64-windows 版本冲突:需要 1.75.0,无法与基线版本 1.83.0 比较。

版本使用的方案不可比较:
boost-regex@1.83.0 使用 relaxed 方案
boost-regex@1.75.0 使用 string 方案

可通过添加显式覆盖来指定首选版本解决此问题。例如:

"overrides": [
{ "name": "boost-regex", "version": "1.83.0" }
]

有关详细信息,请参阅 `kmpkg help versioning` 或 https://pub.kumose.cc/kmpkg/users/versioning。

解决方法:

  1. 使用兼容的版本方案:
    • 查看 kmpkg 注册表中 versions/b-/boost-regex.json 路径下的版本数据库,找到与基线使用相同版本控制方案的 boost-regex 版本;
    • kmpkg.json 中的 version>= 约束更新为使用兼容方案的版本;
  2. 覆盖为所需版本:
    • 若需要使用特定版本的 boost-regex(其版本方案与基线不同),可在清单中覆盖该版本;
    • 修改 kmpkg.json,添加 overrides 部分指定所需版本:
    {
    "dependencies": [
    { "name": "boost-regex" }
    ],
    "overrides": [
    { "name": "boost-regex", "version": "1.75.0" }
    ]
    }

原因:浅克隆中提交历史不完整

当 kmpkg 以有限的提交历史(浅克隆)克隆时,会缺少解析特定版本约束或基线所需的提交历史。kmpkg 用于获取特定端口版本的 Git 树对象哈希,仅在检出完整提交历史时才可用。kmpkg 会检测到自身是浅克隆,并在无法获取端口版本时输出错误信息。

例如,使用包含特定基线的 kmpkg.json

{
"dependencies": [
{
"name": "fmt"
}
],
"overrides": [
{
"name": "fmt",
"version": "7.1.3#1"
}
],
"builtin-baseline": "bb588985e37484d543fc849d0d79434e0d45bb3c"
}

会导致以下错误:

error: 执行命令失败:"C:\Program Files\Git\cmd\git.exe" "--git-dir=C:\dev\demo\kmpkg\.git" "--work-tree=C:\dev\demo\kmpkg\buildtrees\versioning_\versions\fmt\4f8427eb0bd40da1856d4e67bde39a4fda689d72_26648.tmp" -c core.autocrlf=false read-tree -m -u 4f8427eb0bd40da1856d4e67bde39a4fda689d72
kmpkg 被克隆为浅仓库,路径:C:\dev\demo\kmpkg\.git
请使用完整克隆重试。
error: git 执行失败,退出码:(128)。
fatal: 无法解包树对象 4f8427eb0bd40da1856d4e67bde39a4fda689d72
note: 正在检出 fmt 端口,Git 树哈希为 4f8427eb0bd40da1856d4e67bde39a4fda689d72

此错误表明,获取特定版本的 fmt 包所需的提交(4f8427eb0bd40da1856d4e67bde39a4fda689d72)在浅克隆中不可用。

解决方法:

  1. 转换为完整克隆

    • 最简单的解决方法是将浅克隆转换为完整克隆:
    git fetch --unshallow
  2. 使用 GitHub Actions(默认浅克隆)

    • GitHub Actions 通常默认使用浅克隆。要解决此问题,可修改 GitHub Actions 工作流,执行完整克隆。在使用 kmpkg 之前添加以下步骤:
    - name: 转换为完整克隆
    run: git fetch --unshallow

原因:传递依赖中意外包含默认功能

使用 kmpkg 管理依赖项时,你可能会发现传递依赖项会安装其默认功能,即使你的项目并不需要这些功能。这种情况可能导致最终构建中出现意外的冗余或功能。

场景

你的项目依赖于库 Y,而 Y 又依赖于库 X。库 X 有默认功能(包括 foo),你希望在项目中排除这些功能。你的顶层清单可能如下所示:

{
"name": "my-project",
"dependencies": [
{
"name": "Y",
"features": ["featureB"],
"default-features": false
}
]
}

你期望由于设置了 "default-features": falseX 会在不安装默认功能的情况下被安装。但实际上,X 仍然会安装默认功能 foo

原因

default-features 属性仅在顶层清单中生效。这意味着传递依赖项(如本场景中的 X)的默认功能仍会被包含,除非在顶层显式禁用。解析库 Y 时,kmpkg 不会将 "default-features": false 设置传播到传递依赖项 X,导致 X 安装了默认功能。

解决方法

要确保 X 等传递依赖项在安装时不包含默认功能,需要将它们提升为顶层清单中的直接依赖项,并显式禁用其默认功能。修改 kmpkg.json,直接包含 X 并设置 "default-features": false

{
"name": "my-project",
"dependencies": [
{
"name": "Y",
"features": ["featureB"]
},
{
"name": "X",
"default-features": false
}
]
}

这种方式可以确保 X 在安装时不包含默认功能,因为 X 现在是直接依赖项,且有明确的指令排除默认功能。

有关默认功能的工作原理及管理方式的更多详细信息,请参阅 默认功能概念文档

问题未列出?

若你的问题未在本文中列出,请访问 我们的仓库 创建新问题。