[Letux-kernel] improved workflow of editing and merging feature branches

H. Nikolaus Schaller hns at goldelico.com
Mon Sep 19 21:54:53 CEST 2016


Hi,
I found today a better way to organise my kernel work and reduce
risk that anything gets lost.

Let's start with how a letux-tree is merged from letux-base and
feature branches.

letux base is essentially a linus/master (the latest -rc) plus
Letux/ directory plus letux_defconfig. Everthing else should
be in feature branches. This is not always the case since we
have some old code still in letux-base. At some point in the
future I plan to "extract" this into new feature branches.

Every Monday when Linus releases a new -rc I do the following:

1. merge work/for-next-letux-base into letux-base
2. merge v${version} into letux-base
3. compile
4. git commit --amend changes to letux_defconfig
This usually increases the -rc version number only but sometimes
reflects a modified Kconfig

Then we have a new letux-base.

Next, I take all feature branches an rebase them to letux-base.

In most caes this automatically runs fine.
In some cases I have to fix merge conflicts.

Here comes the most important point why we have moved to this
feature branch concept:

If we post commits from a feature branch to LKML and they
are finally accepted, they will come to letux-base some months
later. As soon as this happens, the rebase will remove the
commit from our feature-branch. So we only see the commits
that are not yet in linus/master. And as soon as the feature
branch becomes empty, we have done our job :) At least for
this feature.

Finally I merge the feature branches on top of letux-base
to form a new letux-$version. Written as formula:

	letux-4.8-rc7 = letux-base(rebased to linus/4.8-rc7) + feature-branches(rebased to letux-base(rebased to linus/4.8-rc7))

As soon as the rebase is ok and the result compiles fine,
I git push the rebased feature branches and the resulting
letux-$version. And run the compiler to build a binary for
http://download.goldelico.com/letux-kernel/

Tweaking feature branches (patch sets) according to what
LKML feedback says can be done on the branches.

I should also mention that I do most of these things by
the Letux/scripts/merge and Letux/scripts/rebase scripts.

They have a nice property: they check if a feature branch
with suffix -v2 -v3 etc. exists and use the highest number.

This allows to keep e.g. [PATCH v2] while working and merging
[PATCH v3].

How does bug fixing work? Well, it should be simple to do...

Therefore I have created another branch (in the new idea),
called mywork. This is initially let's say letux-4.8-rc6.

I can compile it and get a letux-4.8-rc6 kernel. Now I
find some bugs and simply can edit them in the source
tree. After a while I do git add -p and git commit to
cast these changes into patches. Ideally in a way that
they can go to one of the feature branches I feel responsible
for.

As soon as things appear stable, I do a git log --oneline
to see the commits piled up.

Then I git checkout some relevant feature branch and git
cherry-pick from the oneline log. This adds the commit
to the feature branch.

I do this with all feature branches where I think commits
should go to. Not necessarily all commits piled up.

Then I can git rebase -i letux-base feature branches
where the new work should be squashed or applied earlier
than something else.

When I do the next ./merge these patches will also go
into the resulting letux-$version. So they will ripple
through.

As soon as a new letux-$version is available, I do
a rebase of the mywork branch on this letux-$version.

This does the trick to remove all commits that have successfully
arrived in some feature branch. So I just see what I have
not yet distributed before.

Another new trick can be used if I am just in the middle of
editing something (e.g. a lot of printk to debug something). The
usual answer would be to use git stash so that we can switch
branches.

But there is a better solution since sometimes git stash pop
might fail with a merge conflict and then it is really big
trouble to recover (there is no git stash --abort).

The trick is to simply git commit -m stash on the mywork
branch. This of course should not be distributed to feature
branches...

And after rebasing mywork to the latest letux-$version it
is still there. And a potential merge conflict is a rebase
conflict which is much easier to resolve (or --abort) than
git stash.

A simple git reset HEAD~1 will undo the stash - even if
it was rebased.

So to summarise:
* work happens on mywork
* clean commits are distributed into feature branches
* ./merge builds a new letux-$version
* rebasing of mywork on top of such a letux-$version makes
  good commits disappear from the head of mywork
* unclean work can be committed as -m stash
* but will survive a rebase

Quite complex, but I think this is now a good and quite
fail-safea approach. It helps that changes do not get lost
(as it happened to me several times).

Of course this whole procedure should be written in some
nice graphics because it makes things easier to understand.
But I have tried to explain it in works. Hope it is readable...

So please keep this mail/thread as a reference and ask
what you don't understand.

BR,
Nikolaus



More information about the Letux-kernel mailing list