VCS 包指南
版本控制系统可用于检索普通静态版本化软件包的源代码,以及开发分支的最新(主干)版本。
/usr/share/pacman/PKGBUILD-vcs.proto 原型。包命名
除非软件包获取的是特定发行版,否则将 pkgname 后缀改为 -bzr, -cvs, -darcs, -git, -hg, -svn 等。
版本控制
如果更改了诸如依赖项、URL 或源之类的项目后,最终软件包发生了变化,请将 pkgver 更新到最新版本。如果自上次更新 PKGBUILD 以来 pkgver 未更改,则应增加 pkgrel。
建议使用以下版本格式:RELEASE.rREVISION,其中 REVISION 是单调递增的数字,唯一标识源代码树(VCS 修订版就是如此)。如果没有公开的发行版也没有存储库标签,则可以使用零作为发行版号,或者完全删除 RELEASE,并使用看起来像 rREVISION 的版本号。如果有公开的发行版但存储库没有标签,则开发者应以某种方式获取发行版号,例如通过解析项目文件。
修订号分隔符——REVISION 前面的 r——很重要。此分隔符可以避免上游决定进行首次发行或使用具有不同组件数量的版本时出现问题。例如,如果修订版是 455,上游决定发行版本 0.1,则修订号分隔符可保留版本单调性:0.1.r456 > r454。没有分隔符,单调性会失败:0.1.456 < 454。
冲突与依赖
- 包含软件包冲突和提供的内容,例如为 fluxbox-gitAUR
conflicts=('fluxbox') provides=("fluxbox=${pkgver}")- 注意 有关版本控制的通用建议,请参阅 PKGBUILD#provides,这对于 VCS 软件包经常适用。
replaces=()通常会引起不必要的麻烦,应避免使用。
- 在
makedepends=()中包含相应的 VCS 工具——cvs, subversion, git 等。
认证与安全
- 使用 cvsroot 时,使用
anonymous:@而不是anonymous@,以避免输入空白密码,或者anonymous:password@,如果需要的话。 - 由于源是动态的,请通过添加
'SKIP'来跳过sha256sums=()中的校验和。
VCS 源
- 根据 FS#34677 和 邮件列表,浅层克隆(Shallow clones)是故意不支持的。
- 稀疏检出(Sparse-checkout)克隆未实现。请参阅 BBS#254881。
VCS 源应在 source 数组中指定,并将像其他任何源一样被处理。makepkg 会将存储库克隆/检出/分支到 $SRCDEST——如果未在 makepkg.conf(5) 中设置,则与 $startdir 相同,并将其复制到 $srcdir(以一种特定于每个 VCS 的方式)。本地存储库保持不变,因此无需 -build 目录。
source 数组的一般格式是
source=('[folder::][vcs+]url[#fragment]')
folder(可选)——用于将默认存储库名称更改为比trunk更相关的名称,或保留之前的源。- 对于不反映 VCS 类型的 URL,需要
vcs+,例如git+https://some_repo。 url是远程或本地存储库的 URL。#fragment(可选)——用于拉取特定分支或提交。请参阅 PKGBUILD(5) § USING VCS SOURCES 以获取支持的 VCS 列表以及可用的相应片段。
一个示例 Git 源数组
source=('project_name::git+https://project_url#branch=project_branch')
folder 字段中使用 pkgver 变量,因为该变量可能在 pkgver() 函数调用期间更改,这将导致在后续函数中无法访问创建的文件夹。pkgver() 函数
pkgver 的自动递增现在通过专用的 pkgver() 函数实现。这使得可以更好地控制 pkgver,维护者应优先选择有意义的 pkgver。要使用 pkgver(),您仍然需要用最新值声明 pkgver 变量。makepkg 将调用 pkgver() 函数,并相应地更新 pkgver 变量。
Bazaar
pkgver() {
cd "$pkgname"
printf "r%s" "$(bzr revno)"
}
r830
Git
使用从最后一个提交可达到的最新带注释的标签
pkgver() {
cd "$pkgname"
git describe --long --abbrev=7 | sed 's/\([^-]*-g\)/r\1/;s/-/./g'
}
2.0.r6.ga17a017
使用从最后一个提交可达到的最新不带注释的标签
pkgver() {
cd "$pkgname"
git describe --long --tags --abbrev=7 | sed 's/\([^-]*-g\)/r\1/;s/-/./g'
}
0.71.r115.gd95ee07
如果 git-tag(1) 不包含连字符,则可以使用更简单的 sed(1) 表达式 sed 's/-/.r/;s/-/./'。
如果标签包含前缀,例如 v 或项目名称,则应将其删除
pkgver() {
cd "$pkgname"
# cutting off 'foo-' prefix that presents in the git tag
git describe --long --abbrev=7 | sed 's/^foo-//;s/\([^-]*-g\)/r\1/;s/-/./g'
}
6.1.r3.gd77e105
如果没有标签,则使用自历史开始以来的修订次数
pkgver() {
cd "$pkgname"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short=7 HEAD)"
}
r1142.a17a017
版本和仅提交/修订号(SHA-1 已省略;但是,如果没有 SHA-1,则如果不注意版本控制,则无法快速引用确切修订版)
git describe --long --abbrev=7 --tags | sed 's/\([^-]*\)-g.*/r\1/;s/-/./g'
这两种方法也可以结合使用,以支持最初没有标签但后来被标记的存储库(使用了 bashism)
pkgver() {
cd "$pkgname"
( set -o pipefail
git describe --long --abbrev=7 2>/dev/null | sed 's/\([^-]*-g\)/r\1/;s/-/./g' ||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short=7 HEAD)"
)
}
0.9.9.r27.g2b039da # if tags exist r1581.2b039da # else fallback
Mercurial
pkgver() {
cd "$pkgname"
printf "r%s.%s" "$(hg identify -n)" "$(hg identify -i)"
}
r2813.75881cc5391e
Subversion
pkgver() {
cd "$pkgname"
local ver="$(svnversion)"
printf "r%s" "${ver//[[:alpha:]]}"
}
r8546
0.。回退方案
如果无法从存储库中提取令人满意的 pkgver,则可以使用当前的 date(1)
pkgver() {
date +%Y%m%d
}
20130408
技巧与提示
Git 子模块
Git 子模块有点棘手。其想法是将子模块本身的 URL 直接添加到 sources 数组,然后在 prepare() 中引用它们。
下游项目开发者可能不会将他们的子模块命名为与上游模块的存储库相同的名称。要查看 Git 子模块的名称,请转到项目存储库中的 .gitmodules 文件并预览它。例如,一个由上游开发者命名的存储库 lib-dependency 可能在下游的 .gitmodules 中注册为一个名为 libs/libdep 的子模块。
[submodule "libs/libdep"] path = libs/libdep url = https://example.org/lib-dependency/lib-dependency.git
source=("git+https://example.org/main-project/main-project.git"
"git+https://example.org/lib-dependency/lib-dependency.git")
prepare() {
cd main-project
git submodule init
git config submodule.libs/libdep.url "$srcdir/lib-dependency"
git -c protocol.file.allow=always submodule update
}
Git LFS
Git LFS 需要一些额外的设置
makedepends=(... 'git-lfs')
prepare() {
git lfs install --local
git remote add network-origin https://example.org/upstream/lfs/repo
git lfs pull network-origin
}
当 LFS 在子模块中使用时,这也有效
prepare() {
git submodule init
git config submodule.libs/libdep.url "$srcdir/lib-dependency"
git -c protocol.file.allow=always submodule update
git -C libs/libdep lfs install --local
git -C libs/libdep remote add network-origin https://example.org/upstream/lfs/repo
git -C libs/libdep lfs pull network-origin
}
Git 校验和
当通过 git+https://domain.invalid/repository.git#tag=v1.0.0 引用稳定的 git 标签或特定提交作为源时,可以在 PKGBUILD 中指定它们的校验和。要做到这一点,只需使用 makepkg -g 或 updpkgsums 来生成它们,就像对待任何其他非 git 源一样。