Gear/Introduction: Difference between revisions
No edit summary |
|||
Line 23: | Line 23: | ||
=== SRPMs === | === SRPMs === | ||
$ gear-srpmimport some.src.rpm | $ gear-srpmimport some-0.1.src.rpm | ||
$ gear-srpmimport some-0.2.src.rpm | |||
... | |||
will import the given | will import the given SRPMs to the branch ("srpms" by default) in the | ||
repository (like git-import-dsc). | repository (like git-import-dsc). | ||
Line 33: | Line 35: | ||
=== Tarballs === | === Tarballs === | ||
$ gear-update foo-2.0.tar.gz | $ gear-update foo-0.2.tar.gz foo | ||
$ gear-update foo-2.0.tar.gz foo | |||
... | |||
will update the subdirectory tar in git repository with contents of | will update the subdirectory tar in git repository with contents of | ||
tarball. This operation is similar to the git-import-orig from | tarball. This operation is similar to the <tt>git-import-orig</tt> from | ||
dpkg-buildpackage. As SRPMs may contain several sources, the source code | <tt>dpkg-buildpackage</tt>. As SRPMs may contain several sources, the source code usually stored in the subdirectory. | ||
usually stored in the subdirectory. | |||
=== Upstream VCS === | === Upstream VCS === | ||
Line 47: | Line 50: | ||
== Packaging and patching == | == Packaging and patching == | ||
There are three major scenarios: | There are three major scenarios for keeping changes in the repository: | ||
* like SRPM | * like SRPM | ||
* patches in one branch | * patches in one branch | ||
Line 90: | Line 93: | ||
The .gear/rules will have the following contents: | The .gear/rules will have the following contents: | ||
copy: foo-something-fixed.patch | |||
copy: foo-another-fixed.patch | |||
tar.gz: foo | |||
This will add both patches and tar.gz'ed directory foo/ to the buildroot | This will add both patches and tar.gz'ed directory foo/ to the buildroot | ||
Line 108: | Line 111: | ||
# changelog entry as a commit message. | # changelog entry as a commit message. | ||
=== | === Scenario 2. "Small fixes" === | ||
$ gear- | This is scenario for the packages which need the small non-overlapping | ||
fixes here and there. This is also easiest scenario to use. | |||
Branches in repository: | |||
master | |||
upstream | |||
Tree layout: | |||
foo/ (in upstream, patched in master) | |||
.gear/rules (in master) | |||
foo.spec (in master) | |||
==== Working on package ==== | |||
$ git checkout master | |||
$ vim ... # hack-hack | |||
$ git commit | |||
All the changes are applied just on top of the upstream source code. | |||
==== .gear/rules ==== | |||
The .gear/rules file will be of the following form: | |||
tar: v@version@:foo | |||
diff: diff: v@version@:foo foo | |||
This will generate foo.tar, containing upstream source code, taken from | |||
the tag <tt>v${version}</tt>, where version is parsed from the <tt>foo.spec</tt>, and the diff with the difference between the directory foo in <tt>v${version}</tt> tag | |||
and the current directory foo. | |||
gear does not use real git tags, but instead it uses the tags stored in <tt>.gear/tags</tt>. | |||
This has the reasons: as tags may move over time, to achieve | |||
reproducibility of builds, tag position need to be stored in the git | |||
tree. There is utility for maintaining this set of tags: | |||
$ gear-update-tag --all | |||
Don't forget to commit the changes after updating: | |||
$ git-commit .gear/tags -m 'tags updated' | |||
==== Rebasing to new upstream version ==== | |||
$ git merge upstream | |||
... Fix conflicts, update changelog, remove unnecesary patches etc ... | |||
$ gear-commit | |||
That's all! As patches are stored in git branch, it's easy to update to | |||
new upstream version: merge will detect many incosistences. As an | |||
additional bonus, if upstream uses git as well, patches forwarded | |||
upstream and accepted there will not generate conflicts on merge. | |||
==== New package revision ==== | |||
$ vim ... # hack-hack, update changelog | |||
$ gear-commit | |||
Also simple. | |||
=== Scenario 3. "Full-blown development" === | |||
This is scenario for the packages which need the lot of work downstream | |||
(e.g. kernel). | |||
Branches: | |||
upstream | |||
topic-A | |||
topic-B | |||
... | |||
master | |||
Tree layout: | |||
foo/ (in upstream, patched in topic-*, master) | |||
.gear/rules (in master) | |||
foos.pec (in master) | |||
==== Working on package ==== | |||
All the work is done in topic branches, each is dedicated for some topic: | |||
$ git checkout topic-A | |||
$ vim ... # hack-hack-hack | |||
$ git commit | |||
$ git checkout topic-B | |||
... | |||
As patches may overlap, some conflict resolution need to be | |||
involved. The naive approach would be using the following branching | |||
scheme: | |||
* upstream | |||
| | |||
\--> topic-A | |||
\--> topic-B | |||
\--> master | |||
And then generating patch-per-topic by using .gear/rules. This will not | |||
work, as the generated patches will conflict. | |||
Instead, the following scheme is used: | |||
* upstream | |||
\-> topic-A | |||
\-> topic-B | |||
\-> master | |||
And gear-merge(1) utility merges the branches as described in | |||
.gear/merge file: | |||
merge: upstream topic-A | |||
merge: topic-A topic-B | |||
merge: topic-B master | |||
After using this utility (and resolving all conflicts occured), master | |||
branch gets a cumulative change. | |||
==== .gear/rules ==== | |||
The .gear/rules file will be exactly the same as for previous scenario, | |||
so the gear-update-tag(1) is also required: | |||
tar: v@version@:foo | |||
diff: diff: v@version@:foo foo | |||
==== Rebasing to new upstream version ==== | |||
$ ... # obtain the new upstream code in upstream branch | |||
$ gear-merge | |||
... Fix conflicts, update changelog, remove unnecessary patches etc... | |||
$ gear-commit | |||
Due to gear-merge, it's only necessary to fix the conflicts once. | |||
==== New package revision ==== | |||
$ vim ... # hack-hack, commit | |||
$ gear-merge | |||
== Builds == | |||
$ gear-hsh | |||
Here the .gear/rules is consulted and the following is performed: | Here the .gear/rules is consulted and the following is performed: | ||
* temporary directory is created | * temporary directory is created | ||
* all the files mentioned in .gear/rules are copied to this directory according to the rules | * all the files mentioned in .gear/rules are generated/copied to this directory according to the rules | ||
* rpmbuild is invoked. | * rpmbuild is invoked. | ||
There are also another build-commands: gear- | There are also another build-commands: gear-rpm (uses <tt>rpmbuild</tt> instead of [[hasher]]) and gear-remote-hsh/gear-remote-rpm, which use remote host for actual building (communicating over SSH). | ||
[[Category:Sisyphus]] | [[Category:Sisyphus]] | ||
[[Category:Devel]] | [[Category:Devel]] |
Revision as of 12:56, 8 March 2009
Gear Introduction
This is an introduction to gear for the people who already have the RPM packaging experience.
RPM-specific stuff
RPM source packages are built from the following files:
- .spec file, which is roughly debian/* without debian/patches/*
- several source files/tarballs
- and several patch-files.
gear provides the means to build/generate latter two types of files from the git, so repository is not required to contain them in the form digestible by rpmbuild.
Working with upstream source code
Upstream source code is generally stored in the separate branch.
There are two main sources of source code: upstream tarballs or upstream VCS, plus importing SRPMs for keeping older packaging history.
SRPMs
$ gear-srpmimport some-0.1.src.rpm $ gear-srpmimport some-0.2.src.rpm ...
will import the given SRPMs to the branch ("srpms" by default) in the repository (like git-import-dsc).
Importing SRPM creates git layout similar to the "Like SRPM" scenario described below.
Tarballs
$ gear-update foo-0.2.tar.gz foo $ gear-update foo-2.0.tar.gz foo ...
will update the subdirectory tar in git repository with contents of tarball. This operation is similar to the git-import-orig from dpkg-buildpackage. As SRPMs may contain several sources, the source code usually stored in the subdirectory.
Upstream VCS
This should be obvious: just fetch/pull if upstream uses git, or use converter if it does not.
Packaging and patching
There are three major scenarios for keeping changes in the repository:
- like SRPM
- patches in one branch
- patches in topic branches
Scenario 1. "Like SRPM"
This is least useful, but simple scenario. git is used just for keeping history, and the usual maintainer's workflow is not changed.
Branches in repository:
master upstream
Tree layout:
foo/ (in upstream, master) .gear/rules (in master) foo.spec (in master) foo-something-fixed.patch (in master) foo-another-fixed.patch (in master)
git repository is generated by the importing SRPMs or by creating from scratch.
Importing tarball to the upstream branch
By using master branch to make it a bit easier
$ mkdir foo $ cd foo $ git init foo $ gear-update ../foo-1.0.tar.gz foo $ git checkout -b upstream
Adding spec and patches
$ vi foo.spec $ vi foo-something-fied.patch $ vi foo-another-fixed.patch
Adding gear/rules
The .gear/rules will have the following contents:
copy: foo-something-fixed.patch copy: foo-another-fixed.patch tar.gz: foo
This will add both patches and tar.gz'ed directory foo/ to the buildroot where the package is built.
Specfile is picked up automatically if there is only .spec in the root directory fo git.
Commiting the stuff
gear is picky about it - it only handles the stuff which is in repo.
$ git add ... $ gear-commit # this is wrapper around git-commit which uses the last # changelog entry as a commit message.
Scenario 2. "Small fixes"
This is scenario for the packages which need the small non-overlapping fixes here and there. This is also easiest scenario to use.
Branches in repository:
master upstream
Tree layout:
foo/ (in upstream, patched in master) .gear/rules (in master) foo.spec (in master)
Working on package
$ git checkout master $ vim ... # hack-hack $ git commit
All the changes are applied just on top of the upstream source code.
.gear/rules
The .gear/rules file will be of the following form:
tar: v@version@:foo diff: diff: v@version@:foo foo
This will generate foo.tar, containing upstream source code, taken from the tag v${version}, where version is parsed from the foo.spec, and the diff with the difference between the directory foo in v${version} tag and the current directory foo.
gear does not use real git tags, but instead it uses the tags stored in .gear/tags.
This has the reasons: as tags may move over time, to achieve reproducibility of builds, tag position need to be stored in the git tree. There is utility for maintaining this set of tags:
$ gear-update-tag --all
Don't forget to commit the changes after updating:
$ git-commit .gear/tags -m 'tags updated'
Rebasing to new upstream version
$ git merge upstream ... Fix conflicts, update changelog, remove unnecesary patches etc ... $ gear-commit
That's all! As patches are stored in git branch, it's easy to update to new upstream version: merge will detect many incosistences. As an additional bonus, if upstream uses git as well, patches forwarded upstream and accepted there will not generate conflicts on merge.
New package revision
$ vim ... # hack-hack, update changelog $ gear-commit
Also simple.
Scenario 3. "Full-blown development"
This is scenario for the packages which need the lot of work downstream (e.g. kernel).
Branches:
upstream topic-A topic-B ... master
Tree layout:
foo/ (in upstream, patched in topic-*, master) .gear/rules (in master) foos.pec (in master)
Working on package
All the work is done in topic branches, each is dedicated for some topic:
$ git checkout topic-A $ vim ... # hack-hack-hack $ git commit $ git checkout topic-B ...
As patches may overlap, some conflict resolution need to be involved. The naive approach would be using the following branching scheme:
* upstream | \--> topic-A \--> topic-B \--> master
And then generating patch-per-topic by using .gear/rules. This will not work, as the generated patches will conflict.
Instead, the following scheme is used:
* upstream \-> topic-A \-> topic-B \-> master
And gear-merge(1) utility merges the branches as described in .gear/merge file:
merge: upstream topic-A merge: topic-A topic-B merge: topic-B master
After using this utility (and resolving all conflicts occured), master branch gets a cumulative change.
.gear/rules
The .gear/rules file will be exactly the same as for previous scenario, so the gear-update-tag(1) is also required:
tar: v@version@:foo diff: diff: v@version@:foo foo
Rebasing to new upstream version
$ ... # obtain the new upstream code in upstream branch $ gear-merge ... Fix conflicts, update changelog, remove unnecessary patches etc... $ gear-commit
Due to gear-merge, it's only necessary to fix the conflicts once.
New package revision
$ vim ... # hack-hack, commit $ gear-merge
Builds
$ gear-hsh
Here the .gear/rules is consulted and the following is performed:
- temporary directory is created
- all the files mentioned in .gear/rules are generated/copied to this directory according to the rules
- rpmbuild is invoked.
There are also another build-commands: gear-rpm (uses rpmbuild instead of hasher) and gear-remote-hsh/gear-remote-rpm, which use remote host for actual building (communicating over SSH).