Penguin

The model for kernel development seems to be at present that everybody at one time or another clones off LinusTorvalds git tree and then creates a branch (see the howto on how to do this). You then make your changes and when you have a kernel that you like you produce patches off it and mail it out or you ask somebody to pull from your tree.

If you want to skip all the documentation and just make a clone of Linus' tree you can type:

git-clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git mysourcedir

When people talk about pulling or rebasing, all it really means is transferring the appropriate objects over. Provided you have created your own branch that is not a problem. It is not mentioned anywhere but because each change is given a unique number, provided that you have set up a branch (documented in howto), you can switch to a different Git and it works without losing your changes as most Gits are based around LinusTorvalds' Git tree and everybody just freely exchanges objects (files) around the Git trees. I would advise you to commit your objects before rebasing, otherwise a git checkout -f will blow your changes away, as rebasing usually changes the branch back to master rather than your own.

David Miller says this about pulling out patches:

If you keep your .git/ORIG_HEAD sane, you can use a script like the following to pull your local changes out of a tree one-by-one. It drops them into a directory called patches/ at the top-level and names them 1.diff, 2.diff, 3.diff, etc. with changelogs prepended to the beginning. I call it git-mkpatches.

#/bin/sh

mkdir patches/

count="1"
for i in $(git-rev-list HEAD ^ORIG_HEAD | tac)
do
   git-diff-tree --pretty -p ${i} > patches/$count.diff
   count=$(($count + 1))
done

The best Git howto that I have found is http://linux.yyz.us/git-howto.html

Also more potentially useful information (untested by me -- IanMcDonald)

Also, a bonus recipe: how to import Linus's pack files (it's easy).

This recipe presumes that you have a vanilla-Linus repo (/repo/linux-2.6) and your own repo (/repo/myrepo-2.6).

$ cd /repo/myrepo-2.6
$ git-fsck-cache                # fsck, make sure we're OK
$ git pull /repo/linux-2.6/.git # make sure we're up-to-date
$ cp -al ../linux-2.6/.git/objects/pack .git/objects
$ cp ../linux-2.6/.git/refs/tags/* .git/refs/tags
$ git-prune-packed
$ git-fsck-cache                # fsck #2, make sure we're OK

This recipe reduced my kernel.org sync from 50,000 files to 5,000 files.

Git has got much better at merges now. In most cases the following commands will give you an updated kernel tree

git pull
git-reset

The only exception to this is that it only pulls from the master tree.

If you want to then work on an older version then do the following for example if you want to work on 2.6.14:

git-reset --hard v2.6.14

If you want to update to a tag older than 2.6.11 you will need to use a git repository that contains all the history that was in Bitkeeper.

Sometimes after doing a git-pull you can have fatal merge errors. The best way to resolve this is often to type git-reset.

If you get funny kernel version numbers when using Git it is a "feature" that can be turned off by unsetting CONFIG_LOCAL_VERSION. If you are in the menuconfig you can do this by going to General setup-->Automatically append version information to the version string.

Most LinuxKernel related Gits can be found at http://www.kernel.org/git/ which is where you should pull/rebase from if you are doing serious KernelDevelopment.

To make a copy of a git locally and quickly type the following:

git-clone -l -s -n sourcedir/.git destdir

This can be useful if you want to sync up to a new kernel tree and want to minimise downloads.

If you want to make a copy of a remote tree but reuse existing files that are stored locally do something like:

git-clone --reference linus git://git.kernel.org/pub/scm/linux/kernel/git/acme/net-2.6.20.git acme-20

This example creates a new git tree which is a copy of acme's remote one, stores it in the directory acme-20 but it also shares files with the git tree in linus. This can be very useful if you keep one tree of Linus' up to date and then keep making copies of other developers trees in this way as they change and can't be pulled easily after they get rebased.

Using an origin file

If you want to do a git pull without having to specify where to get it from everytime edit the file .git/remotes/origin to be in this format where of course you change the URL:

URL: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Pull: master:origin

In git version 1.5 the above has changed and the file is now in .git/config. There is also a new command git-remote for managing multiple remote repositories.

Using git bisect

To use git bisect go to the bad code first (normally where you are at) and then type git bisect start and then git bisect bad

Now go to a place that is good by checking out code something like git-reset --hard v2.6.19-rc6. If that proves to be good then do git bisect good and then do each change marking good or bad with git bisect good or git bisect bad until you find the problem.

See also http://www.kernel.org/pub/software/scm/git/docs/howto/isolate-bugs-with-bisect.txt

Tip: Sometimes you lose track of where you came from so before you use git-bisect go into the .git directory and make a copy of the HEAD file so you know where you started! You can then always go back by typing:

git-reset --hard COPY_HEAD

where COPY_HEAD is your copy of HEAD....

However check the contents of the HEAD file as sometimes it's just a reference such as ref: refs/head/master in which case make a copy of that file which is being pointed to.

You can do this also by typing:

git bisect reset master
git reset --hard FETCH_HEAD

providing you want to go back to the last time you synced up.

Working with branches

A key feature of git is to maintain branches of code. For example you might keep Linus' code and your own in separate branches.

To create a branch do the following:

git-branch mybranch

Now switch to it like:

git-checkout mybranch

If you want to merge back with a branch (e.g. master which is Linus' branch)

git-merge "A comment" mybranch master

Series of patches

There is a tool to help manage a series of patches called Stacked Git or stgit for short. The Debian Package is called stgit.

Basically you create a branch (see above) and then manage stacks of patches in this and resync upstream when you want to.

Mailing patches. ArnaldoMelo says

I use mutt for everything now, did it for years, then tried to use
thunderbird, evolution, kmail, you name it, ran away screaming back to
good old mutt + vi.

For sending patches I'll use git-send-email in the next DCCP batch, the
way it uses reply-to to chain patch series is awesome, and it'll save
lotsa time by being able to use it together with 'git-format-patch -n
origin', so, in summary what I do is:

1. git-clone --reference linus-2.6 davem-2.6 acme-2.6
2. hack away (these days, mostly merge like a turtle :-P)
3. GIT_AUTHOR_NAME="Gerrit" GIT_AUTHOR_EMAIL="gerrit@..."  git-commit -a -s
4. git-format-patch -n origin
5. write 0000-patch-series.txt describing the patche series
6. push to master.kernel.org (that will be propagated to
  www.kernel.org/git, etc)
7. git-send-email with 0000-patch-series.txt and what was produced in
  step #4
8. rm -rf acme-2.6
9. hiatus, that thing called Real Work does a blunt, real time preempt
10. goto #1

Part of CategoryKernel