forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
9.5 KiB
178 lines
9.5 KiB
.. _development_advancedtopics: |
|
|
|
Advanced topics |
|
=============== |
|
|
|
At this point, hopefully, you have a handle on how the development process |
|
works. There is still more to learn, however! This section will cover a |
|
number of topics which can be helpful for developers wanting to become a |
|
regular part of the Linux kernel development process. |
|
|
|
Managing patches with git |
|
------------------------- |
|
|
|
The use of distributed version control for the kernel began in early 2002, |
|
when Linus first started playing with the proprietary BitKeeper |
|
application. While BitKeeper was controversial, the approach to software |
|
version management it embodied most certainly was not. Distributed version |
|
control enabled an immediate acceleration of the kernel development |
|
project. In current times, there are several free alternatives to |
|
BitKeeper. For better or for worse, the kernel project has settled on git |
|
as its tool of choice. |
|
|
|
Managing patches with git can make life much easier for the developer, |
|
especially as the volume of those patches grows. Git also has its rough |
|
edges and poses certain hazards; it is a young and powerful tool which is |
|
still being civilized by its developers. This document will not attempt to |
|
teach the reader how to use git; that would be sufficient material for a |
|
long document in its own right. Instead, the focus here will be on how git |
|
fits into the kernel development process in particular. Developers who |
|
wish to come up to speed with git will find more information at: |
|
|
|
https://git-scm.com/ |
|
|
|
https://www.kernel.org/pub/software/scm/git/docs/user-manual.html |
|
|
|
and on various tutorials found on the web. |
|
|
|
The first order of business is to read the above sites and get a solid |
|
understanding of how git works before trying to use it to make patches |
|
available to others. A git-using developer should be able to obtain a copy |
|
of the mainline repository, explore the revision history, commit changes to |
|
the tree, use branches, etc. An understanding of git's tools for the |
|
rewriting of history (such as rebase) is also useful. Git comes with its |
|
own terminology and concepts; a new user of git should know about refs, |
|
remote branches, the index, fast-forward merges, pushes and pulls, detached |
|
heads, etc. It can all be a little intimidating at the outset, but the |
|
concepts are not that hard to grasp with a bit of study. |
|
|
|
Using git to generate patches for submission by email can be a good |
|
exercise while coming up to speed. |
|
|
|
When you are ready to start putting up git trees for others to look at, you |
|
will, of course, need a server that can be pulled from. Setting up such a |
|
server with git-daemon is relatively straightforward if you have a system |
|
which is accessible to the Internet. Otherwise, free, public hosting sites |
|
(Github, for example) are starting to appear on the net. Established |
|
developers can get an account on kernel.org, but those are not easy to come |
|
by; see https://kernel.org/faq/ for more information. |
|
|
|
The normal git workflow involves the use of a lot of branches. Each line |
|
of development can be separated into a separate "topic branch" and |
|
maintained independently. Branches in git are cheap, there is no reason to |
|
not make free use of them. And, in any case, you should not do your |
|
development in any branch which you intend to ask others to pull from. |
|
Publicly-available branches should be created with care; merge in patches |
|
from development branches when they are in complete form and ready to go - |
|
not before. |
|
|
|
Git provides some powerful tools which can allow you to rewrite your |
|
development history. An inconvenient patch (one which breaks bisection, |
|
say, or which has some other sort of obvious bug) can be fixed in place or |
|
made to disappear from the history entirely. A patch series can be |
|
rewritten as if it had been written on top of today's mainline, even though |
|
you have been working on it for months. Changes can be transparently |
|
shifted from one branch to another. And so on. Judicious use of git's |
|
ability to revise history can help in the creation of clean patch sets with |
|
fewer problems. |
|
|
|
Excessive use of this capability can lead to other problems, though, beyond |
|
a simple obsession for the creation of the perfect project history. |
|
Rewriting history will rewrite the changes contained in that history, |
|
turning a tested (hopefully) kernel tree into an untested one. But, beyond |
|
that, developers cannot easily collaborate if they do not have a shared |
|
view of the project history; if you rewrite history which other developers |
|
have pulled into their repositories, you will make life much more difficult |
|
for those developers. So a simple rule of thumb applies here: history |
|
which has been exported to others should generally be seen as immutable |
|
thereafter. |
|
|
|
So, once you push a set of changes to your publicly-available server, those |
|
changes should not be rewritten. Git will attempt to enforce this rule if |
|
you try to push changes which do not result in a fast-forward merge |
|
(i.e. changes which do not share the same history). It is possible to |
|
override this check, and there may be times when it is necessary to rewrite |
|
an exported tree. Moving changesets between trees to avoid conflicts in |
|
linux-next is one example. But such actions should be rare. This is one |
|
of the reasons why development should be done in private branches (which |
|
can be rewritten if necessary) and only moved into public branches when |
|
it's in a reasonably advanced state. |
|
|
|
As the mainline (or other tree upon which a set of changes is based) |
|
advances, it is tempting to merge with that tree to stay on the leading |
|
edge. For a private branch, rebasing can be an easy way to keep up with |
|
another tree, but rebasing is not an option once a tree is exported to the |
|
world. Once that happens, a full merge must be done. Merging occasionally |
|
makes good sense, but overly frequent merges can clutter the history |
|
needlessly. Suggested technique in this case is to merge infrequently, and |
|
generally only at specific release points (such as a mainline -rc |
|
release). If you are nervous about specific changes, you can always |
|
perform test merges in a private branch. The git "rerere" tool can be |
|
useful in such situations; it remembers how merge conflicts were resolved |
|
so that you don't have to do the same work twice. |
|
|
|
One of the biggest recurring complaints about tools like git is this: the |
|
mass movement of patches from one repository to another makes it easy to |
|
slip in ill-advised changes which go into the mainline below the review |
|
radar. Kernel developers tend to get unhappy when they see that kind of |
|
thing happening; putting up a git tree with unreviewed or off-topic patches |
|
can affect your ability to get trees pulled in the future. Quoting Linus: |
|
|
|
:: |
|
|
|
You can send me patches, but for me to pull a git patch from you, I |
|
need to know that you know what you're doing, and I need to be able |
|
to trust things *without* then having to go and check every |
|
individual change by hand. |
|
|
|
(https://lwn.net/Articles/224135/). |
|
|
|
To avoid this kind of situation, ensure that all patches within a given |
|
branch stick closely to the associated topic; a "driver fixes" branch |
|
should not be making changes to the core memory management code. And, most |
|
importantly, do not use a git tree to bypass the review process. Post an |
|
occasional summary of the tree to the relevant list, and, when the time is |
|
right, request that the tree be included in linux-next. |
|
|
|
If and when others start to send patches for inclusion into your tree, |
|
don't forget to review them. Also ensure that you maintain the correct |
|
authorship information; the git "am" tool does its best in this regard, but |
|
you may have to add a "From:" line to the patch if it has been relayed to |
|
you via a third party. |
|
|
|
When requesting a pull, be sure to give all the relevant information: where |
|
your tree is, what branch to pull, and what changes will result from the |
|
pull. The git request-pull command can be helpful in this regard; it will |
|
format the request as other developers expect, and will also check to be |
|
sure that you have remembered to push those changes to the public server. |
|
|
|
|
|
Reviewing patches |
|
----------------- |
|
|
|
Some readers will certainly object to putting this section with "advanced |
|
topics" on the grounds that even beginning kernel developers should be |
|
reviewing patches. It is certainly true that there is no better way to |
|
learn how to program in the kernel environment than by looking at code |
|
posted by others. In addition, reviewers are forever in short supply; by |
|
looking at code you can make a significant contribution to the process as a |
|
whole. |
|
|
|
Reviewing code can be an intimidating prospect, especially for a new kernel |
|
developer who may well feel nervous about questioning code - in public - |
|
which has been posted by those with more experience. Even code written by |
|
the most experienced developers can be improved, though. Perhaps the best |
|
piece of advice for reviewers (all reviewers) is this: phrase review |
|
comments as questions rather than criticisms. Asking "how does the lock |
|
get released in this path?" will always work better than stating "the |
|
locking here is wrong." |
|
|
|
Different developers will review code from different points of view. Some |
|
are mostly concerned with coding style and whether code lines have trailing |
|
white space. Others will focus primarily on whether the change implemented |
|
by the patch as a whole is a good thing for the kernel or not. Yet others |
|
will check for problematic locking, excessive stack usage, possible |
|
security issues, duplication of code found elsewhere, adequate |
|
documentation, adverse effects on performance, user-space ABI changes, etc. |
|
All types of review, if they lead to better code going into the kernel, are |
|
welcome and worthwhile.
|
|
|