comparison local/git-quick.html @ 78:307408bf8982

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