summaryrefslogtreecommitdiff
path: root/kernel-devel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel-devel')
-rw-r--r--kernel-devel/kernel-best-practices/handout_kernel-best-practices_en.tex498
1 files changed, 498 insertions, 0 deletions
diff --git a/kernel-devel/kernel-best-practices/handout_kernel-best-practices_en.tex b/kernel-devel/kernel-best-practices/handout_kernel-best-practices_en.tex
new file mode 100644
index 0000000..bd1140b
--- /dev/null
+++ b/kernel-devel/kernel-best-practices/handout_kernel-best-practices_en.tex
@@ -0,0 +1,498 @@
+\input{confighandout}
+
+\subsection{Kernel Best-Practices}
+
+Linux development is heavily distributed. There are many powerful tools, which
+assist the distributed development. The most important and powerful ones, will
+be presented in this chapter.
+
+\subsubsection{diff and patch - the basics}
+
+Linux kernel development is based on patches. A patch is a file which describes
+the changes between an original version of a source tree and a modified one.
+
+For simplicity, a source tree with only one file will be used as example:
+
+orig/hello.c
+
+\begin{lstlisting}
+int main (int argc, char **argv)
+{
+ return 0;
+}
+\end{lstlisting}
+
+This source tree will be copied:
+
+\begin{lstlisting}
+cp -a orig new
+\end{lstlisting}
+
+The new source tree be modified:
+
+new/hello.c
+
+\begin{lstlisting}
+#include <stdio.h>
+
+int main (int argc, char **argv)
+{
+ printf ("Huhu World\n");
+ return 0;
+}
+\end{lstlisting}
+
+The diff commands generates a patch file:
+
+\begin{lstlisting}
+diff -Nur orig new > hello.patch
+\end{lstlisting}
+
+The content of hello.patch is:
+
+\begin{lstlisting}
+--- orig/hello.c 2011-03-22 22:38:40.796426752 +0100
++++ new/hello.c 2011-03-22 22:39:02.472155769 +0100
+@@ -1,4 +1,7 @@
++#include <stdio.h>
++
+ int main (int argc, char **argv)
+ {
++ printf ("Huhu World\n");
+ return 0;
+ }
+\end{lstlisting}
+
+The newly added lines are prefixed with a '+', removed lines with a '-'.
+
+If the patch file is more complex, diffstat informs you about the content:
+
+\begin{lstlisting}
+diffstat hello.patch
+ hello.c | 3 +++
+ 1 file changed, 3 insertions(+)
+\end{lstlisting}
+
+Anyone who has the original source version, can apply the generated patch. The
+result is an updated version of the source tree:
+
+\begin{lstlisting}
+cd orig
+patch -p1 < ../hello.patch
+\end{lstlisting}
+
+With the argument -pX the numbers of stripped directories (in our case new) can be defined.
+
+With the argument -R a patch can be 'reverse applied' aka removed. The result
+will be the original source tree.
+
+Don't apply or remove the same patch more then once. If you have more than one
+patch, apply and revert the patches in the right order. Else the resulting
+source tree will be undefined.
+
+If the original source differs from the one, the patch was created. The patch
+may apply with 'HUNKS'. This means, the changes can be applied, but the line
+numbers, given after the @@@ tag don't fit exactly.
+
+If the original source differs from the one, the patch was created. It is
+possible, that the patch won't apply anymore. Then all rejects are saved in a
+file called <original file name>.rej
+
+\subsubsection{quilt}
+
+diff and patch work fine for one patch. But if you have to handle a queuqe of
+patches it will be hard to keep the order of the patches, update a single patch,etc. quilt is a tool, for managing patch queques.
+
+The above example, using quilt:
+
+orig/hello.c
+
+\begin{lstlisting}
+int main (int argc, char **argv)
+{
+ return 0;
+}
+\end{lstlisting}
+
+create a new patch:
+
+\begin{lstlisting}
+cd orig
+quilt new hello.patch
+quilt edit hello.c
+\end{lstlisting}
+
+your default editor will be opened, make your changes to the source:
+
+\begin{lstlisting}
+#include <stdio.h>
+
+int main (int argc, char **argv)
+{
+ printf ("Huhu World\n");
+ return 0;
+}
+\end{lstlisting}
+
+write the changes into the patch file:
+
+\begin{lstlisting}
+quilt refresh
+\end{lstlisting}
+
+two files will be generated:
+
+\begin{lstlisting}
+ls patches/
+hello.patch series
+\end{lstlisting}
+
+hello.patch is our well-known patch. series contains the name of our patch.
+
+The patch can be applied
+
+\begin{lstlisting}
+quilt push
+File series fully applied, ends at patch patches/hello.patch
+\end{lstlisting}
+
+Then we create a new patch on top of our current queque:
+
+\begin{lstlisting}
+quilt new seperate-print-in-own-function.patch
+quilt edit hello.c
+\end{lstlisting}
+
+\begin{lstlisting}
+#include <stdio.h>
+
+void print ()
+{
+ printf ("Huhu World\n");
+}
+
+int main (int argc, char **argv)
+{
+ print ();
+ return 0;
+}
+\end{lstlisting}
+
+both patches are now listed in the series file:
+
+\begin{lstlisting}
+cat patches/series
+hello.patch
+seperate-print-in-own-function.patch
+\end{lstlisting}
+
+All patches can be reverted at once:
+
+\begin{lstlisting}
+quilt pop -a
+Removing patch patches/seperate-print-in-own-function.patch
+Restoring hello.c
+
+Removing patch patches/hello.patch
+Restoring hello.c
+
+No patches applied
+\end{lstlisting}
+
+You can zip the quilt queque and share it with other programmers.
+
+\subsubsection{git}
+
+But if they modify the quilt queque at the same time, as you. Merging the
+queques by hand may be hard. In projects like the linux kernel, it is a no go.
+
+Currently Linus' (and many others) Kernel trees are managed by git. Git is a
+very powerful version control system. The most important difference to other
+systems, like subversion, is that the hole history of a project is held local.
+Nobody should commit into your git tree. In git you pull the changes from other
+people into your tree.
+
+Let's have a look at git:
+
+orig/hello.c
+
+\begin{lstlisting}
+int main (int argc, char **argv)
+{
+ return 0;
+}
+\end{lstlisting}
+
+init git:
+
+\begin{lstlisting}
+$cd orig
+$git init .
+Initialized empty Git repository in /home/manut/vorlesung.git/orig/.git/
+$git config user.email "manut@mecka.net"
+$git config user.name "Manuel Traut"
+\end{lstlisting}
+
+The configuration is saved at .git/config
+If git config --global is used the configuration will be used by all
+repositories which don't have a own configuration. Then it is saved at
+~/.gitconfig
+
+Now add the files to version control and commit your initial code.
+
+\begin{lstlisting}
+$git add hello.c
+$git commit -sa
+\end{lstlisting}
+
+The default editor will be opened, to enter a commit message:
+
+\begin{lstlisting}
+initial import of the hello world source
+
+this projects is aimed to show the use of git.
+
+Signed-off-by: Manuel Traut <manut@mecka.net>
+
+# Please enter the commit message for your changes. Lines starting
+# with '#' will be ignored, and an empty message aborts the commit.
+# On branch master
+#
+# Initial commit
+#
+# Changes to be committed:
+# (use "git rm --cached <file>..." to unstage)
+#
+# new file: hello.c
+#
+
+[master (root-commit) 473cf10] initial import of the hello world source
+ 1 files changed, 4 insertions(+), 0 deletions(-)
+ create mode 100644 hello.c
+
+\end{lstlisting}
+
+Now edit the source tree and generate commit your changes:
+
+\begin{lstlisting}
+$patch -p1 < ../hello.patch
+$git commit -sa
+
+add stdio include, print hello world
+
+prints 'Huhu World' to stdout
+
+Signed-off-by: Manuel Traut <manut@mecka.net>
+
+# Please enter the commit message for your changes. Lines starting
+# with '#' will be ignored, and an empty message aborts the commit.
+# On branch master
+# Changes to be committed:
+# (use "git reset HEAD <file>..." to unstage)
+#
+# modified: hello.c
+
+[master 6ea27e6] add stdio include, print hello world
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+\end{lstlisting}
+
+A hash will be generated that can be used to identify each patch. A history
+and a single patch can be displayed with these commands:
+
+\begin{lstlisting}
+$git log
+commit 6ea27e6199aeac63055d845ef40fecd4b594f1d7
+Author: Manuel Traut <manut@mecka.net>
+Date: Tue Mar 22 23:37:13 2011 +0100
+
+ add stdio include, print hello world
+
+ prints 'Huhu World' to stdout
+
+ Signed-off-by: Manuel Traut <manut@mecka.net>
+
+commit 473cf10e95778c54d49fc6ea368e196f1347ac8a
+Author: Manuel Traut <manut@mecka.net>
+Date: Tue Mar 22 23:31:50 2011 +0100
+
+ initial import of the hello world source
+
+ this projects is aimed to show the use of git.
+
+ Signed-off-by: Manuel Traut <manut@mecka.net>
+
+
+$git shortlog
+Manuel Traut (2):
+ initial import of the hello world source
+ add stdio include, print hello world
+
+$git show 473cf10e95778c54d49fc6ea368e196f1347ac8a
+commit 473cf10e95778c54d49fc6ea368e196f1347ac8a
+Author: Manuel Traut <manut@mecka.net>
+Date: Tue Mar 22 23:31:50 2011 +0100
+
+ initial import of the hello world source
+
+ this projects is aimed to show the use of git.
+
+ Signed-off-by: Manuel Traut <manut@mecka.net>
+
+diff --git a/hello.c b/hello.c
+new file mode 100644
+index 0000000..b891504
+--- /dev/null
++++ b/hello.c
+@@ -0,0 +1,4 @@
++int main (int argc, char **argv)
++{
++ return 0;
++}
+
+\end{lstlisting}
+
+To add some new functionality it's a good idea to temporarily create a new
+branch:
+
+\begin{lstlisting}
+$git branch fancy-new-stuff
+$git checkout fancy-new-stuff
+Switched to branch 'fance-new-stuff'
+\end{lstlisting}
+
+It's possible to go back in history:
+
+\begin{lstlisting}
+git reset --hard 473cf10e95778c54d49fc6ea368e196f1347ac8a
+HEAD is now at 473cf10 initial import of the hello world source
+\end{lstlisting}
+
+Make changes:
+
+\begin{lstlisting}
+#include <stdio.h>
+
+int main (int argc, char **argv)
+{
+ printf ("Hello World\n");
+ return 0;
+}
+\end{lstlisting}
+
+and commit them:
+
+\begin{lstlisting}
+$git commit -sa
+
+HELLO world
+
+..not huhu world
+
+Signed-off-by: Manuel Traut <manut@mecka.net>
+
+[fance-new-stuff 72e3346] HELLO world
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+\end{lstlisting}
+
+You like the new version and want to merge it into your master tree:
+
+\begin{lstlisting}
+$git checkout master
+Switched to branch 'master'
+$git merge fancy-new-stuff
+Auto-merging hello.c
+CONFLICT (content): Merge conflict in hello.c
+Automatic merge failed; fix conflicts and then commit the result.
+\end{lstlisting}
+
+Git reports an CONFLICT because an automatic merge is not possible. The same
+line (printf) has different content in master and fancy-new-stuff. So the merge
+conflict has to be resolved by hand.
+
+hello.c
+
+\begin{lstlisting}
+#include <stdio.h>
+
+int main (int argc, char **argv)
+{
+<<<<<<< HEAD
+ printf ("Huhu World\n");
+=======
+ printf ("Hello World\n");
+>>>>>>> fancy-new-stuff
+ return 0;
+}
+\end{lstlisting}
+
+All lines which shouldn't be there can be removed by hand. This result needs
+to be commited:
+
+\begin{lstlisting}
+$git commit -sa
+
+Merge branch 'fance-new-stuff'
+
+Conflicts:
+ hello.c
+
+Signed-off-by: Manuel Traut <manut@mecka.net>
+#
+# It looks like you may be committing a MERGE.
+# If this is not correct, please remove the file
+# .git/MERGE_HEAD
+# and try again.
+#
+
+# Please enter the commit message for your changes. Lines starting
+# with '#' will be ignored, and an empty message aborts the commit.
+# On branch master
+# Changes to be committed:
+#
+# modified: hello.c
+#
+
+[master 1815151] Merge branch 'fance-new-stuff'
+
+$git log
+
+commit 1815151a08537bd2403605f8adb22852cfdb2d23
+Merge: 6ea27e6 72e3346
+Author: Manuel Traut <manut@mecka.net>
+Date: Tue Mar 22 23:57:19 2011 +0100
+
+ Merge branch 'fance-new-stuff'
+
+ Conflicts:
+ hello.c
+
+ Signed-off-by: Manuel Traut <manut@mecka.net>
+
+commit 72e3346872ec9298f2b582e2859b1dbf1304f77e
+Author: Manuel Traut <manut@mecka.net>
+Date: Tue Mar 22 23:49:58 2011 +0100
+
+ HELLO world
+
+ ..not huhu world
+
+ Signed-off-by: Manuel Traut <manut@mecka.net>
+
+...
+\end{lstlisting}
+
+Further exercises:
+
+\begin{itemize}
+\item pull from another repository
+\item track a repository
+\item what is a bare repository?
+\item find bugs with git bisect
+\item extract a patch queque from your git branch
+\item send mails with git
+\item build a svn - git bridge
+\end{itemize}
+
+\input{tailhandout}