Gear with topgit

The workflow
The Gear workflow we are aiming at here is the one with preparing patches in separate Git branches (and holding upstream in a branch), and then generating .patch files with .gear/rules ("diff") for putting them into the .src.rpm.

In this workflow, there is no need to merge the sources into the branch with the packaging meta-information (like .spec and .gear/rules and .gear/tags), a "git merge -s ours" is enough (but a merge--at least, a fake one--of course, is necessary to satisfy gear, so that when the commit tagged for the package release is pulled, all the objects needed to recreate the upstream tarball and the patches are fetched as well.)

This workflow has some advantages:


 * allows communicating with the upstream (the patches that can be submitted are there, and can be nicely exported with TopGit in the case if they are TopGit-controlled);
 * produces "old good" .src.rpm with explicit separation of topic patches and upstream sources;
 * TopGit can help (semi-automate) updating the Gear branch used for package releases (the commits submitted to git.alt fro building);
 * allows collaborating with other ALT maintainers on the topic branches;
 * anything else?..

"spec" base branch
To start using TopGit for preparing a package in Gear, first, create a plain branch which will have the basic packaging meta-information:

$ git branch spec 0.9-alt3.git20130407

Here 0.9-alt3.git20130407 is the last release (a tag in Gear) of the package done without using TopGit.

"spec" branch is needed due to some technical limitations of the TopGit mechanism for creating TopGit-controlled branches.

Also, a "spec" branch isn't completely useless for the package maintainer: the branches for the packages for different ALT repos ("sisyphus", "p6", etc.) will be able to pull in common changes to the .spec from this "spec" branch.

"sisyphus" branch depending on all the stuff
Create the branch where the package releases will be prepared:

$ tg create --this-with 'git merge -s ours -m merge-s_ours' sisyphus spec upstream tg_rename custom-merge tg: Creating sisyphus base from spec... tg: Merging sisyphus base with upstream tg: (with the cmd given by TG_MERGE if set: git merge -s ours -m merge-s_ours)...   Merge made by the 'ours' strategy. tg: Merging sisyphus base with tg_rename tg: (with the cmd given by TG_MERGE if set: git merge -s ours -m merge-s_ours)...   Merge made by the 'ours' strategy. tg: Merging sisyphus base with custom-merge tg: (with the cmd given by TG_MERGE if set: git merge -s ours -m merge-s_ours)...   Merge made by the 'ours' strategy. Switched to a new branch 'sisyphus' tg: Topic branch sisyphus set up. Please fill .topmsg now and make initial commit. tg: To abort: git rm -f .top* && git checkout spec && tg delete sisyphus $

(Note that we write the custom commit message as one word: merge-s_ours; that's to avoid splitting problems in the tg-scripts. A custom commit message is useful to make the fake merge explicitly marked, so that it is visible when viewing the Git history.)

In this example,


 * "sisyphus" is the name of the new branch,
 * "spec" is the base branch that we have just created,
 * "upstream" is a normal Git branch with upstream sources,
 * "tg_rename", "custom-merge" are the branches representing the patches ("upstream" with changes).

The patch branches can be TopGit-controlled (optionally); you see, this will work both if the branches are not TopGit-controlled (like "upstream") and if they are TopGit-controlled.

How to use TopGit-controlled branches with Gear, particularly, how to write .gear/rules and update the .spec is described elsewhere (topgit вместе с gear (in Russian)).

In the command above, a TopGit feature is used which is only implemented in the ALT's version (--this-with).

git.alt doesn't allow (yet) to store TopGit branches.

Preparing an updated package release in "sisyphus"
Essentially, you do the usual Gear things, and understand what is being done.

Basically, you edit .spec and .gear/rules as usually in this Gear workflow. (How to use TopGit-controlled branches with Gear, particularly, how to write .gear/rules and update the .spec is described elsewhere.)

Then the idea is that you run

tg update --this-with 'git merge -s ours -m merge-s_ours' sisyphus

if you are ready for a release and the upstream branches or patch branches have been updated. (NOT TESTED yet in practice.)

Then, you should do

gear-update-tag --all

I recommend that you run "tg update" and "gear-update-tag" as late as possible in the package release cycle, so that it is easier for you to discard/rewrite these commits after you changed something in the patch branches. (Not clutter the history with excessive merges.) Rewriting the last commits in the history is OK if you haven't made this history public.

(Basically, the same recommendation applies to doing "gear-create-tag" as late as possible, only when everything is ready to be submitted to git.alt.)

And test the build with

gear-hsh

or the like.

Adding a new patch
Ok, you've got a new patch in a new Git branch.

You should do 2 things:


 * "register" the patch in .spec and .gear/rules like described there (in Russian).
 * register the patch branch as a TopGit dependency like this:

git checkout sisyphus tg depend add --this-with 'git merge -s ours -m merge-s_ours' new_patch

--this-with option for "tg depend" is NOT IMPLEMENTED yet (as of topgit-0.9-alt4.git20150225).

Using TopGit to prepare patch branches
This is described elsewhere, say, in TopGit documentation, and I've written about this at some places in the Russian wiki http://altlinux.org : topgit вместе с gear (in Russian), ru:Руководство_по_gear.

Note that the ALT's version of TopGit has a convenient feature for rebasing TopGit branches (to make history beautiful), which can be used before you have merged that branch into "sisyphus" and released the package. (You are not allowed to rewrite the history of "sisyphus" after you have released a package for Sisyphus.) See the description of "tg update" in /usr/share/doc/topgit*/README.

WARNING
Be very careful not to have old "invalid" heads of remote tracking branches corresponding to your TopGit branches when running "tg update" or "tg create", because they can spoil everything and lead to a huge mess in your updated branches! Bring the remote heads up-to-date with your heads with:

tg push -r myremote --all