Mercurial > hg > kdocs
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 --> |