VCS 软件包指南
32 位 – CLR – CMake – 交叉编译 – DKMS – Eclipse – Electron – 字体 – Free Pascal – GNOME – Go – Haskell – Java – KDE – 内核模块 – Lisp – Meson – MinGW – Node.js – 非自由软件 – OCaml – Perl – PHP – Python – R – Ruby – Rust - 安全 – Shell – VCS – Web – Wine
版本控制系统 可用于检索常用静态版本软件包的源代码,以及开发分支的最新(主干)版本。
/usr/share/pacman/PKGBUILD-vcs.proto
原型。软件包命名
除非软件包获取特定版本,否则在 pkgname
后缀 -bzr
、-cvs
、-darcs
、-git
、-hg
、-svn
等。
版本控制
如果更改依赖项、URL 或来源后,生成的软件包有所不同 — 将 pkgver
更新到最新版本。如果自上次更新 PKGBUILD
以来 pkgver
没有更改,则增加 pkgrel
。
建议采用以下版本格式:RELEASE.rREVISION
,其中 REVISION
是单调递增的数字,唯一标识源代码树(VCS 版本控制可以做到这一点)。如果没有公开发行版且没有存储库标签,则可以将零用作发行版号,或者完全删除 RELEASE
并使用看起来像 rREVISION
的版本号。如果存在公开发行版但存储库没有标签,则开发人员应以某种方式获取发行版版本,例如通过解析项目文件。
修订号分隔符 — r
在 REVISION
之前 — 非常重要。此分隔符允许避免上游决定发布其第一个版本或使用具有不同组件数量的版本时出现问题。例如,如果在修订版 455
上游决定发布版本 0.1
,则修订版分隔符保留版本单调性:0.1.r456 > r454
。如果没有分隔符,单调性将失败:0.1.456 < 454
。
冲突与依赖
- 包括软件包冲突和提供的,例如对于 fluxbox-gitAUR
conflicts=('fluxbox') provides=("fluxbox=${pkgver}")
- 注意: 有关 VCS 软件包通常相关的版本控制的通用建议,请参阅 PKGBUILD#provides。
replaces=()
通常会导致不必要的问题,应避免使用。
- 在
makedepends=()
中包含适当的 VCS 工具 — cvs、subversion、git 等。
身份验证与安全
- 使用 cvsroot 时,使用
anonymous:@
而不是anonymous@
,以避免必须输入空白密码或anonymous:password@
(如果需要)。 - 由于来源不是静态的,因此通过添加
'SKIP'
跳过sha256sums=()
中的校验和。
VCS 来源
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
(可选)— 需要拉取特定分支或提交。有关支持的 VCS 和相应的可用片段列表,请参阅 PKGBUILD(5) § USING VCS SOURCES。
一个 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 fetch network-origin git lfs checkout }
当 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 fetch network-origin git -C libs/libdep lfs checkout }
Git 校验和
当通过 git+https://domain.invalid/repository.git#tag=v1.0.0
引用稳定的 git 标签或特定提交作为来源时,可以在 PKGBUILD
中指定其校验和。为此,只需使用 makepkg -g
或 updatepkgsums
生成它们,就像对待任何其他非 git 来源一样。