1<title>Following Linux kernel development with git</title>
4<li><a href="#what">A "git bisect HOWTO" with a few extras.</a></li>
5<li><a href="#installing">Installing git</a></li>
6<li><a href="#downloading">Downloading the kernel with git</a></li>
7<li><a href="#updating">Updating your local copy</a></li>
8<li><a href="#looking">Looking at historical versions</a></li>
9<li><a href="#versions">Working with historical versions<a></li>
10<li><a href="#diff">Using git diff</a></li>
11<li><a href="#tarballs">Creating tarballs</a></li>
12<li><a href="#bisect">Bisect</a></li>
13<li><a href="#example">Example git bisect run</a></li>
14<li><a href="#commands">Command summary</a></li>
15<li><a href="#linus">Linus Tovalds talks about git</a></li>
18<a name="what><h2>A "git bisect HOWTO" with a few extras.</h2>
20<p>This document tells you how to follow Linux kernel development (and
21examine its history) with git. It does not assume you've ever used a source
22control system before, nor does it assume that you're familiar with
23"distributed" vs "centralized" source control systems.</p>
25<p>This document describes a read-only approach, suitable for trying out
26recent versions quickly, using "git bisect" to track down bugs, and
27applying patches temporarily to see if they work for you.
28If you want to learn how to save changes into your copy of the git history and
29submit them back to the kernel developers through git, you'll need
30<a href=http://www.kernel.org/pub/software/scm/git/docs/tutorial.html>a much
31larger tutorial</a> that explains concepts like "branches". This one
32shouldn't get in the way of doing that sort of thing, but it doesn't go there.</p>
34<a name="installing"><h2>Installing git</h2>
36<p>First, install a recent version of git. (Note that the user interface
37changed drastically in git-1.5.0, and this page only describes the new
40<p>If your distro doesn't have a recent enough version, you can grab a
41<a href=http://www.kernel.org/pub/software/scm/git/>source tarball</a> and
42build it yourself. (There's no ./configure, as root go
43"make install prefix=/usr". It needs zlib, libssl, libcurl, and libexpat.)</p>
45<p>When building from source, the easy way to get the man pages is to download
46the appropriate git-manpages tarball (at the same URL as the source code)
47and extract it into /usr/share/man. You want the man pages because "git help"
50<a name="downloading"><h2>Downloading the kernel with git</h2>
52<p>The following command will download the current linux-kernel repository into
53a local directory called "linux-git":</p>
56git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git linux-git
59<p>This downloads a local copy of the entire revision history (back to
602.6.12-rc2), which takes a couple hundred megabytes. It extracts the most
61recent version of all the files into your linux-git directory, but that's just
62a snapshot (generally referred to by git people as your
63"<a href=http://www.kernel.org/pub/software/scm/git/docs/glossary.html#def_working_tree>working copy</a>").
64The history is actually stored in the subdirectory "linux-git/.git", and the
65snapshot can be recreated from that (or changed to match any historical
66version) via various git commands explained below.</p>
68<p>You start with an up-to-the-minute copy of the linux kernel source, which
69you can use just like an extracted tarball (ignoring the extra files in the
70".git" directory). If you're interested in history from the bitkeeper days
71(before 2.6.12-rc2), that's stored in a seperate repository,
72"<b>git://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git</b>".
73(<a href=http://git.kernel.org>Here is a list of all git repositories hosted
74on kernel.org</a>.)</p>
76<p>(If you forget the URL a git repository came from, it's in the file
77".git/FETCH_HEAD". Normally you shouldn't need to care, since git remembers
80<a name="updating"><h2>Updating your local copy</h2>
82<p>The command "<b>git pull</b>" downloads all the changes committed to Linus's
83git repository since the last time you updated your copy, and appends those
84commits to your copy of the repository (in the .git subdirectory). In addition,
85this will automatically update the files in your working copy as appropriate.
86(If your working copy was set to a historical version, it won't be changed,
87but returning your working copy to the present after a pull will get you the
90<p>Note that this copies the revision history into your local .git directory.
91Other git commands (log, checkout, tag, blame, etc.) don't need to talk to
92the server, you can work on your laptop without an internet connection (or
93with a very slow one) and still have access to the complete revision history
94you've already downloaded.</p>
96<a name="looking"><h2>Looking at historical versions</h2>
98<p>The <b>git log</b> command lists the changes recorded in your repository,
99starting with the most recent and working back. The big hexadecimal numbers
100are unique identifiers (sha1sum) for each commit. If you want to specify a
101commit, you only need the first few digits, enough to form a unique prefix.
102(Six digits should be plenty.)</p>
104<p>You can limit the log to a specific file or directory, which lists
105only the commits changing that file/directory. Just add the file(s)
106you're interested in to the end of the <b>git log</b> command line.</p>
108<p>The <b>git tag -l</b> command shows all the tagged releases. These
109human-readable names can be used as synonyms for the appropriate commit
110identifier, which is useful when doing things like checkout and diff.
111The special tag "<b>master</b>" points to the most recent commit.</p>
113<p>The <b>git blame $FILE</b> command displays all the changes that resulted in
114the current state of a file. It shows each line, prefixed with the commit
115identifier which last changed that line. (If the default version of <b>git
116blame</b> is difficult to read on an 80 charater terminal, try <b>git blame
117$FILE | sed 's/([^)]*)//'</b> to see more of the file itself.)</p>
119<a name="versions"><h2>Working with historical versions</h2>
121<p>The <b>git checkout</b> command changes your working copy of the source to a
122specific version. The -f option to checkout backs out any local changes
123you've made to the files. The <b>git clean</b> command deletes any extra files
124in your working directory (ones which aren't checked into the repository).
125The -d option to clean deletes untracked directories as well as files.</p>
127<p>So to reset your working copy of the source to a historical version, go
128<b>git checkout -f $VERSION; git clean -d</b> where $VERSION is the tag or
129sha1sum identifier of the version you want. If you don't specify a $VERSION,
130git will default to "master" which is the most recent checkout in Linus's
131tree (what mercurial calls "tip" and Subversion calls HEAD), returning you
132to the present and removing any uncommitted local changes.</p>
134<p>Another way to undo all changes to your copy is to do "rm -rf *" in
135the linux-git directory (which doesn't delete hidden files like ".git"),
136followed by "git checkout -f" to grab fresh copies from the repository in
137the .git subdirectory. This generally isn't necessary. Most of the time,
138<b>git checkout -f</b> is sufficient to reset your working copy to the most
139recent version in the repository.</p>
141<p>If you lose track of which version is currently checked out as your working
142copy, use <b>git log</b> to see the most recent commits to the version you're
143looking at, and <b>git log master</b> to compare against the most recent
144commits in the repository.</p>
146<a name="diff"><h2>Using git diff</h2>
148<p>The command "git diff" shows differences between git versions. You can
149ask it to show differences between:</p>
151<li><b>git diff</b> - the current version checked out from the respository and all files in the working directory</li>
152<li><b>git diff v2.6.21</b> - a specific historical version and all files in the working directory</li>
153<li><b>git diff v2.6.20 v2.6.21</b> - all files in two different historial
155<li><b>git diff init/main.c</b> - specific locally modified files in the
156working directory that don't match what was checked out from the repository</li>
157<li><b>git diff v2.6.21 init/main.c</b> - specific file(s) in a specific historical version of the repository vs those same files in the working directory.</li>
158<li><b>git diff v2.6.20 v2.6.21 init/main.c</b> - specific files in two
159different historical version of the repository</li>
162<p>What git is doing is checking each argument to see if it recognizes it
163as a historical version sha1sum or tag, and if it isn't it checks to see if
164it's a file. If this is likely to cause confusion, you can use the magic
165argument "--" to indicate that all the arguments before that are versions
166and all the arguments after that are filenames.</p>
168<p>The argument <b>--find-copies-harder</b> tells git diff to detect renamed or
169copied files. Notice that git diff has a special syntax to indicate renamed
170or copied files, which is much more concise and portable than the traditional
171behavior of removing all lines from one file and adding them to another.
172(This behavior may become the default in a future version.)</p>
174<a name="tarballs"><h2>Creating tarballs</h2>
176<p>The <b>git archive $VERSION</b> command creates a tarball (written to
177stdout) of the given version. Note that "master" isn't the default here,
178you have to specify that if you want the most up-to-date version.
179You can pipe it through bzip and write it to a file (<b>git archive master |
180bzip2 > master.tar.bz2</b>) or you can use git archive to grab a clean copy
181out of your local git repository and extract it into another directory, ala:</p>
186git archive master | tar xCv $COPY
190<p>You can also use the standard Linux kernel out-of-tree building
191infrastructure on the git working directory, ala:</p>
196make allnoconfig O=$OTHERDIR
203<p>Finally, you can build in your git directory, and then clean it up
204afterwards with <b>git checkout -f; git clean -d</b>. (Better than
205"make distclean".)</p>
207<a name="bisect"><h2>Bisect</h2>
209<p>Possibly the most useful thing git does for non-kernel developers is
210<b>git bisect</b>, which can track down a bug to a specific revision. This
211is a multi-step process which binary searches through the revision history
212to find a specific commit responsible for a testable change in behavior.</p>
214<p>(You don't need to know this, but bisect turns out to be nontrivial to
215implement in a distributed source control system, because the revision history
216isn't linear. When the history branches and comes back together again, binary
217searching through it requires remembering more than just a single starting and
218ending point. That's why bisect works the way it does.)</p>
220<p>The git bisect commands are:</p>
222<li><b>git bisect start</b> - start a new bisect. This opens a new (empty)
223log file tracking all the known good and bad versions.</li>
224<li><b>git bisect bad $VERSION</b> - Identify a known broken version. (Leaving
225$VERSION blank indicates the current version, "master".)</li>
226<li><b>git bisect good $VERSION</b> - Identify a version that was known to
228<li><b>git bisect log</b> - Show bisection history so far this run.</li>
229<li><b>git bisect replay $LOGFILE</b> - Reset to an earlier state using the output of git bsect log.</li>
230<li><b>git bisect reset</b> - Finished bisecting, clean up and return to
231head. (If git bisect start says "won't bisect on seeked tree", you forgot
232to do this last time and should do it now.)</li>
235<p>To track down the commit that introduced a bug via git bisect, start with
236<b>git bisect reset master</b> (just to be safe), then <b>git bisect start</b>.
237Next identify the last version known to work (ala <b>git bisect good
238v2.6.20</b>), and identify the first bad version you're aware of (if it's
239still broken, use "master".)</p>
241<p>After you identify one good and one bad version, git will grind for a bit
242and reset the working directory state to some version in between, displaying
243the version identifier it selected. Test this version (build and run your
244test), then identify it as good or bad with the appropriate git bisect
245command. (Just "git bisect good" or "get bisect bad", there's no need to
246identify version here because it's the current version.) After each such
247identification, git will grind for a bit and find another version to test,
248resetting the working directory state to the new version until it narrows
249it down to one specific commit.</p>
251<p>The biggest problem with <b>git bisect</b> is hitting a revision that
252doesn't compile properly. When the build breaks, you can't determine
253whether or not the current version is good or bad. This is where
254<b>git bisect log</b> comes into play.</p>
256<p>When in doubt, save the git bisect log output to a file
257(<b>git bisect log > ../bisect.log</b>). Then make a guess
258whether the commit you can't build would have shown the problem if you
259could build it. If you guess wrong (hint: every revision bisect wants
260to test after that comes out the opposite of your guess, all the way to the
261end) do a <b>git bisect replay ../bisect.log</b> to restart from your
262saved position, and guess the other way. If you realize after the fact you
263need to back up, the bisect log is an easily editable text file you can
264always chop a few lines off the end of.</p>
266<a name="example"><h2>Example git bisect run</h2>
268<p>Here is a real git bisect run I did on the <a href=http://qemu.org>qemu</a>
269git repository (git://git.kernel.dk/data/git/qemu) to figure out why
270the PowerPC Linux kernel I'd built was hanging during IDE controller
271intiialization under the current development version of qemu-system-ppc
272(but not under older versions).</p>
275<pre><b>$ git bisect reset master</b>
276Already on branch "master"
277<b>$ git bisect good release_0_8_1</b>
278You need to start by "git bisect start"
279Do you want me to do it for you [Y/n]? y
280<b>$ git bisect bad master</b>
281Bisecting: 753 revisions left to test after this
282[7c8ad370662b706b4f46497f532016cc7a49b83e] Embedded PowerPC Device Control Registers infrastructure.
283<b>$ ./configure && make -j 2 && ~/mytest</b>
286<b>$ git bisect bad # The test failed</b>
287Bisecting: 376 revisions left to test after this
288[255d4f6dd496d2d529bce38a85cc02199833f080] Simplify error handling again.
289<b>$ ./configure && make -j 2 && ~/mytest</b>
290WARNING: "gcc" looks like gcc 4.x
292./configure: 357: Syntax error: Bad fd number
293<b>$ git bisect log > ../bisect.log # Darn it, build break. Save state and...</b>
294<b>$ git bisect good # Wild guess because I couldn't run the test.</b>
295Bisecting: 188 revisions left to test after this
296[16bcc6b31799ca01cd389db7cb90a345e9b68dd9] Fix wrong interrupt number for the second serial interface.
297<b>$ ./configure && make -j 2 && ~/mytest</b>
300<b>$ git bisect good # Hey, maybe my guess was right</b>
301Bisecting: 94 revisions left to test after this
302[37781cc88f69e45624c1cb15321ddd2055cf74b6] Fix usb hid and mass-storage protocol revision, by Juergen Keil.
303<b>$ ./configure && make -j 2 && ~/mytest</b>
306<b>$ git bisect good</b>
307Bisecting: 47 revisions left to test after this
308[30347b54b7212eba09db05317217dbc65a149e25] Documentation update
309<b>$ ./configure && make -j 2 && ~/mytest</b>
312<b>$ git bisect good</b>
313Bisecting: 23 revisions left to test after this
314[06a21b23c22ac18d04c9f676b9b70bb6ef72d7f1] Set proper BadVAddress value for unaligned instruction fetch.
315<b>$ ./configure && make -j 2 && ~/mytest</b>
318<b>$ git bisect good</b>
319Bisecting: 11 revisions left to test after this
320[da77e9d7918cabed5b0725f87496a1dc28da8b8c] Fix exception handling cornercase for rdhwr.
321<b>$ ./configure && make -j 2 && ~/mytest</b>
324<b>$ git bisect good</b>
325Bisecting: 5 revisions left to test after this
326[36f447f730f61ac413c5b1c4a512781f5dea0c94] Implement embedded IRQ controller for PowerPC 6xx/740 & 750.
327<b>$ ./configure && make -j 2 && ~/mytest</b>
330<b>$ git bisect bad # Oh good, I was getting worried I'd guessed wrong above...</b>
331Bisecting: 2 revisions left to test after this
332[d4838c6aa7442fae62b08afbf4c358200f10ec74] Proper handling of reserved bits in the context register.
333<b>$ ./configure && make -j 2 && ~/mytest</b>
336Bisecting: 1 revisions left to test after this
337[a8b64e6f4c7f3c4850be5fd303bf590564264294] Fix monitor disasm output for Sparc64 target
338<b>$ ./configure && make -j 2 && ~/mytest</b>
341<b>$ git bisect good</b>
34236f447f730f61ac413c5b1c4a512781f5dea0c94 is first bad commit
343commit 36f447f730f61ac413c5b1c4a512781f5dea0c94
344Author: j_mayer <j_mayer>
345Date: Mon Apr 9 22:45:36 2007 +0000
347 Implement embedded IRQ controller for PowerPC 6xx/740 & 750.
348 Fix PowerPC external interrupt input handling and lowering.
349 Fix OpenPIC output pins management.
350 Fix multiples bugs in OpenPIC IRQ management.
351 Fix OpenPIC CPU(s) reset function.
352 Fix Mac99 machine to properly route OpenPIC outputs to the PowerPC input pins.
353 Fix PREP machine to properly route i8259 output to the PowerPC external
356:100644 100644 0eabacd6434b8e40876581605c619513bf9ac512 284cb92ae83a2a36e05137d3532106ff85167364 M cpu-exec.c
357:040000 040000 68740f5b1330c7859abfea3ce31062cb92adaa7f 5c48b0d20f1c4d3115881b5e9e5b6c1d681f4880 M hw
358:040000 040000 3ad1f0d09c60d8190d98b28318519ebaaccbb569 69efc274cec1801848de9238ae71e97681978433 M target-ppc
359:100644 100644 2f87946e874e8f6cbf9afd47c65e0baff236dc45 b40ff3747530d275181ff071c9cc9cff1d5ba02d M vl.h
360<b>$ git bisect reset</b>
366<a name="commands"><h2>Command summary</h2>
368<p><b>git help</b></p> - List available commands. You can also go
369<b>git help COMMANDNAME</b> to see help on a specific command. Note,
370this displays the man page for the appropriate command, so you need to have
371the git man pages installed for it to work.</p>
373<p><b>git clone git://blah/blah/blah localdir</b> - Download a repository
374from the web into "localdir". Linus's current repository is at
375"git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git",
376the old history from the bitkeeper days (before 2.6.12-rc2) is at
377"git://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git", and
378there are lots of <a href=http;//git.kernel.org>other trees hosted on
379kernel.org</a> and elsewhere.</p>
381<p><b>git pull</b> - Freshen up your local copy of the repository, downloading
382and merging all of Linus's changes since last time you did this. In addition
383to appending lots of commits to your repository in the .git directory, this
384also updates the snapshot of the files (if it isn't already pointing into
387<p><b>git log</b> - List the changes recorded in your repository, starting with
388the most recent and working back. Note: the big hex numbers are unique
389identifiers (sha1sum) for each commit. If you want to specify a commit, you
390only need a unique prefix (generally the first four digits is enough).</p>
392<p><b>git tag -l</b> - Show all the tagged releases. These human-readable
393names can be used as synonyms for the appropriate commit identifier when
394doing things like checkout and diff. (Note, the special tag "master"
395points to the most recent commit.)</p>
397<p><b>git checkout -f; git clean -d</b> - reset your snapshot to the most recent
398commit. The "checkout" command updates your snapshot to a specific version
399(defaulting to the tip of the current branch). The -f argument says to back
400out any local changes you've made to the files, and "clean -d" says to
401delete any extra files in the snapshot that aren't checked into the
404<p><b>git diff</b> - Show differences between two commits, such as
405"git diff v2.6.20 v2.6.21". You can also specify specific files you're
406interested in, ala "git diff v2.6.20 v2.6.21 README init/main.c". If you
407specify one version it'll compare your working directory against that version,
408and if you specify no versions it'll compare the version you checked out
409against your working directory. Anything that isn't recognized as the start of
410a commit indentifying sha1sum, or a tagged release, is assumed to be a filename.
411If this causes problems, you can add "--" to the command line to explicitly
412specify that arguments before that (if any) are version identifiers and all the
413arguments after that are filenames. Add "--find-copies-harder" to detect
416<a name="linus"><h2>Linus Tovalds talks about git</h2>
418<p>In <a href=http://youtube.com/watch?v=4XpnKHJAok8>this Google Tech Talk</a></p>
421 "git show @{163}"... one character less...
423http://www.kernel.org/pub/software/scm/git/docs/glossary.html#def_working_tree