GBS支持的维护模式

本地和非本地的包

从包的易维护角度出发,我们可以将包分为两种:

  • 地包:由我们、你们或Tizen负责控制源代码。 例如Tizen中的电源管理。 我们负责本地包的版本和发布,所以包的维护更简单。 我们可以根据需要随时发布一个新的版本。
  • 非本地包(或上游):我们,你们或Tizen不是上游, 例如linux内核或zlib。 对于这些包,我们需要按照上游项目的发布进程和进度。 比如,从开发者和法律的角度来说,这非常有益于追溯对源代码和包的修改(不同的上游和本地的修改)。

GBS也将包分为两种。 如果git仓库有一个上游分支,GBS为这个包是非本地的, 在.gbs.conf文件中,这个上游分支的配置可以使用名字"upstram_branch",或在命令行中使用“--upstram-branch”。

本地和非本地包的GBS编译,远程编译和导出命令都不一样。 即为编译准备的打包文件不同。

目前对于非本地包,GBS支持两种不同的维护模式:一种打包和源代码在同一个分支,另一种打包和开发处于不同的分支。

GBS和本地包

GBS从当前分支的头部简单地创建一个单片源的包。 打包文件从打包目录原样复制。 没有生成新的补丁。

Git仓库的布局如下:

         v1.0    v2.0
            |       |
o---A---B---C---D---E   master

GBS和非本地包:联合打包,即打包和开发在同一个分支。

在联合打包模式下,打包数据(如spec文件)与源代码在同一个分支:

              F---G---H   master (packaging + code changes)
             /
o---A---B---C---D---E     upstream
            |       |
          v1.0    v2.0

GBS创建一个上游源包,根据本地修改自动生成补丁,且自动更新spec文件。 逻辑如下:

  • 生成补丁

    • 根据upstream-tag..HEAD生成补丁,去除可能的旧补丁
    • 更新spec文件:去除旧的“Patch:”标签和“%patch”宏,并根据新的补丁用新的标签和宏代替。
  • 成功生成补丁之后,创建上游包
    • 如果git仓库有pristine-tar分支(而且安装了pristine-tar工具),GBS要使用pristine-tar对源tarball进行检验。
    • 如果前面的步骤失败,GBS根据正确的上游tag生成源tar包,要对spec文件中获取的版本号进行匹配。
  • 如果源tar包或补丁生成失败,GBS将使用老方法(把包按照本地包处理),只生成单个tar包,不产生补丁。

在packging目录或spec文件中不要有任何事先存在的补丁, 否责,GBS将拒绝生成补丁。 对于手动维护的补丁,请参考高级用法/手动维护补丁部分。

GBS和非本地包:分开打包,即打包和开发处于不同的分支。

在分开打包模式下,打包的数据被保存在一个单独的(orphan)分支,该分支没有源代码或通常的代码开发分支的历史:

o---I---J---K---L         master (packaging)

              F---G---H   development/master/1.0 (local source code changes)
             /
o---A---B---C---D---E     upstream
            |       |
          v1.0    v2.0

所有的打包数据,包括补丁,都保存在打包分支下。 开发分支仅包含上游源,没有打包数据。 gbs devel令协调各个不同分支的工作。

开发者工作于开发分支下,修改源代码。 如果包的维护者要发布一个新的包,他将修改分从开发分支导出到打包分支,提交修改,更新修改日志,提交一个新的版本。

在编译或导出包时,GBS创建一个真正的上游源tar包(类似于联合打包模式)。 在开发分支下,自动生成补丁,且自动更新spec文件。 在打包分支下工作时,packaging文件没有任何修改地被导出。

在联合打包模式下编译非本地包

这是非常简单和容易使用的。 如果要GBS把包看做非本地(比如使能上游的源文件和生成补丁),你需要:

  1. git仓库中具有上游分支,且包含未改动的上游源代码
  2. 件.gbs.conf中具有正确配置的上游tag格式,默认的是upstream/${upstreamversion}
  3. 你的开发分支基于上游版本(在.spec文件中体现)
  4. 所有本地手动维护的补丁(在packaging目录下)应用于开发分支,且从packaging目录中去除。

此外,你可以:

  1. 在git仓库有pristine-tar分支,用于使用pristine-tar工具生成上游tar包。

开发过程很简单:只要在你的开发分支上使用edit,commit和build。 GBS处理tar包和产生补丁,且更新spec文件。 运行gbs后看起来像这样(这里使用gbs export为例,因它的输出较短):

$ gbs export -o export
info: Generating patches from git (v1.2.7..HEAD)
info: Didn't find any old '%patch' macros, adding new patches after the last '%setup' macro at line %s
info: Didn't find any old 'Patch' tags, adding new patches after the last 'Source' tag.
info: zlib-1.2.7.tar.bz2 does not exist, creating from 'v1.2.7'
info: package files have been exported to:
/home/test/src/zlib/export/zlib-1.2.7-0

第一次尝试着产生补丁时,你可能要导出并检查spec文件,确认GBS正确更新了spec文件。 对于手动维护的补丁,请参考高级用法/手动维护补丁部分。

上游包或补丁产生包失败可能是如下原因:

  • 没有找到上游tag

    • git仓库中没有版本号
    • tag格式没有正确配置
  • 当前分支虽然声明其继承上游版本,但没有继承

在分开打包模式下编译非本地包

为了使用分开打包模式,必须:

  1. git仓库具有上游分支,且包含原始的上游源代码
  2. 件.gbs.conf中具有正确配置的上游tag格式,默认的是upstream/${upstreamversion}
  3. 具有一个分开打包分支,这个分支仅包含packaging文件,包含补丁
  4. 具有一个开发分支,所有的补丁应用于上游版本的头部

再次,此外,你可能:

  1. 在git仓库中有pristine-tar分支,用于使用pristine-tar工具生成上游tarball。

代码开发在开发分支完成,只要像联合打包模式下使用edit,commit和build。 然而,所有的打包改都是在打包分支下完成的。 最重要的,提交(比如发布到整合版本)是在打包分支下完成的。 在提交之前,包的维护者在开发分支下,根据新的修改产生补丁,并将其提交到打包分支下。 关于如何使用gbs devel命令管理打包和开发分支,请看下面的GBS devel章节,以了解具体的使用方法。

管理上游源

本章节仅针对那些对包的维护者感兴趣的人。

如果要使用上面的模式维护包,您需要在git仓库中的一个单独的分支下,保持未修改的上游源代码。 为此,GBS支持两种模式。

将上游源文件导入到git

在这种模式下,通过使用gbs import命令,您可从上游的发布版本导入源tarball(或zip文件)到您的git仓库中。 GBS在上游分支提交源代码,并根据上游发布版本生成一个tag。 从头开始的一个例子,即导入到一个空的repo:

$ mkdir zlib && cd zlib && git init
$ gbs import ../zlib-1.2.6.tar.gz
...
$ git branch
* master
upstream
$ git tag
upstream/1.2.6

现在你只要向主分支增加打包文件,就可以开始开发了。 如果你需要更新到一个新的上游版本,只要再次使用gbs import命令:

$ gbs import ../zlib-1.2.7.tar.gz
$ git tag
upstream/1.2.6
upstream/1.2.7

意,当前,GBS自动合并新的版本到你的主分支。 所以,你需要在spec文件中更新相应的版本号。

跟踪远程git

在这个模式下,你直接跟踪一个远程的git仓库。 你完全不需要使用GBS导入。 GBS仅需要知道上游分支的名字,以及上游发布tag的格式。 由于这些信息依赖于特定的包,因此在主分支上面,你应该在包特定的.gbs.conf 里面配置他们。 再一个从头开始的例子:

$ git clone git://github.com/madler/zlib.git && cd zlib
$ git branch -m master origin # to keep origin tracking the upstream
$ git checkout -b master
$ vim .gbs.conf
$ git add .gbs.conf && git commit -m"Add gbs.conf"

配置文件的例子应该是这样:

[general]
upstream_branch = origin
upstream_tag = v${upstreamversion}

Pristine-tar支持

你可以使用prinstine-tar来保存或获得上游tarball(请http://joeyh.name/code/pristine-tar/),这个做法是可以选择的(但是我们强烈推荐!)。 可以从Tizen工具仓库进行安装。 Pristine-tar保证由GBS生成的tarball和真正的上游发布的源tarball在bit位上是相同的。 如果你已经在你的系统上安装了pristine-tar,那么GBS会自动地使用pristine-tar。 如果你使用GBS import来管理上游源,则每一件事情都会出乎意料之外:GBS import 会自动地提交新的tarball到pristine-tar分支上。

然而,如果你直接跟踪一个远程上游仓库,那么你需要手动地提交上游源tarball到pristine-tar分支。 所以,类似于我们的zlib例子:

$ cd zlib
$ git branch
* master
origin
$ pristine-tar commit ../zlib-1.2.7.tar.gz v1.2.7
$ git branch
* master
origin
pristine-tar

将目前存在的仓库转换成一个非本地的包

  1. 你需要一个上游分支
  1. 如果你已经在跟踪上游,只要在包特定的.gbs.conf文件中配置上游分支的名字和tag格式。
  2. 否则,就使用gbs import将上游源tarball导入,或将上游远程加到你的仓库中且进行跟踪。
  1. 推荐:如果你在直接跟踪上游git,可能要用'pristine-tar commit <tarball> <upstream-tag>'
  2. 将你目前的开发分支rebase到正确的上游版本 (就是在上游tag做rebase)。
  3. 删除所有的本地补丁:在你开发分支的头部应用并提交,在packaging目录下去除补丁,最好也从spec文件中去除补丁。
  4. 这一点是可选的,如果你需要使用分开打包模式维护包,可以使用gbs devel convert命令创建打包和开发分支。

高级用法

手动维护补丁

GBS支持手动维护补丁,这些不是自动生成补丁。 这可能用在与架构相关的补丁上,比如,GBS仍然不支持生成带条件的补丁。 另一个例子,是在二次源树上所应用的补丁,这些源不在git树上进行维护,仅是一个在你的packaging目录下的压缩包。

要使用这个特性,你需要使你的补丁放在packaging目录下,并在spec文件中列出。 此外,你需要通过在spec文件中加上:# Gbp-Ignore-Patches: <补丁号>,以标记这些补丁被补丁生成器或导入工具所忽略。 当在导入或产生补丁时,这会使得GBS忽略所列出补丁的'Patch:' 标签和'%patch'宏。 从spec文件中摘录的一段如下:

...
Source0: %{name}-%{version}.tar.bz2
# Gbp-Ignore-Patches: 0
Patch0: my.patch
 
%description
...

实际上,你可以再spec文件中的任何地方使用这个特殊的标志。 而且,它不区分大小写,如果你喜欢,也可以用如GBP-IGNORE-PATCHES:。 使用GBP作为前缀的原因就是,GBS使用 git-buildpackage (gbp)作为生成补丁的后端。

意:此外,在编译或导出时,要注意补丁生成。 同样,在导入源rpm包时,gbs import也会忽略被标记为手动维护的补丁。

补丁宏定位

GBS在根据新生成的补丁更新spec文件时,会尝试着自动找出正确的加了'%patch' 宏的位置。 一般来说,定位还不错,但是GBS也会猜错。 你可以在spec文件中通过加上一条# Gbp-Patch-Macros标志线,进行手动地标记自动生成的'%patch'宏的位置。 从spec文件中摘录的一段如下:

...
%prep
%setup
# do things here...
 
# Gbp-Patch-Macros
 
# do more things here...
 
%build
...

GBS会将新的'%patch'宏放置在标志线后面。 这个标志不区分大小写,类似于# Gbp-Ignore-Patches。

挤压提交

在生成补丁时,GBS支持将多个提交挤压到一个单个的diff中。 目前,仅能将上游标签挤压到一个给定的提交中。 一个例子可以是这样,将从上游发布版本到一个稳定的更新版本之间的提交,挤压成一个单独的diff(通常在稳定生成的版本上提交一个补丁)。 你可以通过使用'squash_patches_until'配置文件选项来启动它,或者使用'--squash-patches-unitl'命令行选项:选项的格式是<commit-ish>[:<filename-base>]。

举个例子:

$ git branch
* master
stable
upstream
$ gbs export --squash-patches-until=stable:stable-update
info: Generating patches from git (upstream/0.1.2..HEAD)
info: Squashing commits a2a7d82..9c0f5ba into one monolithic 'stable-update.diff'
info: Didn't find any old 'Patch' tags, adding new patches after the last 'Source' tag.
info: Didn't find any old '%patch' macros, adding new patches after the last '%setup' macro
info: mypackage-0.1.2.tar.gz does not exist, creating from 'upstream/0.1.2'
info: package files have been exported to:
/home/user/src/mypackage/packaging/mypackage-0.1.2-1.21

意!如果你计划着要使用它,强烈推荐你在.gbs.conf文件中进行配置。 这样,所有用户(包含自动编译器)以相似的方式编译或导出包。