Imported Upstream version 20090801
Francois Marier
14 years ago
0 | GNU GENERAL PUBLIC LICENSE | |
1 | Version 3, 29 June 2007 | |
2 | ||
3 | Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> | |
4 | Everyone is permitted to copy and distribute verbatim copies | |
5 | of this license document, but changing it is not allowed. | |
6 | ||
7 | Preamble | |
8 | ||
9 | The GNU General Public License is a free, copyleft license for | |
10 | software and other kinds of works. | |
11 | ||
12 | The licenses for most software and other practical works are designed | |
13 | to take away your freedom to share and change the works. By contrast, | |
14 | the GNU General Public License is intended to guarantee your freedom to | |
15 | share and change all versions of a program--to make sure it remains free | |
16 | software for all its users. We, the Free Software Foundation, use the | |
17 | GNU General Public License for most of our software; it applies also to | |
18 | any other work released this way by its authors. You can apply it to | |
19 | your programs, too. | |
20 | ||
21 | When we speak of free software, we are referring to freedom, not | |
22 | price. Our General Public Licenses are designed to make sure that you | |
23 | have the freedom to distribute copies of free software (and charge for | |
24 | them if you wish), that you receive source code or can get it if you | |
25 | want it, that you can change the software or use pieces of it in new | |
26 | free programs, and that you know you can do these things. | |
27 | ||
28 | To protect your rights, we need to prevent others from denying you | |
29 | these rights or asking you to surrender the rights. Therefore, you have | |
30 | certain responsibilities if you distribute copies of the software, or if | |
31 | you modify it: responsibilities to respect the freedom of others. | |
32 | ||
33 | For example, if you distribute copies of such a program, whether | |
34 | gratis or for a fee, you must pass on to the recipients the same | |
35 | freedoms that you received. You must make sure that they, too, receive | |
36 | or can get the source code. And you must show them these terms so they | |
37 | know their rights. | |
38 | ||
39 | Developers that use the GNU GPL protect your rights with two steps: | |
40 | (1) assert copyright on the software, and (2) offer you this License | |
41 | giving you legal permission to copy, distribute and/or modify it. | |
42 | ||
43 | For the developers' and authors' protection, the GPL clearly explains | |
44 | that there is no warranty for this free software. For both users' and | |
45 | authors' sake, the GPL requires that modified versions be marked as | |
46 | changed, so that their problems will not be attributed erroneously to | |
47 | authors of previous versions. | |
48 | ||
49 | Some devices are designed to deny users access to install or run | |
50 | modified versions of the software inside them, although the manufacturer | |
51 | can do so. This is fundamentally incompatible with the aim of | |
52 | protecting users' freedom to change the software. The systematic | |
53 | pattern of such abuse occurs in the area of products for individuals to | |
54 | use, which is precisely where it is most unacceptable. Therefore, we | |
55 | have designed this version of the GPL to prohibit the practice for those | |
56 | products. If such problems arise substantially in other domains, we | |
57 | stand ready to extend this provision to those domains in future versions | |
58 | of the GPL, as needed to protect the freedom of users. | |
59 | ||
60 | Finally, every program is threatened constantly by software patents. | |
61 | States should not allow patents to restrict development and use of | |
62 | software on general-purpose computers, but in those that do, we wish to | |
63 | avoid the special danger that patents applied to a free program could | |
64 | make it effectively proprietary. To prevent this, the GPL assures that | |
65 | patents cannot be used to render the program non-free. | |
66 | ||
67 | The precise terms and conditions for copying, distribution and | |
68 | modification follow. | |
69 | ||
70 | TERMS AND CONDITIONS | |
71 | ||
72 | 0. Definitions. | |
73 | ||
74 | "This License" refers to version 3 of the GNU General Public License. | |
75 | ||
76 | "Copyright" also means copyright-like laws that apply to other kinds of | |
77 | works, such as semiconductor masks. | |
78 | ||
79 | "The Program" refers to any copyrightable work licensed under this | |
80 | License. Each licensee is addressed as "you". "Licensees" and | |
81 | "recipients" may be individuals or organizations. | |
82 | ||
83 | To "modify" a work means to copy from or adapt all or part of the work | |
84 | in a fashion requiring copyright permission, other than the making of an | |
85 | exact copy. The resulting work is called a "modified version" of the | |
86 | earlier work or a work "based on" the earlier work. | |
87 | ||
88 | A "covered work" means either the unmodified Program or a work based | |
89 | on the Program. | |
90 | ||
91 | To "propagate" a work means to do anything with it that, without | |
92 | permission, would make you directly or secondarily liable for | |
93 | infringement under applicable copyright law, except executing it on a | |
94 | computer or modifying a private copy. Propagation includes copying, | |
95 | distribution (with or without modification), making available to the | |
96 | public, and in some countries other activities as well. | |
97 | ||
98 | To "convey" a work means any kind of propagation that enables other | |
99 | parties to make or receive copies. Mere interaction with a user through | |
100 | a computer network, with no transfer of a copy, is not conveying. | |
101 | ||
102 | An interactive user interface displays "Appropriate Legal Notices" | |
103 | to the extent that it includes a convenient and prominently visible | |
104 | feature that (1) displays an appropriate copyright notice, and (2) | |
105 | tells the user that there is no warranty for the work (except to the | |
106 | extent that warranties are provided), that licensees may convey the | |
107 | work under this License, and how to view a copy of this License. If | |
108 | the interface presents a list of user commands or options, such as a | |
109 | menu, a prominent item in the list meets this criterion. | |
110 | ||
111 | 1. Source Code. | |
112 | ||
113 | The "source code" for a work means the preferred form of the work | |
114 | for making modifications to it. "Object code" means any non-source | |
115 | form of a work. | |
116 | ||
117 | A "Standard Interface" means an interface that either is an official | |
118 | standard defined by a recognized standards body, or, in the case of | |
119 | interfaces specified for a particular programming language, one that | |
120 | is widely used among developers working in that language. | |
121 | ||
122 | The "System Libraries" of an executable work include anything, other | |
123 | than the work as a whole, that (a) is included in the normal form of | |
124 | packaging a Major Component, but which is not part of that Major | |
125 | Component, and (b) serves only to enable use of the work with that | |
126 | Major Component, or to implement a Standard Interface for which an | |
127 | implementation is available to the public in source code form. A | |
128 | "Major Component", in this context, means a major essential component | |
129 | (kernel, window system, and so on) of the specific operating system | |
130 | (if any) on which the executable work runs, or a compiler used to | |
131 | produce the work, or an object code interpreter used to run it. | |
132 | ||
133 | The "Corresponding Source" for a work in object code form means all | |
134 | the source code needed to generate, install, and (for an executable | |
135 | work) run the object code and to modify the work, including scripts to | |
136 | control those activities. However, it does not include the work's | |
137 | System Libraries, or general-purpose tools or generally available free | |
138 | programs which are used unmodified in performing those activities but | |
139 | which are not part of the work. For example, Corresponding Source | |
140 | includes interface definition files associated with source files for | |
141 | the work, and the source code for shared libraries and dynamically | |
142 | linked subprograms that the work is specifically designed to require, | |
143 | such as by intimate data communication or control flow between those | |
144 | subprograms and other parts of the work. | |
145 | ||
146 | The Corresponding Source need not include anything that users | |
147 | can regenerate automatically from other parts of the Corresponding | |
148 | Source. | |
149 | ||
150 | The Corresponding Source for a work in source code form is that | |
151 | same work. | |
152 | ||
153 | 2. Basic Permissions. | |
154 | ||
155 | All rights granted under this License are granted for the term of | |
156 | copyright on the Program, and are irrevocable provided the stated | |
157 | conditions are met. This License explicitly affirms your unlimited | |
158 | permission to run the unmodified Program. The output from running a | |
159 | covered work is covered by this License only if the output, given its | |
160 | content, constitutes a covered work. This License acknowledges your | |
161 | rights of fair use or other equivalent, as provided by copyright law. | |
162 | ||
163 | You may make, run and propagate covered works that you do not | |
164 | convey, without conditions so long as your license otherwise remains | |
165 | in force. You may convey covered works to others for the sole purpose | |
166 | of having them make modifications exclusively for you, or provide you | |
167 | with facilities for running those works, provided that you comply with | |
168 | the terms of this License in conveying all material for which you do | |
169 | not control copyright. Those thus making or running the covered works | |
170 | for you must do so exclusively on your behalf, under your direction | |
171 | and control, on terms that prohibit them from making any copies of | |
172 | your copyrighted material outside their relationship with you. | |
173 | ||
174 | Conveying under any other circumstances is permitted solely under | |
175 | the conditions stated below. Sublicensing is not allowed; section 10 | |
176 | makes it unnecessary. | |
177 | ||
178 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. | |
179 | ||
180 | No covered work shall be deemed part of an effective technological | |
181 | measure under any applicable law fulfilling obligations under article | |
182 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or | |
183 | similar laws prohibiting or restricting circumvention of such | |
184 | measures. | |
185 | ||
186 | When you convey a covered work, you waive any legal power to forbid | |
187 | circumvention of technological measures to the extent such circumvention | |
188 | is effected by exercising rights under this License with respect to | |
189 | the covered work, and you disclaim any intention to limit operation or | |
190 | modification of the work as a means of enforcing, against the work's | |
191 | users, your or third parties' legal rights to forbid circumvention of | |
192 | technological measures. | |
193 | ||
194 | 4. Conveying Verbatim Copies. | |
195 | ||
196 | You may convey verbatim copies of the Program's source code as you | |
197 | receive it, in any medium, provided that you conspicuously and | |
198 | appropriately publish on each copy an appropriate copyright notice; | |
199 | keep intact all notices stating that this License and any | |
200 | non-permissive terms added in accord with section 7 apply to the code; | |
201 | keep intact all notices of the absence of any warranty; and give all | |
202 | recipients a copy of this License along with the Program. | |
203 | ||
204 | You may charge any price or no price for each copy that you convey, | |
205 | and you may offer support or warranty protection for a fee. | |
206 | ||
207 | 5. Conveying Modified Source Versions. | |
208 | ||
209 | You may convey a work based on the Program, or the modifications to | |
210 | produce it from the Program, in the form of source code under the | |
211 | terms of section 4, provided that you also meet all of these conditions: | |
212 | ||
213 | a) The work must carry prominent notices stating that you modified | |
214 | it, and giving a relevant date. | |
215 | ||
216 | b) The work must carry prominent notices stating that it is | |
217 | released under this License and any conditions added under section | |
218 | 7. This requirement modifies the requirement in section 4 to | |
219 | "keep intact all notices". | |
220 | ||
221 | c) You must license the entire work, as a whole, under this | |
222 | License to anyone who comes into possession of a copy. This | |
223 | License will therefore apply, along with any applicable section 7 | |
224 | additional terms, to the whole of the work, and all its parts, | |
225 | regardless of how they are packaged. This License gives no | |
226 | permission to license the work in any other way, but it does not | |
227 | invalidate such permission if you have separately received it. | |
228 | ||
229 | d) If the work has interactive user interfaces, each must display | |
230 | Appropriate Legal Notices; however, if the Program has interactive | |
231 | interfaces that do not display Appropriate Legal Notices, your | |
232 | work need not make them do so. | |
233 | ||
234 | A compilation of a covered work with other separate and independent | |
235 | works, which are not by their nature extensions of the covered work, | |
236 | and which are not combined with it such as to form a larger program, | |
237 | in or on a volume of a storage or distribution medium, is called an | |
238 | "aggregate" if the compilation and its resulting copyright are not | |
239 | used to limit the access or legal rights of the compilation's users | |
240 | beyond what the individual works permit. Inclusion of a covered work | |
241 | in an aggregate does not cause this License to apply to the other | |
242 | parts of the aggregate. | |
243 | ||
244 | 6. Conveying Non-Source Forms. | |
245 | ||
246 | You may convey a covered work in object code form under the terms | |
247 | of sections 4 and 5, provided that you also convey the | |
248 | machine-readable Corresponding Source under the terms of this License, | |
249 | in one of these ways: | |
250 | ||
251 | a) Convey the object code in, or embodied in, a physical product | |
252 | (including a physical distribution medium), accompanied by the | |
253 | Corresponding Source fixed on a durable physical medium | |
254 | customarily used for software interchange. | |
255 | ||
256 | b) Convey the object code in, or embodied in, a physical product | |
257 | (including a physical distribution medium), accompanied by a | |
258 | written offer, valid for at least three years and valid for as | |
259 | long as you offer spare parts or customer support for that product | |
260 | model, to give anyone who possesses the object code either (1) a | |
261 | copy of the Corresponding Source for all the software in the | |
262 | product that is covered by this License, on a durable physical | |
263 | medium customarily used for software interchange, for a price no | |
264 | more than your reasonable cost of physically performing this | |
265 | conveying of source, or (2) access to copy the | |
266 | Corresponding Source from a network server at no charge. | |
267 | ||
268 | c) Convey individual copies of the object code with a copy of the | |
269 | written offer to provide the Corresponding Source. This | |
270 | alternative is allowed only occasionally and noncommercially, and | |
271 | only if you received the object code with such an offer, in accord | |
272 | with subsection 6b. | |
273 | ||
274 | d) Convey the object code by offering access from a designated | |
275 | place (gratis or for a charge), and offer equivalent access to the | |
276 | Corresponding Source in the same way through the same place at no | |
277 | further charge. You need not require recipients to copy the | |
278 | Corresponding Source along with the object code. If the place to | |
279 | copy the object code is a network server, the Corresponding Source | |
280 | may be on a different server (operated by you or a third party) | |
281 | that supports equivalent copying facilities, provided you maintain | |
282 | clear directions next to the object code saying where to find the | |
283 | Corresponding Source. Regardless of what server hosts the | |
284 | Corresponding Source, you remain obligated to ensure that it is | |
285 | available for as long as needed to satisfy these requirements. | |
286 | ||
287 | e) Convey the object code using peer-to-peer transmission, provided | |
288 | you inform other peers where the object code and Corresponding | |
289 | Source of the work are being offered to the general public at no | |
290 | charge under subsection 6d. | |
291 | ||
292 | A separable portion of the object code, whose source code is excluded | |
293 | from the Corresponding Source as a System Library, need not be | |
294 | included in conveying the object code work. | |
295 | ||
296 | A "User Product" is either (1) a "consumer product", which means any | |
297 | tangible personal property which is normally used for personal, family, | |
298 | or household purposes, or (2) anything designed or sold for incorporation | |
299 | into a dwelling. In determining whether a product is a consumer product, | |
300 | doubtful cases shall be resolved in favor of coverage. For a particular | |
301 | product received by a particular user, "normally used" refers to a | |
302 | typical or common use of that class of product, regardless of the status | |
303 | of the particular user or of the way in which the particular user | |
304 | actually uses, or expects or is expected to use, the product. A product | |
305 | is a consumer product regardless of whether the product has substantial | |
306 | commercial, industrial or non-consumer uses, unless such uses represent | |
307 | the only significant mode of use of the product. | |
308 | ||
309 | "Installation Information" for a User Product means any methods, | |
310 | procedures, authorization keys, or other information required to install | |
311 | and execute modified versions of a covered work in that User Product from | |
312 | a modified version of its Corresponding Source. The information must | |
313 | suffice to ensure that the continued functioning of the modified object | |
314 | code is in no case prevented or interfered with solely because | |
315 | modification has been made. | |
316 | ||
317 | If you convey an object code work under this section in, or with, or | |
318 | specifically for use in, a User Product, and the conveying occurs as | |
319 | part of a transaction in which the right of possession and use of the | |
320 | User Product is transferred to the recipient in perpetuity or for a | |
321 | fixed term (regardless of how the transaction is characterized), the | |
322 | Corresponding Source conveyed under this section must be accompanied | |
323 | by the Installation Information. But this requirement does not apply | |
324 | if neither you nor any third party retains the ability to install | |
325 | modified object code on the User Product (for example, the work has | |
326 | been installed in ROM). | |
327 | ||
328 | The requirement to provide Installation Information does not include a | |
329 | requirement to continue to provide support service, warranty, or updates | |
330 | for a work that has been modified or installed by the recipient, or for | |
331 | the User Product in which it has been modified or installed. Access to a | |
332 | network may be denied when the modification itself materially and | |
333 | adversely affects the operation of the network or violates the rules and | |
334 | protocols for communication across the network. | |
335 | ||
336 | Corresponding Source conveyed, and Installation Information provided, | |
337 | in accord with this section must be in a format that is publicly | |
338 | documented (and with an implementation available to the public in | |
339 | source code form), and must require no special password or key for | |
340 | unpacking, reading or copying. | |
341 | ||
342 | 7. Additional Terms. | |
343 | ||
344 | "Additional permissions" are terms that supplement the terms of this | |
345 | License by making exceptions from one or more of its conditions. | |
346 | Additional permissions that are applicable to the entire Program shall | |
347 | be treated as though they were included in this License, to the extent | |
348 | that they are valid under applicable law. If additional permissions | |
349 | apply only to part of the Program, that part may be used separately | |
350 | under those permissions, but the entire Program remains governed by | |
351 | this License without regard to the additional permissions. | |
352 | ||
353 | When you convey a copy of a covered work, you may at your option | |
354 | remove any additional permissions from that copy, or from any part of | |
355 | it. (Additional permissions may be written to require their own | |
356 | removal in certain cases when you modify the work.) You may place | |
357 | additional permissions on material, added by you to a covered work, | |
358 | for which you have or can give appropriate copyright permission. | |
359 | ||
360 | Notwithstanding any other provision of this License, for material you | |
361 | add to a covered work, you may (if authorized by the copyright holders of | |
362 | that material) supplement the terms of this License with terms: | |
363 | ||
364 | a) Disclaiming warranty or limiting liability differently from the | |
365 | terms of sections 15 and 16 of this License; or | |
366 | ||
367 | b) Requiring preservation of specified reasonable legal notices or | |
368 | author attributions in that material or in the Appropriate Legal | |
369 | Notices displayed by works containing it; or | |
370 | ||
371 | c) Prohibiting misrepresentation of the origin of that material, or | |
372 | requiring that modified versions of such material be marked in | |
373 | reasonable ways as different from the original version; or | |
374 | ||
375 | d) Limiting the use for publicity purposes of names of licensors or | |
376 | authors of the material; or | |
377 | ||
378 | e) Declining to grant rights under trademark law for use of some | |
379 | trade names, trademarks, or service marks; or | |
380 | ||
381 | f) Requiring indemnification of licensors and authors of that | |
382 | material by anyone who conveys the material (or modified versions of | |
383 | it) with contractual assumptions of liability to the recipient, for | |
384 | any liability that these contractual assumptions directly impose on | |
385 | those licensors and authors. | |
386 | ||
387 | All other non-permissive additional terms are considered "further | |
388 | restrictions" within the meaning of section 10. If the Program as you | |
389 | received it, or any part of it, contains a notice stating that it is | |
390 | governed by this License along with a term that is a further | |
391 | restriction, you may remove that term. If a license document contains | |
392 | a further restriction but permits relicensing or conveying under this | |
393 | License, you may add to a covered work material governed by the terms | |
394 | of that license document, provided that the further restriction does | |
395 | not survive such relicensing or conveying. | |
396 | ||
397 | If you add terms to a covered work in accord with this section, you | |
398 | must place, in the relevant source files, a statement of the | |
399 | additional terms that apply to those files, or a notice indicating | |
400 | where to find the applicable terms. | |
401 | ||
402 | Additional terms, permissive or non-permissive, may be stated in the | |
403 | form of a separately written license, or stated as exceptions; | |
404 | the above requirements apply either way. | |
405 | ||
406 | 8. Termination. | |
407 | ||
408 | You may not propagate or modify a covered work except as expressly | |
409 | provided under this License. Any attempt otherwise to propagate or | |
410 | modify it is void, and will automatically terminate your rights under | |
411 | this License (including any patent licenses granted under the third | |
412 | paragraph of section 11). | |
413 | ||
414 | However, if you cease all violation of this License, then your | |
415 | license from a particular copyright holder is reinstated (a) | |
416 | provisionally, unless and until the copyright holder explicitly and | |
417 | finally terminates your license, and (b) permanently, if the copyright | |
418 | holder fails to notify you of the violation by some reasonable means | |
419 | prior to 60 days after the cessation. | |
420 | ||
421 | Moreover, your license from a particular copyright holder is | |
422 | reinstated permanently if the copyright holder notifies you of the | |
423 | violation by some reasonable means, this is the first time you have | |
424 | received notice of violation of this License (for any work) from that | |
425 | copyright holder, and you cure the violation prior to 30 days after | |
426 | your receipt of the notice. | |
427 | ||
428 | Termination of your rights under this section does not terminate the | |
429 | licenses of parties who have received copies or rights from you under | |
430 | this License. If your rights have been terminated and not permanently | |
431 | reinstated, you do not qualify to receive new licenses for the same | |
432 | material under section 10. | |
433 | ||
434 | 9. Acceptance Not Required for Having Copies. | |
435 | ||
436 | You are not required to accept this License in order to receive or | |
437 | run a copy of the Program. Ancillary propagation of a covered work | |
438 | occurring solely as a consequence of using peer-to-peer transmission | |
439 | to receive a copy likewise does not require acceptance. However, | |
440 | nothing other than this License grants you permission to propagate or | |
441 | modify any covered work. These actions infringe copyright if you do | |
442 | not accept this License. Therefore, by modifying or propagating a | |
443 | covered work, you indicate your acceptance of this License to do so. | |
444 | ||
445 | 10. Automatic Licensing of Downstream Recipients. | |
446 | ||
447 | Each time you convey a covered work, the recipient automatically | |
448 | receives a license from the original licensors, to run, modify and | |
449 | propagate that work, subject to this License. You are not responsible | |
450 | for enforcing compliance by third parties with this License. | |
451 | ||
452 | An "entity transaction" is a transaction transferring control of an | |
453 | organization, or substantially all assets of one, or subdividing an | |
454 | organization, or merging organizations. If propagation of a covered | |
455 | work results from an entity transaction, each party to that | |
456 | transaction who receives a copy of the work also receives whatever | |
457 | licenses to the work the party's predecessor in interest had or could | |
458 | give under the previous paragraph, plus a right to possession of the | |
459 | Corresponding Source of the work from the predecessor in interest, if | |
460 | the predecessor has it or can get it with reasonable efforts. | |
461 | ||
462 | You may not impose any further restrictions on the exercise of the | |
463 | rights granted or affirmed under this License. For example, you may | |
464 | not impose a license fee, royalty, or other charge for exercise of | |
465 | rights granted under this License, and you may not initiate litigation | |
466 | (including a cross-claim or counterclaim in a lawsuit) alleging that | |
467 | any patent claim is infringed by making, using, selling, offering for | |
468 | sale, or importing the Program or any portion of it. | |
469 | ||
470 | 11. Patents. | |
471 | ||
472 | A "contributor" is a copyright holder who authorizes use under this | |
473 | License of the Program or a work on which the Program is based. The | |
474 | work thus licensed is called the contributor's "contributor version". | |
475 | ||
476 | A contributor's "essential patent claims" are all patent claims | |
477 | owned or controlled by the contributor, whether already acquired or | |
478 | hereafter acquired, that would be infringed by some manner, permitted | |
479 | by this License, of making, using, or selling its contributor version, | |
480 | but do not include claims that would be infringed only as a | |
481 | consequence of further modification of the contributor version. For | |
482 | purposes of this definition, "control" includes the right to grant | |
483 | patent sublicenses in a manner consistent with the requirements of | |
484 | this License. | |
485 | ||
486 | Each contributor grants you a non-exclusive, worldwide, royalty-free | |
487 | patent license under the contributor's essential patent claims, to | |
488 | make, use, sell, offer for sale, import and otherwise run, modify and | |
489 | propagate the contents of its contributor version. | |
490 | ||
491 | In the following three paragraphs, a "patent license" is any express | |
492 | agreement or commitment, however denominated, not to enforce a patent | |
493 | (such as an express permission to practice a patent or covenant not to | |
494 | sue for patent infringement). To "grant" such a patent license to a | |
495 | party means to make such an agreement or commitment not to enforce a | |
496 | patent against the party. | |
497 | ||
498 | If you convey a covered work, knowingly relying on a patent license, | |
499 | and the Corresponding Source of the work is not available for anyone | |
500 | to copy, free of charge and under the terms of this License, through a | |
501 | publicly available network server or other readily accessible means, | |
502 | then you must either (1) cause the Corresponding Source to be so | |
503 | available, or (2) arrange to deprive yourself of the benefit of the | |
504 | patent license for this particular work, or (3) arrange, in a manner | |
505 | consistent with the requirements of this License, to extend the patent | |
506 | license to downstream recipients. "Knowingly relying" means you have | |
507 | actual knowledge that, but for the patent license, your conveying the | |
508 | covered work in a country, or your recipient's use of the covered work | |
509 | in a country, would infringe one or more identifiable patents in that | |
510 | country that you have reason to believe are valid. | |
511 | ||
512 | If, pursuant to or in connection with a single transaction or | |
513 | arrangement, you convey, or propagate by procuring conveyance of, a | |
514 | covered work, and grant a patent license to some of the parties | |
515 | receiving the covered work authorizing them to use, propagate, modify | |
516 | or convey a specific copy of the covered work, then the patent license | |
517 | you grant is automatically extended to all recipients of the covered | |
518 | work and works based on it. | |
519 | ||
520 | A patent license is "discriminatory" if it does not include within | |
521 | the scope of its coverage, prohibits the exercise of, or is | |
522 | conditioned on the non-exercise of one or more of the rights that are | |
523 | specifically granted under this License. You may not convey a covered | |
524 | work if you are a party to an arrangement with a third party that is | |
525 | in the business of distributing software, under which you make payment | |
526 | to the third party based on the extent of your activity of conveying | |
527 | the work, and under which the third party grants, to any of the | |
528 | parties who would receive the covered work from you, a discriminatory | |
529 | patent license (a) in connection with copies of the covered work | |
530 | conveyed by you (or copies made from those copies), or (b) primarily | |
531 | for and in connection with specific products or compilations that | |
532 | contain the covered work, unless you entered into that arrangement, | |
533 | or that patent license was granted, prior to 28 March 2007. | |
534 | ||
535 | Nothing in this License shall be construed as excluding or limiting | |
536 | any implied license or other defenses to infringement that may | |
537 | otherwise be available to you under applicable patent law. | |
538 | ||
539 | 12. No Surrender of Others' Freedom. | |
540 | ||
541 | If conditions are imposed on you (whether by court order, agreement or | |
542 | otherwise) that contradict the conditions of this License, they do not | |
543 | excuse you from the conditions of this License. If you cannot convey a | |
544 | covered work so as to satisfy simultaneously your obligations under this | |
545 | License and any other pertinent obligations, then as a consequence you may | |
546 | not convey it at all. For example, if you agree to terms that obligate you | |
547 | to collect a royalty for further conveying from those to whom you convey | |
548 | the Program, the only way you could satisfy both those terms and this | |
549 | License would be to refrain entirely from conveying the Program. | |
550 | ||
551 | 13. Use with the GNU Affero General Public License. | |
552 | ||
553 | Notwithstanding any other provision of this License, you have | |
554 | permission to link or combine any covered work with a work licensed | |
555 | under version 3 of the GNU Affero General Public License into a single | |
556 | combined work, and to convey the resulting work. The terms of this | |
557 | License will continue to apply to the part which is the covered work, | |
558 | but the special requirements of the GNU Affero General Public License, | |
559 | section 13, concerning interaction through a network will apply to the | |
560 | combination as such. | |
561 | ||
562 | 14. Revised Versions of this License. | |
563 | ||
564 | The Free Software Foundation may publish revised and/or new versions of | |
565 | the GNU General Public License from time to time. Such new versions will | |
566 | be similar in spirit to the present version, but may differ in detail to | |
567 | address new problems or concerns. | |
568 | ||
569 | Each version is given a distinguishing version number. If the | |
570 | Program specifies that a certain numbered version of the GNU General | |
571 | Public License "or any later version" applies to it, you have the | |
572 | option of following the terms and conditions either of that numbered | |
573 | version or of any later version published by the Free Software | |
574 | Foundation. If the Program does not specify a version number of the | |
575 | GNU General Public License, you may choose any version ever published | |
576 | by the Free Software Foundation. | |
577 | ||
578 | If the Program specifies that a proxy can decide which future | |
579 | versions of the GNU General Public License can be used, that proxy's | |
580 | public statement of acceptance of a version permanently authorizes you | |
581 | to choose that version for the Program. | |
582 | ||
583 | Later license versions may give you additional or different | |
584 | permissions. However, no additional obligations are imposed on any | |
585 | author or copyright holder as a result of your choosing to follow a | |
586 | later version. | |
587 | ||
588 | 15. Disclaimer of Warranty. | |
589 | ||
590 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY | |
591 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT | |
592 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY | |
593 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, | |
594 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
595 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM | |
596 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF | |
597 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. | |
598 | ||
599 | 16. Limitation of Liability. | |
600 | ||
601 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |
602 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS | |
603 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY | |
604 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE | |
605 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF | |
606 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD | |
607 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), | |
608 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF | |
609 | SUCH DAMAGES. | |
610 | ||
611 | 17. Interpretation of Sections 15 and 16. | |
612 | ||
613 | If the disclaimer of warranty and limitation of liability provided | |
614 | above cannot be given local legal effect according to their terms, | |
615 | reviewing courts shall apply local law that most closely approximates | |
616 | an absolute waiver of all civil liability in connection with the | |
617 | Program, unless a warranty or assumption of liability accompanies a | |
618 | copy of the Program in return for a fee. | |
619 | ||
620 | END OF TERMS AND CONDITIONS | |
621 | ||
622 | How to Apply These Terms to Your New Programs | |
623 | ||
624 | If you develop a new program, and you want it to be of the greatest | |
625 | possible use to the public, the best way to achieve this is to make it | |
626 | free software which everyone can redistribute and change under these terms. | |
627 | ||
628 | To do so, attach the following notices to the program. It is safest | |
629 | to attach them to the start of each source file to most effectively | |
630 | state the exclusion of warranty; and each file should have at least | |
631 | the "copyright" line and a pointer to where the full notice is found. | |
632 | ||
633 | <one line to give the program's name and a brief idea of what it does.> | |
634 | Copyright (C) <year> <name of author> | |
635 | ||
636 | This program is free software: you can redistribute it and/or modify | |
637 | it under the terms of the GNU General Public License as published by | |
638 | the Free Software Foundation, either version 3 of the License, or | |
639 | (at your option) any later version. | |
640 | ||
641 | This program is distributed in the hope that it will be useful, | |
642 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
643 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
644 | GNU General Public License for more details. | |
645 | ||
646 | You should have received a copy of the GNU General Public License | |
647 | along with this program. If not, see <http://www.gnu.org/licenses/>. | |
648 | ||
649 | Also add information on how to contact you by electronic and paper mail. | |
650 | ||
651 | If the program does terminal interaction, make it output a short | |
652 | notice like this when it starts in an interactive mode: | |
653 | ||
654 | <program> Copyright (C) <year> <name of author> | |
655 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |
656 | This is free software, and you are welcome to redistribute it | |
657 | under certain conditions; type `show c' for details. | |
658 | ||
659 | The hypothetical commands `show w' and `show c' should show the appropriate | |
660 | parts of the General Public License. Of course, your program's commands | |
661 | might be different; for a GUI interface, you would use an "about box". | |
662 | ||
663 | You should also get your employer (if you work as a programmer) or school, | |
664 | if any, to sign a "copyright disclaimer" for the program, if necessary. | |
665 | For more information on this, and how to apply and follow the GNU GPL, see | |
666 | <http://www.gnu.org/licenses/>. | |
667 | ||
668 | The GNU General Public License does not permit incorporating your program | |
669 | into proprietary programs. If your program is a subroutine library, you | |
670 | may consider it more useful to permit linking proprietary applications with | |
671 | the library. If this is what you want to do, use the GNU Lesser General | |
672 | Public License instead of this License. But first, please read | |
673 | <http://www.gnu.org/philosophy/why-not-lgpl.html>. |
0 | # The language we are building. | |
1 | # For example, Run "make LANG=es" to build the Spanish edition. | |
2 | LANG := en | |
3 | ||
4 | .PHONY: target clean sync push | |
5 | ||
6 | target: book book/default.css book.html book.pdf | |
7 | ||
8 | # The book consists of these text files in the following order: | |
9 | ||
10 | TXTFILES := preface.txt intro.txt basic.txt clone.txt branch.txt history.txt \ | |
11 | multiplayer.txt grandmaster.txt secrets.txt drawbacks.txt translate.txt | |
12 | ||
13 | book.xml: $(addprefix $(LANG)/,$(TXTFILES)) | |
14 | # Kludge to make preface sections work for languages besides English. | |
15 | echo '[specialsections]' > conf | |
16 | sed -n '/^== .* ==$$/p' $(LANG)/preface.txt | sed 's/^== \(.*\) ==$$/^\1$$=sect-preface/' >> conf | |
17 | # Concatenate the text files and feed to AsciiDoc. | |
18 | # If a file has not yet been translated for the target language, | |
19 | # then substitute the English version. | |
20 | ( for FILE in $^ ; do if [ -f $$FILE ]; then cat $$FILE; else \ | |
21 | cat en/$$(basename $$FILE); fi; echo ; done ) | \ | |
22 | asciidoc -a lang=$(LANG) -d book -b docbook -f conf - > $@ | |
23 | ||
24 | # This rule allows unfinished translations to build. | |
25 | # Report an error if the English version of the text file is missing. | |
26 | $(addprefix $(LANG)/,$(TXTFILES)) : | |
27 | ifeq ($(LANG),en) | |
28 | @if [ ! -f $@ ]; then echo English file missing: $@; exit 123; fi | |
29 | else | |
30 | @if [ ! -f $@ ]; then echo $@ missing: using English version; fi | |
31 | endif | |
32 | ||
33 | # Ignore tidy's exit code because Asciidoc generates section IDs beginning with | |
34 | # "_", which xmlto converts to "id" attributes of <a> tags. The standard | |
35 | # insists that "id" attributes begin with a letter, which causes tidy to | |
36 | # print a warning and return a nonzero code. | |
37 | # | |
38 | # When Asciidoc 8.3.0+ is widespread, I'll use its idprefix attribute instead | |
39 | # of ignoring return codes. | |
40 | ||
41 | book: book.xml | |
42 | xmlto -m custom-html.xsl -o book html book.xml | |
43 | sed -i 's/xmlns:fo[^ ]*//g' book/*.html | |
44 | -ls book/*.html | xargs -n 1 tidy -utf8 -m -i -q | |
45 | ./makeover | |
46 | ||
47 | book/default.css: book.css | |
48 | -mkdir book | |
49 | rsync book.css book/default.css | |
50 | ||
51 | book.html: book.xml | |
52 | xmlto -m custom-nochunks.xsl html-nochunks $^ | |
53 | -tidy -utf8 -imq $@ | |
54 | ||
55 | # Set SP_ENCODING to avoid "non SGML character" errors. | |
56 | # Can also do SP_ENCODING="UTF-8". | |
57 | book.pdf: book.xml | |
58 | SP_ENCODING="XML" docbook2pdf book.xml | |
59 | ||
60 | clean: | |
61 | -rm -rf book.xml book.html book | |
62 | ||
63 | sync: target | |
64 | rsync -r book.html book.pdf book/* blynn@tl1.stanford.edu:www/gitmagic/intl/$(LANG)/ | |
65 | ||
66 | public: | |
67 | git push blynn@git.or.cz:srv/git/gitmagic.git | |
68 | git push git@github.com:blynn/gitmagic.git | |
69 | git push git@gitorious.org:gitmagic/mainline.git |
0 | body { | |
1 | font-size: 90%; | |
2 | font-family: verdana, arial, sans-serif; | |
3 | } | |
4 | ||
5 | tt, code, pre, .type { | |
6 | font-family: andale mono, courier new, courier, monospace; | |
7 | font-size: 90%; | |
8 | } | |
9 | ||
10 | pre { | |
11 | color: #0000aa; | |
12 | } | |
13 | ||
14 | ul li p { | |
15 | margin-bottom:0; | |
16 | } | |
17 | ||
18 | /* Based on http://phrogz.net/CSS/columns3.html */ | |
19 | div.toc { | |
20 | float: left; | |
21 | margin: 0; | |
22 | padding: 0; | |
23 | padding-top: 0.5em; | |
24 | border: 0; | |
25 | width: 16em; | |
26 | ||
27 | background-color: #f9f9f9; | |
28 | margin-right:1em; | |
29 | } | |
30 | ||
31 | div.content { | |
32 | margin: 0; | |
33 | padding: 0; | |
34 | ||
35 | /* won't match if font is smaller in toc */ | |
36 | border-left: 16em solid #f9f9f9; | |
37 | padding-left: 1em; | |
38 | } | |
39 | ||
40 | div.content:after { | |
41 | content:' '; | |
42 | clear:both; | |
43 | display:block; | |
44 | height:0; | |
45 | overflow:hidden | |
46 | } | |
47 | ||
48 | div.footer { | |
49 | clear:left; | |
50 | padding: 0.5em; | |
51 | /* background-color: #f9f9f9; | |
52 | border: 1px solid #aaaaaa; */ | |
53 | font-size: 80%; | |
54 | margin: 0; | |
55 | } | |
56 | ||
57 | div.toc ul { | |
58 | list-style: none; | |
59 | padding: 0; | |
60 | margin: 0; | |
61 | } | |
62 | ||
63 | div.toc li ul a, li ul span.currentlink | |
64 | { | |
65 | font-weight: normal; | |
66 | font-size: 90%; | |
67 | padding-left: 2em; | |
68 | } | |
69 | ||
70 | div.toc a, span.currentlink{ | |
71 | display:block; | |
72 | text-decoration: none; | |
73 | padding-left: 0.5em; | |
74 | color: #0000aa; | |
75 | } | |
76 | ||
77 | span.currentlink { | |
78 | text-decoration: none; | |
79 | background-color: #aaaaf9; | |
80 | } | |
81 | ||
82 | div.toc a:visited { | |
83 | color: #0000aa; | |
84 | } | |
85 | ||
86 | div.toc a:hover { | |
87 | background-color: #f9f9aa; | |
88 | } | |
89 | ||
90 | .programlisting, .screen { | |
91 | margin: 0; | |
92 | border: 1px solid #aaaaaa; | |
93 | background-color: #f9f9f9; | |
94 | padding: 0.17em; | |
95 | margin: 1em; | |
96 | margin-right: 3em; | |
97 | } | |
98 | ||
99 | .parameter { | |
100 | font-style: italic; | |
101 | } | |
102 | ||
103 | h1, h2 { | |
104 | padding-top: 0.5em; | |
105 | padding-bottom: 0.17em; | |
106 | margin: 0; | |
107 | font-weight: normal; | |
108 | color: black; | |
109 | border-bottom: 1px solid #aaaaaa; | |
110 | } | |
111 | ||
112 | h1 { | |
113 | font-size: 188%; | |
114 | } | |
115 | ||
116 | div.chapter h2 { | |
117 | font-size: 188%; | |
118 | } | |
119 | ||
120 | div.section h2 { | |
121 | font-size: 150%; | |
122 | } |
0 | <?xml version='1.0'?> | |
1 | <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
2 | xmlns:fo="http://www.w3.org/1999/XSL/Format" | |
3 | version="1.0"> | |
4 | <xsl:param name="chunk.section.depth" select="0"></xsl:param> | |
5 | <xsl:param name="css.decoration" select="0"></xsl:param> | |
6 | <xsl:param name="toc.list.type">ul</xsl:param> | |
7 | <xsl:param name="chunker.output.encoding" select="'UTF-8'"></xsl:param> | |
8 | <xsl:param name="chunker.output.doctype-public" select="'-//W3C//DTD HTML 4.01 Transitional//EN'"></xsl:param> | |
9 | <!-- use tidy instead | |
10 | <xsl:param name="chunker.output.indent" select="'yes'"></xsl:param> | |
11 | --> | |
12 | <xsl:param name="suppress.navigation" select="1"></xsl:param> | |
13 | <xsl:param name="generate.toc" select="'book toc'"/> | |
14 | <xsl:param name="html.stylesheet" select="'default.css'"/> | |
15 | ||
16 | <xsl:template name="user.footer.navigation"> | |
17 | <script type="text/javascript" src="find_selflink.js"></script> | |
18 | <script type="text/javascript"> | |
19 | var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); | |
20 | document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); | |
21 | </script> | |
22 | <script type="text/javascript"> | |
23 | var pageTracker = _gat._getTracker("UA-1901330-2"); | |
24 | pageTracker._initData(); | |
25 | pageTracker._trackPageview(); | |
26 | </script> | |
27 | </xsl:template> | |
28 | ||
29 | </xsl:stylesheet> |
0 | <?xml version='1.0'?> | |
1 | <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
2 | xmlns:fo="http://www.w3.org/1999/XSL/Format" | |
3 | version="1.0"> | |
4 | <xsl:output method="html" encoding="UTF-8" indent="no" | |
5 | doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN" | |
6 | /> | |
7 | </xsl:stylesheet> |
0 | == Basic Tricks == | |
1 | ||
2 | Rather than diving into a sea of Git commands, use these elementary examples to | |
3 | get your feet wet. Despite their simplicity, each of them are useful. | |
4 | Indeed, in my first months with Git I never ventured beyond the material in this chapter. | |
5 | ||
6 | === Saving State === | |
7 | ||
8 | About to attempt something drastic? Before you do, take a snapshot of all files | |
9 | in the current directory with: | |
10 | ||
11 | $ git init | |
12 | $ git add . | |
13 | $ git commit -m "My first backup" | |
14 | ||
15 | Now if your new edits go awry, run: | |
16 | ||
17 | $ git reset --hard | |
18 | ||
19 | to go back to where you were. To save the state again: | |
20 | ||
21 | $ git commit -a -m "Another backup" | |
22 | ||
23 | ==== Add, Delete, Rename ==== | |
24 | ||
25 | The above will only keep track of the files that were present when you first ran *git add*. If you add new files or subdirectories, you'll have to tell Git: | |
26 | ||
27 | $ git add NEWFILES... | |
28 | ||
29 | Similarly, if you want Git to forget about certain files, maybe because you've deleted them: | |
30 | ||
31 | $ git rm OLDFILES... | |
32 | ||
33 | Renaming a file is the same as removing the old name and adding the new name. There's also the shortcut *git mv* which has the same syntax as the *mv* command. For example: | |
34 | ||
35 | $ git mv OLDFILE NEWFILE | |
36 | ||
37 | === Advanced Undo/Redo === | |
38 | ||
39 | Sometimes you just want to go back and forget about every change past a certain point because they're all wrong. Then: | |
40 | ||
41 | $ git log | |
42 | ||
43 | shows you a list of recent commits, and their SHA1 hashes. Next, type: | |
44 | ||
45 | $ git reset --hard SHA1_HASH | |
46 | ||
47 | to restore the state to a given commit and erase all newer commits from the record permanently. | |
48 | ||
49 | Other times you want to hop to an old state briefly. In this case, type: | |
50 | ||
51 | $ git checkout SHA1_HASH | |
52 | ||
53 | This takes you back in time, while preserving newer commits. However, like time travel in a science-fiction movie, if you now edit and commit, you will be in an alternate reality, because your actions are different to what they were the first time around. | |
54 | ||
55 | This alternate reality is called a 'branch', and <<branch,we'll have more to say about this later>>. For now, just remember that | |
56 | ||
57 | $ git checkout master | |
58 | ||
59 | will take you back to the present. Also, to stop Git complaining, always | |
60 | commit or reset your changes before running checkout. | |
61 | ||
62 | To take the computer game analogy again: | |
63 | ||
64 | - *`git reset --hard`*: load an old save and delete all saved games newer than the one just loaded. | |
65 | ||
66 | - *`git checkout`*: load an old game, but if you play on, the game state will deviate from the newer saves you made the first time around. Any saved games you make now will end up in a separate branch representing the alternate reality you have entered. <<branch,We deal with this later>>. | |
67 | ||
68 | You can choose only to restore particular files and subdirectories by appending them after the command: | |
69 | ||
70 | $ git checkout SHA1_HASH some.file another.file | |
71 | ||
72 | Take care, as this form of *checkout* can silently overwrite files. To | |
73 | prevent accidents, commit before running any checkout command, especially when | |
74 | first learning Git. In general, whenever you feel unsure about any operation, Git command or not, first run *git commit -a*. | |
75 | ||
76 | Don't like cutting and pasting hashes? Then use: | |
77 | ||
78 | $ git checkout :/"My first b" | |
79 | ||
80 | to jump to the commit that starts with a given message. | |
81 | You can also ask for the 5th-last saved state: | |
82 | ||
83 | $ git checkout master~5 | |
84 | ||
85 | ==== Reverting ==== | |
86 | ||
87 | In a court of law, events can be stricken from the record. Likewise, you can pick specific commits to undo. | |
88 | ||
89 | $ git commit -a | |
90 | $ git revert SHA1_HASH | |
91 | ||
92 | will undo just the commit with the given hash. Running *git log* reveals the revert is recorded as a new commit. | |
93 | ||
94 | === Changelog Generation === | |
95 | ||
96 | Some projects require a http://en.wikipedia.org/wiki/Changelog[changelog]. | |
97 | Generate one by typing: | |
98 | ||
99 | $ git log > ChangeLog | |
100 | ||
101 | === Downloading Files === | |
102 | ||
103 | Get a copy of a project managed with Git by typing: | |
104 | ||
105 | $ git clone git://server/path/to/files | |
106 | ||
107 | For example, to get all the files I used to create this site: | |
108 | ||
109 | $ git clone git://git.or.cz/gitmagic.git | |
110 | ||
111 | We'll have much to say about the *clone* command soon. | |
112 | ||
113 | === The Bleeding Edge === | |
114 | ||
115 | If you've already downloaded a copy of a project using *git clone*, you can upgrade to the latest version with: | |
116 | ||
117 | $ git pull | |
118 | ||
119 | === Instant Publishing === | |
120 | ||
121 | Suppose you've written a script you'd like to share with others. You could just tell them to download from your computer, but if they do so while you're improving the script or making experimental changes, they could wind up in trouble. Of course, this is why release cycles exist. Developers may work on a project frequently, but they only make the code available when they feel it is presentable. | |
122 | ||
123 | To do this with Git, in the directory where your script resides: | |
124 | ||
125 | $ git init | |
126 | $ git add . | |
127 | $ git commit -m "First release" | |
128 | ||
129 | Then tell your users to run: | |
130 | ||
131 | $ git clone your.computer:/path/to/script | |
132 | ||
133 | to download your script. This assumes they have ssh access. If not, run *git daemon* and tell your users to instead run: | |
134 | ||
135 | $ git clone git://your.computer/path/to/script | |
136 | ||
137 | From now on, every time your script is ready for release, execute: | |
138 | ||
139 | $ git commit -a -m "Next release" | |
140 | ||
141 | and your users can upgrade their version by changing to the directory containing your script and typing: | |
142 | ||
143 | $ git pull | |
144 | ||
145 | Your users will never end up with a version of your script you don't want them to see. Obviously this trick works for anything, not just scripts. | |
146 | ||
147 | === What Have I Done? === | |
148 | ||
149 | Find out what changes you've made since the last commit with: | |
150 | ||
151 | $ git diff | |
152 | ||
153 | Or since yesterday: | |
154 | ||
155 | $ git diff "@{yesterday}" | |
156 | ||
157 | Or between a particular version and 2 versions ago: | |
158 | ||
159 | $ git diff SHA1_HASH "master~2" | |
160 | ||
161 | In each case the output is a patch that can be applied with *git apply*. | |
162 | Try also: | |
163 | ||
164 | $ git whatchanged --since="2 weeks ago" | |
165 | ||
166 | Often I'll browse history with http://sourceforge.net/projects/qgit[qgit] | |
167 | instead, due to its slick photogenic interface, or | |
168 | http://jonas.nitro.dk/tig/[tig], a text-mode interface that works well over | |
169 | slow connections. Alternatively, install a web server, run *git instaweb* and | |
170 | fire up any web browser. | |
171 | ||
172 | === Exercise === | |
173 | ||
174 | Let A, B, C, D be four successive commits where B is the same as A except some files have been removed. We want to add the files back at D and not at B. How can we do this? | |
175 | ||
176 | There are at least three solutions. Assuming we are at D: | |
177 | ||
178 | 1. The difference between A and B are the removed files. We can create a patch representing this difference and apply it: | |
179 | ||
180 | $ git diff B A | git apply | |
181 | ||
182 | 2. Since we saved the files back at A, we can retrieve them: | |
183 | ||
184 | $ git checkout A FILES... | |
185 | ||
186 | 3. We can view going from A to B as a change we want to undo: | |
187 | ||
188 | $ git revert B | |
189 | ||
190 | Which choice is best? Whichever you prefer most. It is easy to get what you want with Git, and often there are many ways to get it. |
0 | == Branch Wizardry == | |
1 | ||
2 | Instant branching and merging are the most lethal of Git's killer features. | |
3 | ||
4 | *Problem*: External factors inevitably necessitate context switching. A severe | |
5 | bug manifests in the released version without warning. The deadline for a | |
6 | certain feature is moved closer. A developer whose help you need for a key section of the project is about to leave. In all cases, you must abruptly drop what you are doing and focus on a completely different task. | |
7 | ||
8 | Interrupting your train of thought can be detrimental to your productivity, and the more cumbersome it is to switch contexts, the greater the loss. With centralized version control we must download a fresh working copy from the central server. Distributed systems fare better, as we can clone the desired version locally. | |
9 | ||
10 | But cloning still entails copying the whole working directory as well as the entire history up to the given point. Even though Git reduces the cost of this with file sharing and hard links, the project files themselves must be recreated in their entirety in the new working directory. | |
11 | ||
12 | *Solution*: Git has a better tool for these situations that is much faster and more space-efficient than cloning: *git branch*. | |
13 | ||
14 | With this magic word, the files in your directory suddenly shapeshift from one version to another. This transformation can do more than merely go back or forward in history. Your files can morph from the last release to the experimental version to the current development version to your friend's version and so on. | |
15 | ||
16 | === The Boss Key === | |
17 | ||
18 | Ever play one of those games where at the push of a button ("the boss key"), the screen would instantly display a spreadsheet or something? So if the boss walked in the office while you were playing the game you could quickly hide it away? | |
19 | ||
20 | In some directory: | |
21 | ||
22 | $ echo "I'm smarter than my boss" > myfile.txt | |
23 | $ git init | |
24 | $ git add . | |
25 | $ git commit -m "Initial commit" | |
26 | ||
27 | We have created a Git repository that tracks one text file containing a certain message. Now type: | |
28 | ||
29 | $ git checkout -b boss # nothing seems to change after this | |
30 | $ echo "My boss is smarter than me" > myfile.txt | |
31 | $ git commit -a -m "Another commit" | |
32 | ||
33 | It looks like we've just overwritten our file and committed it. But it's an illusion. Type: | |
34 | ||
35 | $ git checkout master # switch to original version of the file | |
36 | ||
37 | and hey presto! The text file is restored. And if the boss decides to snoop around this directory, type: | |
38 | ||
39 | $ git checkout boss # switch to version suitable for boss' eyes | |
40 | ||
41 | You can switch between the two versions of the file as much as you like, and commit to each independently. | |
42 | ||
43 | === Dirty Work === | |
44 | ||
45 | [[branch]] | |
46 | Say you're working on some feature, and for some reason, you need to go back to an old version and temporarily put in a few prints statements to see how something works. Then: | |
47 | ||
48 | $ git commit -a | |
49 | $ git checkout SHA1_HASH | |
50 | ||
51 | Now you can add ugly temporary code all over the place. You can even commit these changes. When you're done, | |
52 | ||
53 | $ git checkout master | |
54 | ||
55 | to return to your original work. Observe that any uncommitted changes are carried over. | |
56 | ||
57 | What if you wanted to save the temporary changes after all? Easy: | |
58 | ||
59 | $ git checkout -b dirty | |
60 | ||
61 | and commit before switching back to the master branch. Whenever you want to return to the dirty changes, simply type | |
62 | ||
63 | $ git checkout dirty | |
64 | ||
65 | We touched upon this command in an earlier chapter, when discussing loading old states. At last we can tell the whole story: the files change to the requested state, but we must leave the master branch. Any commits made from now on take your files down a different road, which can be named later. | |
66 | ||
67 | In other words, after checking out an old state, Git automatically puts you in a new, unnamed branch, which can be named and saved with *git checkout -b*. | |
68 | ||
69 | === Quick Fixes === | |
70 | ||
71 | You're in the middle of something when you are told to drop everything and fix a newly discovered bug: | |
72 | ||
73 | $ git commit -a | |
74 | $ git checkout -b fixes SHA1_HASH | |
75 | ||
76 | Then once you've fixed the bug: | |
77 | ||
78 | $ git commit -a -m "Bug fixed" | |
79 | $ git push # to the central repository | |
80 | $ git checkout master | |
81 | ||
82 | and resume work on your original task. | |
83 | ||
84 | === Uninterrupted Workflow === | |
85 | ||
86 | Some projects require your code to be reviewed before you may submit it. To make life easier for those reviewing your code, if you have a big change to make you might break it into two or more parts, and get each part separately reviewed. | |
87 | ||
88 | What if the second part cannot be written until the first part is approved and checked in? In many version control systems, you'd have to send the first part to the reviewers, and then wait until it has been approved before starting on the second part. | |
89 | ||
90 | Actually that's not quite true, but in these systems editing Part II before submitting Part I involves suffering and hardship. In Git, branching and merging are painless (a technical term for fast and local). So after you've committed the first part and sent it for review: | |
91 | ||
92 | $ git checkout -b part2 | |
93 | ||
94 | Next, code the second part of the big change without waiting for the first part to be accepted. When the first part is approved and submitted, | |
95 | ||
96 | $ git checkout master | |
97 | $ git merge part2 | |
98 | $ git branch -d part2 # don't need this branch anymore | |
99 | ||
100 | and the second part of the change is ready to review. | |
101 | ||
102 | But wait! What if it wasn't that simple? Say you made a mistake in the first part, which you have to correct before submitting. No problem! First, switch back to the master branch with | |
103 | ||
104 | $ git checkout master | |
105 | ||
106 | Fix the issue with the first part of the change and hope it gets approved. If not we simply repeat this step. You'll probably want to merge the fixed version of Part I into Part II as well: | |
107 | ||
108 | $ git checkout part2 | |
109 | $ git merge master | |
110 | ||
111 | Now it's the same as before. Once the first part has been approved and submitted: | |
112 | ||
113 | $ git checkout master | |
114 | $ git merge part2 | |
115 | $ git branch -d part2 | |
116 | ||
117 | and again, the second part is ready to be reviewed. | |
118 | ||
119 | It's easy to extend this trick for any number of parts. | |
120 | ||
121 | === Reorganizing a Medley === | |
122 | ||
123 | Perhaps you like to work on all aspects of a project in the same branch. You want to keep works-in-progress to yourself and want others to see your commits only when they have been neatly organized. Start a couple of branches: | |
124 | ||
125 | $ git checkout -b sanitized | |
126 | $ git checkout -b medley | |
127 | ||
128 | Next, work on anything: fix bugs, add features, add temporary code, and so forth, committing often along the way. Then: | |
129 | ||
130 | $ git checkout sanitized | |
131 | $ git cherry-pick SHA1_HASH | |
132 | ||
133 | applies a given commit to the "sanitized" branch. With appropriate cherry-picks you can construct a branch that contains only permanent code, and has related commits grouped together. | |
134 | ||
135 | === Managing Branches === | |
136 | ||
137 | List all branches by typing: | |
138 | ||
139 | $ git branch | |
140 | ||
141 | There is always a branch named "master", and you start here by default. Some | |
142 | advocate leaving the "master" branch untouched and creating new branches for | |
143 | your own edits. | |
144 | ||
145 | The *-d* and *-m* options allow you to delete and move (rename) branches. | |
146 | See *git help branch*. | |
147 | ||
148 | The "master" branch is a useful convention. Others may assume that your | |
149 | repository has a branch with this name, and that it contains the official | |
150 | version of your project. You can rename or obliterate the "master" branch, but | |
151 | you might as well respect this custom. | |
152 | ||
153 | === Temporary Branches === | |
154 | ||
155 | After a while you may realize you are creating short-lived branches | |
156 | frequently for similar reasons: every other branch merely serves to | |
157 | save the current state so you can briefly hop back to an older state to | |
158 | fix a high-priority bug or something. | |
159 | ||
160 | It's analogous to changing the TV channel temporarily to see what else is on. | |
161 | But instead of pushing a couple of buttons, you have to create, check out and | |
162 | delete temporary branches and commits. Luckily, Git has a shorcut that | |
163 | is as convenient as a TV remote control: | |
164 | ||
165 | $ git stash | |
166 | ||
167 | This saves the current state in a temporary location (a 'stash') and | |
168 | restores the previous state. Your working directory appears exactly as it was | |
169 | before you started editing, and you can fix bugs, pull in upstream changes, and | |
170 | so on. When you want to go back to the stashed state, type: | |
171 | ||
172 | $ git stash apply # You may need to resolve some conflicts. | |
173 | ||
174 | You can have multiple stashes, and manipulate them in various ways. See | |
175 | *git help stash*. As you may have guessed, Git maintains branches behind the scenes to perform this magic trick. | |
176 | ||
177 | === Work How You Want === | |
178 | ||
179 | Applications such as http://www.mozilla.com/[Mozilla Firefox] allow you to open multiple tabs and multiple windows. Switching tabs gives you different content in the same window. Git branching is like tabs for your working directory. Continuing this analogy, Git cloning is like opening a new window. Being able to do both improves the user experience. | |
180 | ||
181 | On a higher level, several Linux window managers support multiple desktops. | |
182 | Branching in Git is similar to switching to a different desktop, while cloning | |
183 | is similar to attaching another monitor to gain another desktop. | |
184 | ||
185 | Yet another example is the http://www.gnu.org/software/screen/[*screen*] utility. This gem lets you create, destroy and switch between multiple terminal sessions in the same terminal. Instead of opening new terminals (clone), you can use the same one if you run *screen* (branch). In fact, you can do a lot more with *screen* but that's a topic for another text. | |
186 | ||
187 | Cloning, branching, and merging are fast and local in Git, encouraging you to use the combination that best suits you. Git lets you work exactly how you want. |
0 | == Cloning Around == | |
1 | ||
2 | In older version control systems, checkout is the standard operation to get files. You retrieve a bunch of files in the requested saved state. | |
3 | ||
4 | In Git and other distributed version control systems, cloning is the standard operation. To get files you create a clone of the entire repository. In other words, you practically mirror the central server. Anything the main repository can do, you can do. | |
5 | ||
6 | === Sync Computers === | |
7 | ||
8 | This is the reason I first used Git. I can tolerate making tarballs or using *rsync* for backups and basic syncing. But sometimes I edit on my laptop, other times on my desktop, and the two may not have talked to each other in between. | |
9 | ||
10 | Initialize a Git repository and commit your files on one machine. Then on the other: | |
11 | ||
12 | $ git clone other.computer:/path/to/files | |
13 | ||
14 | to create a second copy of the files and Git repository. From now on, | |
15 | ||
16 | $ git commit -a | |
17 | $ git pull other.computer:/path/to/files HEAD | |
18 | ||
19 | will pull in the state of the files on the other computer into the one you're working on. If you've recently made conflicting edits in the same file, Git will let you know and you should commit again after resolving them. | |
20 | ||
21 | === Classic Source Control === | |
22 | ||
23 | Initialize a Git repository for your files: | |
24 | ||
25 | $ git init | |
26 | $ git add . | |
27 | $ git commit -m "Initial commit" | |
28 | ||
29 | On the central server, initialize an empty Git repository with some name, | |
30 | and start the Git daemon if necessary: | |
31 | ||
32 | $ GIT_DIR=proj.git git init | |
33 | $ git daemon --detach # it might already be running | |
34 | ||
35 | For Git hosting services, follow the instructions to setup the initially | |
36 | empty Git repository. Typically one fills in a form on a webpage. | |
37 | ||
38 | Push your project to the central server with: | |
39 | ||
40 | $ git push git://central.server/path/to/proj.git HEAD | |
41 | ||
42 | We're ready. To check out source, a developer types | |
43 | ||
44 | $ git clone git://central.server/path/to/proj.git | |
45 | ||
46 | After making changes, the code is checked in to the main server by: | |
47 | ||
48 | $ git commit -a | |
49 | $ git push | |
50 | ||
51 | If the main server has been updated, the latest version needs to be checked out before the push. To sync to the latest version: | |
52 | ||
53 | $ git commit -a | |
54 | $ git pull | |
55 | ||
56 | ==== Push versus pull ==== | |
57 | ||
58 | We mostly avoid pushing into a repository, because confusion can ensue | |
59 | if the destination has a working directory with changes. However, pushing into | |
60 | a bare repository is a straightforward operation and more suitable than a pull | |
61 | in this case. | |
62 | ||
63 | Pulling from the server requires shelling into the server, and also | |
64 | knowing the network address of the machine you happen to be working on. | |
65 | Furthermore, firewalls may interfere. | |
66 | ||
67 | === Forking a Project === | |
68 | ||
69 | Sick of the way a project is being run? Think you could do a better job? Then on your server: | |
70 | ||
71 | $ git clone git://main.server/path/to/files | |
72 | ||
73 | Next tell everyone about your fork of the project at your server. | |
74 | ||
75 | At any later time, you can merge in the changes from the original project with: | |
76 | ||
77 | $ git pull | |
78 | ||
79 | === Ultimate Backups === | |
80 | ||
81 | Want numerous tamper-proof geographically diverse redundant archives? If your project has many developers, don't do anything! Every clone of your code is effectively a backup. Not just of the current state, but of your project's entire history. Thanks to cryptographic hashing, if anyone's clone becomes corrupted, it will be spotted as soon as they try to communicate with others. | |
82 | ||
83 | If your project is not so popular, find as many servers as you can to host clones. | |
84 | ||
85 | The truly paranoid should always write down the latest 20-byte SHA1 hash of the HEAD somewhere safe. It has to be safe, not private. For example, publishing it in a newspaper would work well, because it's hard for an attacker to alter every copy of a newspaper. | |
86 | ||
87 | === Light-Speed Multitask === | |
88 | ||
89 | Say you want to work on several features in parallel. Then commit your project and run: | |
90 | ||
91 | $ git clone . /some/new/directory | |
92 | ||
93 | Git exploits hard links and file sharing as much as safely possible to create this clone, so it will be ready in a flash, and you can now work on two independent features simultaneously. For example, you can edit one clone while the other is compiling. | |
94 | ||
95 | At any time, you can commit and pull changes from the other clone. | |
96 | ||
97 | $ git pull /the/other/clone HEAD | |
98 | ||
99 | === Guerilla Version Control === | |
100 | ||
101 | Are you working on a project that uses some other version control system, and you sorely miss Git? Then initialize a Git repository in your working directory: | |
102 | ||
103 | $ git init | |
104 | $ git add . | |
105 | $ git commit -m "Initial commit" | |
106 | ||
107 | then clone it: | |
108 | ||
109 | $ git clone . /some/new/directory | |
110 | ||
111 | Now go to the new directory and work here instead, using Git to your heart's content. Once in a while, you'll want to sync with everyone else, in which case go to the original directory, sync using the other version control system, and type: | |
112 | ||
113 | $ git add . | |
114 | $ git commit -m "Sync with everyone else" | |
115 | ||
116 | Then go to the new directory and run: | |
117 | ||
118 | $ git commit -a -m "Description of my changes" | |
119 | $ git pull | |
120 | ||
121 | The procedure for giving your changes to everyone else depends on the other version control system. The new directory contains the files with your changes. Run whatever commands of the other version control system are needed to upload them to the central repository. | |
122 | ||
123 | The *git svn* command automates the above for Subversion repositories, and can | |
124 | also be used to | |
125 | http://google-opensource.blogspot.com/2008/05/export-git-project-to-google-code.html[export a Git project to a Subversion repository]. |
0 | == Appendix A: Git Shortcomings == | |
1 | ||
2 | There are some Git issues I've swept under the carpet. Some can be handled easily with scripts and hooks, some require reorganizing or redefining the project, and for the few remaining annoyances, one will just have to wait. Or better yet, pitch in and help! | |
3 | ||
4 | === SHA1 Weaknesses === | |
5 | ||
6 | As time passes, cryptographers discover more and more SHA1 weaknesses. Already, | |
7 | finding hash collisions is feasible for well-funded organizations. Within | |
8 | years, perhaps even a typical PC will have enough computing power to silently | |
9 | corrupt a Git repository. | |
10 | ||
11 | Hopefully Git will migrate to a better hash function before further research | |
12 | destroys SHA1. | |
13 | ||
14 | === Microsoft Windows === | |
15 | ||
16 | Git on Microsoft Windows can be cumbersome: | |
17 | ||
18 | - http://cygwin.com/[Cygwin], a Linux-like environment for Windows, contains http://cygwin.com/packages/git/[a Windows port of Git]. | |
19 | ||
20 | - http://code.google.com/p/msysgit/[Git on MSys] is an alternative requiring minimal runtime support, though a few of the commands need some work. | |
21 | ||
22 | === Unrelated Files === | |
23 | ||
24 | If your project is very large and contains many unrelated files that are constantly being changed, Git may be disadvantaged more than other systems because single files are not tracked. Git tracks changes to the whole project, which is usually beneficial. | |
25 | ||
26 | A solution is to break up your project into pieces, each consisting of related files. Use *git submodule* if you still want to keep everything in a single repository. | |
27 | ||
28 | === Who's Editing What? === | |
29 | ||
30 | Some version control systems force you to explicitly mark a file in some way before editing. While this is especially annoying when this involves talking to a central server, it does have two benefits: | |
31 | ||
32 | 1. Diffs are quick because only the marked files need be examined. | |
33 | ||
34 | 2. One can discover who else is working on the file by asking the central server who has marked it for editing. | |
35 | ||
36 | With appropriate scripting, you can achieve the same with Git. This requires cooperation from the programmer, who should execute particular scripts when editing a file. | |
37 | ||
38 | === File History === | |
39 | ||
40 | Since Git records project-wide changes, reconstructing the history of a single file requires more work than in version control systems that track individual files. | |
41 | ||
42 | The penalty is typically slight, and well worth having as other operations are incredibly efficient. For example, `git checkout` is faster than `cp -a`, and project-wide deltas compress better than collections of file-based deltas. | |
43 | ||
44 | === Initial Clone === | |
45 | ||
46 | Creating a clone is more expensive than checking out code in other version control systems when there is a lengthy history. | |
47 | ||
48 | The initial cost is worth paying in the long run, as most future operations will then be fast and offline. However, in some situations, it may be preferable to create a shallow clone with the `--depth` option. This is much faster, but the resulting clone has reduced functionality. | |
49 | ||
50 | === Volatile Projects === | |
51 | ||
52 | Git was written to be fast with respect to the size of the changes. Humans make small edits from version to version. A one-liner bugfix here, a new feature there, emended comments, and so forth. But if your files are radically different in successive revisions, then on each commit, your history necessarily grows by the size of your whole project. | |
53 | ||
54 | There is nothing any version control system can do about this, but standard Git users will suffer more since normally histories are cloned. | |
55 | ||
56 | The reasons why the changes are so great should be examined. Perhaps file formats should be changed. Minor edits should only cause minor changes to at most a few files. | |
57 | ||
58 | Or perhaps a database or backup/archival solution is what is actually being sought, not a version control system. For example, version control may be ill-suited for managing photos periodically taken from a webcam. | |
59 | ||
60 | If the files really must be constantly morphing and they really must be versioned, a possibility is to use Git in a centralized fashion. One can create shallow clones, which checks out little or no history of the project. Of course, many Git tools will be unavailable, and fixes must be submitted as patches. This is probably fine as it's unclear why anyone would want the history of wildly unstable files. | |
61 | ||
62 | Another example is a project depending on firmware, which takes the form of a huge binary file. The history of the firmware is uninteresting to users, and updates compress poorly, so firmware revisions would unnecessarily blow up the size of the repository. | |
63 | ||
64 | In this case, the source code should be stored in a Git repository, and the binary file should be kept separately. To make life easier, one could distribute a script that uses Git to clone the code, and rsync or a Git shallow clone for the firmware. | |
65 | ||
66 | === Global Counter === | |
67 | ||
68 | Some centralized version control systems maintain a positive integer that increases when a new commit is accepted. Git refers to changes by their hash, which is better in many circumstances. | |
69 | ||
70 | But some people like having this integer around. Luckily, it's easy to write scripts so that with every update, the central Git repository increments an integer, perhaps in a tag, and associates it with the hash of the latest commit. | |
71 | ||
72 | Every clone could maintain such a counter, but this would probably be useless, since only the central repository and its counter matters to everyone. | |
73 | ||
74 | === Empty Subdirectories === | |
75 | ||
76 | Empty subdirectories cannot be tracked. Create dummy files to work around this problem. | |
77 | ||
78 | The current implementation of Git, rather than its design, is to blame for this drawback. With luck, once Git gains more traction, more users will clamour for this feature and it will be implemented. | |
79 | ||
80 | === Initial Commit === | |
81 | ||
82 | A stereotypical computer scientist counts from 0, rather than 1. Unfortunately, with respect to commits, git does not adhere to this convention. Many commands are unfriendly before the initial commit. Additionally, some corner cases must be handled specially, such as rebasing a branch with a different initial commit. | |
83 | ||
84 | Git would benefit from defining the zero commit: as soon as a repository is constructed, HEAD would be set to the string consisting of 20 zero bytes. This special commit represents an empty tree, with no parent, at some time predating all Git repositories. | |
85 | ||
86 | Then running git log, for example, would inform the user that no commits have been made yet, instead of exiting with a fatal error. Similarly for other tools. | |
87 | ||
88 | Every initial commit is implicitly a descendant of this zero commit. For example, rebasing an unrelated branch would cause the whole branch to be grafted on to the target. Currently, all but the initial commit is applied, resulting in a merge conflict. One workaround is to use `git checkout` followed by `git commit -C` on the initial commit, then rebase the rest. | |
89 | ||
90 | There are worse cases unfortunately. If several branches with different initial commits are merged together, then rebasing the result requires substantial manual intervention. | |
91 | ||
92 | === Interface Quirks === | |
93 | ||
94 | For commits A and B, the meaning of the expressions "A..B" and "A...B" depends | |
95 | on whether the command expects two endpoints or a range. See *git help diff* | |
96 | and *git help rev-parse*. | |
97 | ||
98 | Some error messages are inscrutable. For example, if Git cannot create the | |
99 | lockfile +packed-refs.lock+, then you might see: | |
100 | ||
101 | $ git branch -D foo | |
102 | error: cannot delete 'refs/heads/foo' from packed refs | |
103 | error: Error deleting branch 'foo' | |
104 | ||
105 | This could happen if say filesystem trouble prevented the lockfile from being | |
106 | deleted in a previous Git command. In this case the solution is to delete the | |
107 | lockfile and try again, after ensuring no Git commands are still running. | |
108 | ||
109 | The push command ignores the state of the working directory of the target | |
110 | repository. To prevent confusion, push only into bare repositories, or setup a | |
111 | dedicated push-only branch. |
0 | == Git Grandmastery == | |
1 | ||
2 | This pretentiously named page is my dumping ground for uncategorized Git tricks. | |
3 | ||
4 | === Source Releases === | |
5 | ||
6 | For my projects, Git tracks exactly the files I'd like to archive and release | |
7 | to users. To create a tarball of the source code, I run: | |
8 | ||
9 | $ git archive --format=tar --prefix=proj-1.2.3/ HEAD | |
10 | ||
11 | === Commit What Changed === | |
12 | ||
13 | Telling Git when you've added, deleted and renamed files is troublesome for | |
14 | certain projects. Instead, you can type: | |
15 | ||
16 | $ git add . | |
17 | $ git add -u | |
18 | ||
19 | Git will look at the files in the current directory and work out the details by | |
20 | itself. Instead of the second add command, run `git commit -a` if you also | |
21 | intend to commit at this time. See *git help ignore* for how to specify files | |
22 | that should be ignored. | |
23 | ||
24 | You can perform the above in a single pass with: | |
25 | ||
26 | $ git ls-files -d -m -o -z | xargs -0 git update-index --add --remove | |
27 | ||
28 | The *-z* and *-0* options prevent ill side-effects from filenames containing | |
29 | strange characters. As this command adds ignored files, you may want to use the | |
30 | `-x` or `-X` option. | |
31 | ||
32 | === My Commit Is Too Big! === | |
33 | ||
34 | Have you neglected to commit for too long? Been coding furiously and forgotten | |
35 | about source control until now? Made a series of unrelated changes, because | |
36 | that's your style? | |
37 | ||
38 | No worries. Run: | |
39 | ||
40 | $ git add -p | |
41 | ||
42 | For each edit you made, Git will show you the hunk of code that was changed, | |
43 | and ask if it should be part of the next commit. Answer with "y" or "n". You | |
44 | have other options, such as postponing the decision; type "?" to learn more. | |
45 | ||
46 | Once you're satisfied, type | |
47 | ||
48 | $ git commit | |
49 | ||
50 | to commit precisely the changes you selected (the 'staged' changes). Make sure | |
51 | you omit the *-a* option, otherwise Git will commit all the edits. | |
52 | ||
53 | What if you've edited many files in many places? Reviewing each change one by | |
54 | one becomes frustratingly mind-numbing. In this case, use *git add -i*, whose | |
55 | interface is less straightforward, but more flexible. With a few keystrokes, | |
56 | you can stage or unstage several files at a time, or review and select changes | |
57 | in particular files only. Alternatively, run *git commit \--interactive* which | |
58 | automatically commits after you're done. | |
59 | ||
60 | ==== Staged Changes ==== | |
61 | ||
62 | So far we have avoided Git's famous 'index', but we must now confront it to | |
63 | explain the above. The index is a temporary staging area. Git seldom shuttles | |
64 | data directly between your project and its history. Rather, Git first writes | |
65 | data to the index, and then copies the data in the index to its final | |
66 | destination. | |
67 | ||
68 | For example, *commit -a* is really a two-step process. The first step places a | |
69 | snapshot of the current state of every tracked file into the index. The second | |
70 | step permanently records the snapshot now in the index. Committing without the | |
71 | *-a* option only performs the second step, and only makes sense after running | |
72 | commands that somehow change the index, such as *git add*. | |
73 | ||
74 | Usually we can ignore the index and pretend we are reading straight from and writing straight to the history. On this occasion, we want finer control on what gets written to history, and are forced to manipulate the index. We place a snapshot of some, but not all, of our changes into the index, and then permanently record this carefully rigged snapshot. | |
75 | ||
76 | === Don't Lose Your HEAD === | |
77 | ||
78 | The HEAD tag is like a cursor that normally points at the latest commit, advancing with each new commit. Some Git commands let you move it. For example: | |
79 | ||
80 | $ git reset HEAD~3 | |
81 | ||
82 | will move the HEAD three commits back. Thus all Git commands now act as if you hadn't made those last three commits, while your files remain in the present. See the help page for some applications. | |
83 | ||
84 | But how can you go back to the future? The past commits know nothing of the future. | |
85 | ||
86 | If you have the SHA1 of the original HEAD then: | |
87 | ||
88 | $ git reset SHA1 | |
89 | ||
90 | But suppose you never took it down? Don't worry, for commands like these, Git saves the original HEAD as a tag called ORIG_HEAD, and you can return safe and sound with: | |
91 | ||
92 | $ git reset ORIG_HEAD | |
93 | ||
94 | === HEAD-hunting === | |
95 | ||
96 | Perhaps ORIG_HEAD isn't enough. Perhaps you've just realized you made a monumental mistake and you need to go back to an ancient commit in a long-forgotten branch. | |
97 | ||
98 | By default, Git keeps a commit for at least two weeks, even if you ordered | |
99 | Git to destroy the branch containing it. The trouble is finding the appropriate | |
100 | hash. You could look at all the hash values in `.git/objects` and use trial | |
101 | and error to find the one you want. But there's a much easier way. | |
102 | ||
103 | Git records every hash of a commit it computes in `.git/logs`. The subdirectory `refs` contains the history of all activity on all branches, while the file `HEAD` shows every hash value it has ever taken. The latter can be used to find hashes of commits on branches that have been accidentally lopped off. | |
104 | ||
105 | The reflog command provides a friendly interface to these log files. Try | |
106 | ||
107 | $ git reflog | |
108 | ||
109 | Instead of cutting and pasting hashes from the reflog, try: | |
110 | ||
111 | $ git checkout "@{10 minutes ago}" | |
112 | ||
113 | Or checkout the 5th-last visited commit via: | |
114 | ||
115 | $ git checkout "@{5}" | |
116 | ||
117 | See the ``Specifying Revisions'' section of *git help rev-parse* for more. | |
118 | ||
119 | You may wish to configure a longer grace period for doomed commits. For | |
120 | example: | |
121 | ||
122 | $ git config gc.pruneexpire "30 days" | |
123 | ||
124 | means a deleted commit will only be permanently lost once 30 days have passed | |
125 | and *git gc* is run. | |
126 | ||
127 | You may also wish to disable automatic invocations of *git gc*: | |
128 | ||
129 | $ git conifg gc.auto 0 | |
130 | ||
131 | in which case commits will only be deleted when you run *git gc* manually. | |
132 | ||
133 | === Building On Git === | |
134 | ||
135 | In true UNIX fashion, Git's design allows it to be easily used as a low-level component of other programs, such as GUI and web interfaces, alternative command-line interfaces, patch managements tools, importing and conversion tools and so on. In fact, some Git commands are themselves scripts standing on the shoulders of giants. With a little tinkering, you can customize Git to suit your preferences. | |
136 | ||
137 | One easy trick is to use built-in Git aliases to shorten your most frequently | |
138 | used commands: | |
139 | ||
140 | $ git config --global alias.co checkout | |
141 | $ git config --global --get-regexp alias # display current aliases | |
142 | alias.co checkout | |
143 | $ git co foo # same as 'git checkout foo' | |
144 | ||
145 | Another is to print the current branch in the prompt, or window title. | |
146 | Invoking | |
147 | ||
148 | $ git symbolic-ref HEAD | |
149 | ||
150 | shows the current branch name. In practice, you most likely want to remove | |
151 | the "refs/heads/" and ignore errors: | |
152 | ||
153 | $ git symbolic-ref HEAD 2> /dev/null | cut -b 12- | |
154 | ||
155 | The +contrib+ subdirectory is a treasure trove of tools built on Git. | |
156 | In time, some of them may be promoted to official commands. On Debian and | |
157 | Ubuntu, this directory lives at +/usr/share/doc/git-core/contrib+. | |
158 | ||
159 | One popular resident is +workdir/git-new-workdir+. Via clever symlinking, this script creates a new working directory whose history is shared with the original respository: | |
160 | ||
161 | $ git-new-workdir an/existing/repo new/directory | |
162 | ||
163 | The new directory and files within can be thought of as a clone, except since the history is shared, the two trees automatically stay in sync. There's no need to merge, push or pull. | |
164 | ||
165 | === Daring Stunts === | |
166 | ||
167 | These days, Git makes it difficult for the user to accidentally destroy data. | |
168 | But if you know what you are doing, you can override safeguards for common | |
169 | commands. | |
170 | ||
171 | *Checkout*: Uncommitted changes cause checkout to fail. To destroy your changes, and checkout a given commit anyway, use the force flag: | |
172 | ||
173 | $ git checkout -f COMMIT | |
174 | ||
175 | On the other hand, if you specify particular paths for checkout, then there are no safety checks. The supplied paths are quietly overwritten. Take care if you use checkout in this manner. | |
176 | ||
177 | *Reset*: Reset also fails in the presence of uncommitted changes. To force it through, run: | |
178 | ||
179 | $ git reset --hard [COMMIT] | |
180 | ||
181 | *Branch*: Deleting branches fails if this causes changes to be lost. To force a deletion, type: | |
182 | ||
183 | $ git branch -D BRANCH # instead of -d | |
184 | ||
185 | Similarly, attempting to overwrite a branch via a move fails if data loss would ensue. To force a branch move, type: | |
186 | ||
187 | $ git branch -M [SOURCE] TARGET # instead of -m | |
188 | ||
189 | Unlike checkout and reset, these two commands defer data destruction. The | |
190 | changes are still stored in the .git subdirectory, and can be retrieved by | |
191 | recovering the appropriate hash from `.git/logs` (see "HEAD-hunting" above). | |
192 | By default, they will be kept for at least two weeks. | |
193 | ||
194 | *Clean*: Some git commands refuse to proceed because they're worried about | |
195 | clobbering untracked files. If you're certain that all untracked files and | |
196 | directories are expendable, then delete them mercilessly with: | |
197 | ||
198 | $ git clean -f -d | |
199 | ||
200 | Next time, that pesky command will work! | |
201 | ||
202 | === Improve Your Public Image === | |
203 | ||
204 | Stupid mistakes abound in the histories of many of my projects. The most | |
205 | frightening are missing files due to forgetting to run *git add*. Luckily I | |
206 | have yet to lose crucial data though accidental omission because I rarely | |
207 | delete original working directories. I typically notice the error a few commits | |
208 | later, so the only damage is a bit of missing history and a sheepish admission | |
209 | of guilt. | |
210 | ||
211 | I also regularly commit (literally and git-erally) the lesser transgression of | |
212 | trailing whitespace. Though harmless, I wish these also never appeared on the | |
213 | public record. | |
214 | ||
215 | In addition, though unscathed so far, I worry about leaving merge conflicts | |
216 | unresolved. Usually I catch them when I build a project, but there are some | |
217 | cases this can overlook. | |
218 | ||
219 | If only I had bought idiot insurance by using a _hook_ to alert me about these | |
220 | problems: | |
221 | ||
222 | $ cd .git/hooks | |
223 | $ cp pre-commit.sample pre-commit # Older Git versions: chmod +x pre-commit | |
224 | ||
225 | Now Git aborts a commit if useless whitespace or unresolved merge conflicts are | |
226 | detected. | |
227 | ||
228 | For this guide, I eventually added the following to the beginning of the | |
229 | *pre-commit* hook to guard against absent-mindedness: | |
230 | ||
231 | if git ls-files -o | grep '\.txt$'; then | |
232 | echo FAIL! Untracked .txt files. | |
233 | exit 1 | |
234 | fi | |
235 | ||
236 | Several git operations support hooks; see *git help hooks*. One can write hooks | |
237 | to complain about spelling mistakes in commit messages, add new files, indent | |
238 | paragraphs, append an entry to a webpage, play a sound, and so on. | |
239 | ||
240 | We encountered the *post-update* hook earlier when discussing Git over | |
241 | HTTP. This hook updates a few files Git needs for non-native communication. |
0 | == Lessons of History == | |
1 | ||
2 | A consequence of Git's distributed nature is that history can be edited | |
3 | easily. But if you tamper with the past, take care: only rewrite that part of | |
4 | history which you alone possess. Just as nations forever argue over who | |
5 | committed what atrocity, if someone else has a clone whose version of history | |
6 | differs to yours, you will have trouble reconciling when your trees interact. | |
7 | ||
8 | Of course, if you control all the other trees too, then there is no problem | |
9 | since you can overwrite them. | |
10 | ||
11 | Some developers strongly feel history should be immutable, warts and all. | |
12 | Others feel trees should be made presentable before they are unleashed in | |
13 | public. Git accommodates both viewpoints. Like cloning, branching and merging, | |
14 | rewriting history is simply another power Git gives you. It is up to you | |
15 | to use it wisely. | |
16 | ||
17 | === I Stand Corrected === | |
18 | ||
19 | Did you just commit, but wish you had typed a different message? Then run: | |
20 | ||
21 | $ git commit --amend | |
22 | ||
23 | to change the last message. Realized you forgot to add a file? Run *git add* to | |
24 | add it, and then run the above command. | |
25 | ||
26 | Want to include a few more edits in that last commit? Then make those edits and run: | |
27 | ||
28 | $ git commit --amend -a | |
29 | ||
30 | === ... And Then Some === | |
31 | ||
32 | Let's suppose the previous problem is ten times worse. After a lengthy session you've made a bunch of commits. But you're not quite happy with the way they're organized, and some of those commit messages could use rewording. Then type: | |
33 | ||
34 | $ git rebase -i HEAD~10 | |
35 | ||
36 | and the last 10 commits will appear in your favourite $EDITOR. A sample excerpt: | |
37 | ||
38 | pick 5c6eb73 Added repo.or.cz link | |
39 | pick a311a64 Reordered analogies in "Work How You Want" | |
40 | pick 100834f Added push target to Makefile | |
41 | ||
42 | Then: | |
43 | ||
44 | - Remove commits by deleting lines. | |
45 | - Reorder commits by reordering lines. | |
46 | - Replace "pick" with "edit" to mark a commit for amending. | |
47 | - Replace "pick" with "squash" to merge a commit with the previous one. | |
48 | ||
49 | If you marked a commit for editing, then run: | |
50 | ||
51 | $ git commit --amend | |
52 | ||
53 | Otherwise, run: | |
54 | ||
55 | $ git rebase --continue | |
56 | ||
57 | So commit early and commit often: you can easily tidy up later with rebase. | |
58 | ||
59 | === Local Changes Last === | |
60 | ||
61 | You're working on an active project. You make some local commits over time, and | |
62 | then you sync with the official tree with a merge. This cycle repeats itself a few times before you're ready to push to the central tree. | |
63 | ||
64 | But now the history in your local Git clone is a messy jumble of your changes and the official changes. You'd prefer to see all your changes in one contiguous section, and after all the official changes. | |
65 | ||
66 | This is a job for *git rebase* as described above. In many cases you can use | |
67 | the *--onto* flag and avoid interaction. | |
68 | ||
69 | Also see *git help rebase* for detailed examples of this amazing command. You can split commits. You can even rearrange branches of a tree. | |
70 | ||
71 | === Rewriting History === | |
72 | ||
73 | Occasionally, you need the source control equivalent of airbrushing people out | |
74 | of official photos, erasing them from history in a Stalinesque fashion. For | |
75 | example, suppose we intend to release a project, but it involves a file that | |
76 | should be kept private for some reason. Perhaps I left my credit card number in | |
77 | a text file and accidentally added it to the project. Deleting the file is | |
78 | insufficient, for the file can be accessed from older commits. We must remove | |
79 | the file from all commits: | |
80 | ||
81 | $ git filter-branch --tree-filter 'rm top/secret/file' HEAD | |
82 | ||
83 | See *git help filter-branch*, which discusses this example and gives a faster | |
84 | method. In general, *filter-branch* lets you alter large sections of history | |
85 | with a single command. | |
86 | ||
87 | Afterwards, the +.git/refs/original+ directory describes the state of affairs before the operation. Check the filter-branch command did what you wanted, then delete this directory if you wish to run more filter-branch commands. | |
88 | ||
89 | Lastly, replace clones of your project with your revised version if you want to interact with them later. | |
90 | ||
91 | === Making History === | |
92 | ||
93 | [[makinghistory]] | |
94 | Want to migrate a project to Git? If it's managed with one of the more well-known systems, then chances are someone has already written a script to export the whole history to Git. | |
95 | ||
96 | Otherwise, look up *git fast-import*, which reads text input in a specific | |
97 | format to create Git history from scratch. Typically a script using this | |
98 | command is hastily cobbled together and run once, migrating the project in a | |
99 | single shot. | |
100 | ||
101 | As an example, paste the following listing into temporary file, such as `/tmp/history`: | |
102 | ---------------------------------- | |
103 | commit refs/heads/master | |
104 | committer Alice <alice@example.com> Thu, 01 Jan 1970 00:00:00 +0000 | |
105 | data <<EOT | |
106 | Initial commit. | |
107 | EOT | |
108 | ||
109 | M 100644 inline hello.c | |
110 | data <<EOT | |
111 | #include <stdio.h> | |
112 | ||
113 | int main() { | |
114 | printf("Hello, world!\n"); | |
115 | return 0; | |
116 | } | |
117 | EOT | |
118 | ||
119 | ||
120 | commit refs/heads/master | |
121 | committer Bob <bob@example.com> Tue, 14 Mar 2000 01:59:26 -0800 | |
122 | data <<EOT | |
123 | Replace printf() with write(). | |
124 | EOT | |
125 | ||
126 | M 100644 inline hello.c | |
127 | data <<EOT | |
128 | #include <unistd.h> | |
129 | ||
130 | int main() { | |
131 | write(1, "Hello, world!\n", 14); | |
132 | return 0; | |
133 | } | |
134 | EOT | |
135 | ||
136 | ---------------------------------- | |
137 | ||
138 | Then create a Git repository from this temporary file by typing: | |
139 | ||
140 | $ mkdir project; cd project; git init | |
141 | $ git fast-import < /tmp/history | |
142 | ||
143 | You can checkout the latest version of the project with: | |
144 | ||
145 | $ git checkout master . | |
146 | ||
147 | The *git fast-export* command converts any git repository to the | |
148 | *git fast-import* format, whose output you can study for writing exporters, | |
149 | and also to transport git repositories in a human-readable format. Indeed, | |
150 | these commands can send repositories of text files over text-only channels. | |
151 | ||
152 | === Where Did It All Go Wrong? === | |
153 | ||
154 | You've just discovered a broken feature in your program which you know for sure was working a few months ago. Argh! Where did this bug come from? If only you had been testing the feature as you developed. | |
155 | ||
156 | It's too late for that now. However, provided you've been committing often, Git | |
157 | can pinpoint the problem: | |
158 | ||
159 | $ git bisect start | |
160 | $ git bisect bad SHA1_OF_BAD_VERSION | |
161 | $ git bisect good SHA1_OF_GOOD_VERSION | |
162 | ||
163 | Git checks out a state halfway in between. Test the feature, and if it's still broken: | |
164 | ||
165 | $ git bisect bad | |
166 | ||
167 | If not, replace "bad" with "good". Git again transports you to a state halfway | |
168 | between the known good and bad versions, narrowing down the possibilities. | |
169 | After a few iterations, this binary search will lead you to the commit that | |
170 | caused the trouble. Once you've finished your investigation, return to your | |
171 | original state by typing: | |
172 | ||
173 | $ git bisect reset | |
174 | ||
175 | Instead of testing every change by hand, automate the search by running: | |
176 | ||
177 | $ git bisect run COMMAND | |
178 | ||
179 | Git uses the return value of the given command, typically a one-off script, to | |
180 | decide whether a change is good or bad: the command should exit with code 0 | |
181 | when good, 125 when the change should be skipped, and anything else between 1 | |
182 | and 127 if it is bad. A negative return value aborts the bisect. | |
183 | ||
184 | You can do much more: the help page explains how to visualize bisects, examine | |
185 | or replay the bisect log, and eliminate known innocent changes for a speedier | |
186 | search. | |
187 | ||
188 | === Who Made It All Go Wrong? === | |
189 | ||
190 | Like many other version control systems, Git has a blame command: | |
191 | ||
192 | $ git blame FILE | |
193 | ||
194 | which annotates every line in the given file showing who last changed it, and when. Unlike many other version control systems, this operation works offline, reading only from local disk. | |
195 | ||
196 | === Personal Experience === | |
197 | ||
198 | In a centralized version control system, history modification is a difficult | |
199 | operation, and only available to administrators. Cloning, branching, and | |
200 | merging are impossible without network communication. So are basic operations | |
201 | such as browsing history, or committing a change. In some systems, users | |
202 | require network connectivity just to view their own changes or open a file for | |
203 | editing. | |
204 | ||
205 | Centralized systems preclude working offline, and need more expensive network | |
206 | infrastructure, especially as the number of developers grows. Most | |
207 | importantly, all operations are slower to some degree, usually to the point | |
208 | where users shun advanced commands unless absolutely necessary. In extreme | |
209 | cases this is true of even the most basic commands. When users must run slow | |
210 | commands, productivity suffers because of an interrupted work flow. | |
211 | ||
212 | I experienced these phenomena first-hand. Git was the first version control | |
213 | system I used. I quickly grew accustomed to it, taking many features for | |
214 | granted. I simply assumed other systems were similar: choosing a version | |
215 | control system ought to be no different from choosing a text editor or web | |
216 | browser. | |
217 | ||
218 | I was shocked when later forced to use a centralized system. My often flaky | |
219 | internet connection matters little with Git, but makes development unbearable | |
220 | when it needs to be as reliable as local disk. Additionally, I found myself | |
221 | conditioned to avoid certain commands because of the latencies involved, which | |
222 | ultimately prevented me from following my desired work flow. | |
223 | ||
224 | When I had to run a slow command, the interruption to my train of thought | |
225 | dealt a disproportionate amount of damage. While waiting for server | |
226 | communication to complete, I'd do something else to pass the time, such as | |
227 | check email or write documentation. By the time I returned to the original | |
228 | task, the command had finished long ago, and I would waste more time trying to | |
229 | remember what I was doing. Humans are bad at context switching. | |
230 | ||
231 | There was also an interesting tragedy-of-the-commons effect: anticipating | |
232 | network congestion, individuals would consume more bandwidth than necessary on | |
233 | various operations in an attempt to reduce future delays. The combined efforts | |
234 | intensified congestion, encouraging individuals to consume even more bandwidth | |
235 | next time to avoid even longer delays. |
0 | == Introduction == | |
1 | ||
2 | I'll use an analogy to introduce version control. See http://en.wikipedia.org/wiki/Revision_control[the Wikipedia entry on revision control] for a saner explanation. | |
3 | ||
4 | === Work is Play === | |
5 | ||
6 | I've played computer games almost all my life. In contrast, I only started using version control systems as an adult. I suspect I'm not alone, and comparing the two may make these concepts easier to explain and understand. | |
7 | ||
8 | Think of editing your code or document, or whatever, as playing a game. Once you've made a lot of progress, you'd like to save. To do so, you click on the "Save" button in your trusty editor. | |
9 | ||
10 | But this will overwrite the old version. It's like those old school games which only had one save slot: sure you could save, but you could never go back to an older state. Which was a shame, because your previous save might have been right at an exceptionally fun part of the game that you'd like to revisit one day. Or worse still, your current save is in an unwinnable state, and you have to start again. | |
11 | ||
12 | === Version Control === | |
13 | ||
14 | When editing, you can "Save As..." a different file, or copy the file somewhere first before saving if you want to savour old versions. You can compress them too to save space. This is a primitive and labour-intensive form of version control. Computer games improved on this long ago, many of them providing multiple automatically timestamped save slots. | |
15 | ||
16 | Let's make the problem slightly tougher. Say you have a bunch of files that go together, such as source code for a project, or files for a website. Now if you want to keep an old version you have to archive a whole directory. Keeping many versions around by hand is inconvenient, and quickly becomes expensive. | |
17 | ||
18 | With some computer games, a saved game really does consist of a directory full of files. These games hide this detail from the player and present a convenient interface to manage different versions of this directory. | |
19 | ||
20 | Version control systems are no different. They all have nice interfaces to manage a directory of stuff. You can save the state of the directory every so often, and you can load any one of the saved states later on. Unlike most computer games, they're usually smart about conserving space. Typically, only a few files change between version to version, and not by much. Storing the differences instead of entire new copies saves room. | |
21 | ||
22 | === Distributed Control === | |
23 | ||
24 | Now imagine a very difficult computer game. So difficult to finish that many experienced gamers all over the world decide to team up and share their saved games to try to beat it. Speedruns are real-life examples: players specializing in different levels of the same game collaborate to produce amazing results. | |
25 | ||
26 | How would you set up a system so they can get at each other's saves easily? And upload new ones? | |
27 | ||
28 | In the old days, every project used centralized version control. A server somewhere held all the saved games. Nobody else did. Every player kept at most a few saved games on their machine. When a player wanted to make progress, they'd download the latest save from the main server, play a while, save and upload back to the server for everyone else to use. | |
29 | ||
30 | What if a player wanted to get an older saved game for some reason? Maybe the current saved game is in an unwinnable state because somebody forgot to pick up an object back in level three, and they want to find the latest saved game where the game can still be completed. Or maybe they want to compare two older saved games to see how much work a particular player did. | |
31 | ||
32 | There could be many reasons to want to see an older revision, but the outcome is the same. They have to ask the central server for that old saved game. The more saved games they want, the more they need to communicate. | |
33 | ||
34 | The new generation of version control systems, of which Git is a member, are known as distributed systems, and can be thought of as a generalization of centralized systems. When players download from the main server they get every saved game, not just the latest one. It's as if they're mirroring the central server. | |
35 | ||
36 | This initial cloning operation can be expensive, especially if there's a long history, but it pays off in the long run. One immediate benefit is that when an old save is desired for any reason, communication with the central server is unnecessary. | |
37 | ||
38 | ==== A Silly Superstition ==== | |
39 | ||
40 | A popular misconception is that distributed systems are ill-suited for projects requiring an official central repository. Nothing could be further from the truth. Photographing someone does not cause their soul to be stolen. Similarly, cloning the master repository does not diminish its importance. | |
41 | ||
42 | A good first approximation is that anything a centralized version control system can do, a well-designed distributed system can do better. Network resources are simply costlier than local resources. While we shall later see there are drawbacks to a distributed approach, one is less likely to make erroneous comparisons with this rule of thumb. | |
43 | ||
44 | A small project may only need a fraction of the features offered by such a | |
45 | system, but saying you should use systems that don't scale well when your | |
46 | project is tiny is like saying you should use Roman numerals for calculations | |
47 | involving small numbers. | |
48 | ||
49 | Moreover, your project may grow beyond your original expectations. Using Git from the outset is like carrying a Swiss army knife even though you mostly use it to open bottles. On the day you desperately need a screwdriver you'll be glad you have more than a plain bottle-opener. | |
50 | ||
51 | === Merge Conflicts === | |
52 | ||
53 | For this topic, our computer game analogy becomes too thinly stretched. Instead, let us again consider editing a document. | |
54 | ||
55 | Suppose Alice inserts a line at the beginning of a file, and Bob appends one at the end of his copy. They both upload their changes. Most systems will automatically deduce a reasonable course of action: accept and merge their changes, so both Alice's and Bob's edits are applied. | |
56 | ||
57 | Now suppose both Alice and Bob have made distinct edits to the same line. Then it is impossible to proceed without human intervention. The second person to upload is informed of a _merge conflict_, and must choose one edit over another, or revise the line entirely. | |
58 | ||
59 | More complex situations can arise. Version control systems handle the simpler cases themselves, and leave the difficult cases for humans. Usually their behaviour is configurable. |
0 | == Multiplayer Git == | |
1 | ||
2 | Initially I used Git on a private project where I was the sole developer. | |
3 | Amongst the commands related to Git's distributed nature, I needed only *pull* | |
4 | and *clone* so could I keep the same project in different places. | |
5 | ||
6 | Later I wanted to publish my code with Git, and include changes from | |
7 | contributors. I had to learn how to manage projects with multiple developers | |
8 | from all over the world. Fortunately, this is Git's forte, and arguably its | |
9 | raison d'être. | |
10 | ||
11 | === Who Am I? === | |
12 | ||
13 | Every commit has an author name and email, which is shown by *git log*. | |
14 | By default, Git uses system settings to populate these fields. | |
15 | To set them explicitly, type: | |
16 | ||
17 | $ git config --global user.name "John Doe" | |
18 | $ git config --global user.email johndoe@example.com | |
19 | ||
20 | Omit the global flag to set these options only for the current repository. | |
21 | ||
22 | === Git Over SSH, HTTP === | |
23 | ||
24 | Suppose you have SSH access to a web server, but Git is not installed. Though | |
25 | less efficient than its native protocol, Git can communicate over HTTP. | |
26 | ||
27 | Download, compile and install Git in your account, and create a repository in | |
28 | your web directory: | |
29 | ||
30 | $ GIT_DIR=proj.git git init | |
31 | ||
32 | In the "proj.git" directory, run: | |
33 | ||
34 | $ git --bare update-server-info | |
35 | $ cp hooks/post-update.sample hooks/post-update | |
36 | ||
37 | For older versions of Git, the copy command fails and you should run: | |
38 | ||
39 | $ chmod a+x hooks/post-update | |
40 | ||
41 | Now you can publish your latest edits via SSH from any clone: | |
42 | ||
43 | $ git push web.server:/path/to/proj.git master | |
44 | ||
45 | and anybody can get your project with: | |
46 | ||
47 | $ git clone http://web.server/proj.git | |
48 | ||
49 | === Git Over Anything === | |
50 | ||
51 | Want to synchronize repositories without servers, or even a network connection? | |
52 | Need to improvise during an emergency? We've seen <<makinghistory, *git | |
53 | fast-export* and *git fast-import* can convert repositories to a single file | |
54 | and back>>. We could shuttle such files back and forth to transport git | |
55 | repositories over any medium, but a more efficient tool is *git bundle*. | |
56 | ||
57 | The sender creates a 'bundle': | |
58 | ||
59 | $ git bundle create somefile HEAD | |
60 | ||
61 | then transports the bundle, +somefile+, to the other party somehow: email, | |
62 | thumb drive, floppy disk, an *xxd* printout and an OCR machine, | |
63 | reading bits over the phone, smoke signals, etc. The receiver retrieves | |
64 | commits from the bundle by typing: | |
65 | ||
66 | $ git pull somefile | |
67 | ||
68 | The receiver can even do this from an empty repository. Despite its | |
69 | size, +somefile+ contains the entire original git repository. | |
70 | ||
71 | In larger projects, eliminate waste by bundling only changes the other | |
72 | repository lacks: | |
73 | ||
74 | $ git bundle create somefile HEAD ^COMMON_SHA1 | |
75 | ||
76 | If done frequently, one could easily forget which commit was last sent. The | |
77 | help page suggests using tags to solve this. Namely, after you send a bundle, | |
78 | type: | |
79 | ||
80 | $ git tag -f lastbundle HEAD | |
81 | ||
82 | and create new refresher bundles with: | |
83 | ||
84 | $ git bundle create newbundle HEAD ^lastbundle | |
85 | ||
86 | === Patches: The Global Currency === | |
87 | ||
88 | Patches are text representations of your changes that can be easily understood | |
89 | by computers and humans alike. This gives them universal appeal. You can email a | |
90 | patch to developers no matter what version control system they're using. As long | |
91 | as your audience can read their email, they can see your edits. Similarly, on | |
92 | your side, all you require is an email account: there's no need to setup an online Git repository. | |
93 | ||
94 | Recall from the first chapter: | |
95 | ||
96 | $ git diff COMMIT | |
97 | ||
98 | outputs a patch which can be pasted into an email for discussion. In a Git | |
99 | repository, type: | |
100 | ||
101 | $ git apply < FILE | |
102 | ||
103 | to apply the patch. | |
104 | ||
105 | In more formal settings, when author names and perhaps signatures should be | |
106 | recorded, generate the corresponding patches past a certain point by typing: | |
107 | ||
108 | $ git format-patch START_COMMIT | |
109 | ||
110 | The resulting files can be given to *git-send-email*, or sent by hand. You can also specify a range of commits: | |
111 | ||
112 | $ git format-patch START_COMMIT..END_COMMIT | |
113 | ||
114 | On the receving end, save an email to a file, then type: | |
115 | ||
116 | $ git am < FILE | |
117 | ||
118 | This applies the incoming patch and also creates a commit, including information such as the author. | |
119 | ||
120 | With a browser email client, you may need to click a button to see the email in its raw original form before saving the patch to a file. | |
121 | ||
122 | There are slight differences for mbox-based email clients, but if you use one | |
123 | of these, you're probably the sort of person who can figure them out easily | |
124 | without reading tutorials! | |
125 | ||
126 | === Sorry, We've Moved === | |
127 | ||
128 | After cloning a repository, running *git push* or *git pull* will automatically | |
129 | push to or pull from the original URL. How does Git do this? The secret lies in | |
130 | config options initialized created with the clone. Let's take a peek: | |
131 | ||
132 | $ git config --list | |
133 | ||
134 | The +remote.origin.url+ option controls the source URL; "origin" is a nickname | |
135 | given to the source repository. As with the "master" branch convention, we may | |
136 | change or delete this nickname but there is usually no reason for doing so. | |
137 | ||
138 | If the the original repository moves, we can update the URL via: | |
139 | ||
140 | $ git config remote.origin.url NEW_URL | |
141 | ||
142 | The +branch.master.merge+ option specifies the default remote branch in | |
143 | a *git pull*. During the initial clone, it is set to the current branch of the | |
144 | source repository, so even if the HEAD of the source repository subsequently | |
145 | moves to a different branch, a later pull will faithfully follow the | |
146 | original branch. | |
147 | ||
148 | This option only applies to the repository we first cloned from, which is | |
149 | recorded in the option +branch.master.remote+. If we pull in from other | |
150 | repositories we must explicitly state which branch we want: | |
151 | ||
152 | $ git pull ANOTHER_URL master | |
153 | ||
154 | The above explains why some of our earlier push and pull examples had no | |
155 | arguments. | |
156 | ||
157 | === Remote Branches === | |
158 | ||
159 | When you clone a repository, you also clone all its branches. You may not have | |
160 | noticed this because Git hides them away: you must ask for them specifically. | |
161 | This prevents branches in the remote repository from interfering with | |
162 | your branches, and also makes Git easier for beginners. | |
163 | ||
164 | List the remote branches with: | |
165 | ||
166 | $ git branch -r | |
167 | ||
168 | You should see something like: | |
169 | ||
170 | origin/HEAD | |
171 | origin/master | |
172 | origin/experimental | |
173 | ||
174 | These represent branches and the HEAD of the remote repository, and can be used | |
175 | in regular Git commands. For example, suppose you have made many commits, and | |
176 | wish to compare against the last fetched version. You could search through the | |
177 | logs for the appropriate SHA1 hash, but it's much easier to type: | |
178 | ||
179 | $ git diff origin/HEAD | |
180 | ||
181 | Or you can see what the "experimental" branch has been up to: | |
182 | ||
183 | $ git log origin/experimental | |
184 | ||
185 | === Multiple Remotes === | |
186 | ||
187 | Suppose two other developers are working on our project, and we want to | |
188 | keep tabs on both. We can follow more than one repository at a time with: | |
189 | ||
190 | $ git remote add other ANOTHER_URL | |
191 | $ git pull other some_branch | |
192 | ||
193 | Now we have merged in a branch from the second repository, and we have | |
194 | easy access to all branches of all repositories: | |
195 | ||
196 | $ git diff origin/experimental^ other/some_branch~5 | |
197 | ||
198 | But what if we just want to compare their changes without affecting our own | |
199 | work? In other words, we want to examine their branches without having | |
200 | their changes invade our working directory. In this case, rather than pull, | |
201 | run: | |
202 | ||
203 | $ git fetch # Fetch from origin, the default. | |
204 | $ git fetch other # Fetch from the second programmer. | |
205 | ||
206 | This fetches their histories and nothing more, so although the working | |
207 | directory remains untouched, we can refer to any branch of any repository in | |
208 | a Git command. By the way, behind the scenes, a pull is simply a fetch followed | |
209 | by *git merge*; recall the latter merges a given commit into the working | |
210 | directory. Usually we pull because we want to merge after a fetch; this | |
211 | situation is a notable exception. | |
212 | ||
213 | See *git help remote* for how to remove remote repositories, ignore certain | |
214 | branches, and more. | |
215 | ||
216 | === My Preferences === | |
217 | ||
218 | For my projects, I like contributors to prepare Git repositories which I can | |
219 | pull. Some Git hosting services let you host your own fork of a project with | |
220 | the click of a button. | |
221 | ||
222 | After I fetch a tree, I run Git commands to navigate and examine the changes, | |
223 | which ideally are well-organized and well-described. I merge unpublished | |
224 | changes of my own, and perhaps make further edits. Once satisfied, I push to | |
225 | the official repository. | |
226 | ||
227 | Though I infrequently receive contributions, I believe this approach scales | |
228 | well. See | |
229 | http://torvalds-family.blogspot.com/2009/06/happiness-is-warm-scm.html[this | |
230 | blog post by Linus Torvalds]. | |
231 | ||
232 | Staying in the Git world is slightly more convenient than patch files, as it | |
233 | saves me the step of converting them to Git commits. Furthermore, Git | |
234 | automatically handles details such as recording the author's name and email | |
235 | address, as well as the time and date, and asks the author to describe | |
236 | their own change. |
0 | = Git Magic = | |
1 | Ben Lynn | |
2 | August 2007 | |
3 | ||
4 | == Preface == | |
5 | ||
6 | http://git.or.cz/[Git] is a version control Swiss army knife. A reliable versatile multipurpose revision control tool whose extraordinary flexibility makes it tricky to learn, let alone master. | |
7 | ||
8 | As Arthur C. Clarke observed, any sufficiently advanced technology is indistinguishable from magic. This is a great way to approach Git: newbies can ignore its inner workings and view Git as a gizmo that can amaze friends and infuriate enemies with its wondrous abilities. | |
9 | ||
10 | Rather than go into details, we provide rough instructions for particular effects. After repeated use, gradually you will understand how each trick works, and how to tailor the recipes for your needs. | |
11 | ||
12 | .Translations | |
13 | ||
14 | - http://docs.google.com/View?id=dfwthj68_675gz3bw8kj[Chinese (Simplified)]: by JunJie, Meng and JiangWei. | |
15 | - link:/~blynn/gitmagic/intl/es/[Spanish]: by Rodrigo Toledo. | |
16 | - http://www.slideshare.net/slide_user/magia-git[Portuguese]: by Leonardo Siqueira Rodrigues [http://www.slideshare.net/slide_user/magia-git-verso-odt[ODT version]]. | |
17 | ||
18 | .Other Editions | |
19 | ||
20 | - link:book.html[Single webpage]: barebones HTML, with no CSS. | |
21 | - link:book.pdf[PDF file]: printer-friendly. | |
22 | - http://packages.debian.org/search?searchon=names&keywords=gitmagic[Debian package]: get a fast and local copy of this site. http://packages.ubuntu.com/jaunty/gitmagic[Ubuntu package (Jaunty Jackalope)] also available. Handy http://csdcf.stanford.edu/status/[when this server is offline for maintenance]. | |
23 | ||
24 | === Thanks! === | |
25 | ||
26 | Dustin Sallings, Alberto Bertogli, James Cameron, Douglas Livingstone, | |
27 | Michael Budde, Richard Albury, Tarmigan, Derek Mahar, Frode Aannevik, and Keith | |
28 | Rarick contributed suggestions and improvements. | |
29 | ||
30 | Daniel Baumann maintains the Debian package. | |
31 | ||
32 | JunJie, Meng, JiangWei, Rodrigo Toledo, and Leonardo Siqueira Rodrigues | |
33 | worked on translations of this guide. | |
34 | ||
35 | My gratitute goes to many others for your support and praise. If this were | |
36 | a real physical book, I'd quote your generous words on the cover to promote it. | |
37 | ||
38 | If I've left you out by mistake, please tell me or just send me a patch! | |
39 | ||
40 | .Free Git hosting | |
41 | ||
42 | - http://repo.or.cz/[http://repo.or.cz/] hosts free projects. The first Git hosting site. Founded and maintained by one of the earliest Git developers. | |
43 | - http://gitorious.org/[http://gitorious.org/] is another Git hosting site aimed at open-source projects. | |
44 | - http://github.com/[http://github.com/] hosts open-source projects for free, and private projects for a fee. | |
45 | ||
46 | Many thanks to each of these sites for hosting this guide. | |
47 | ||
48 | === License === | |
49 | ||
50 | This guide is released under http://www.gnu.org/licenses/gpl-3.0.html[the GNU General Public License version 3]. Naturally, the source is kept in a Git | |
51 | repository, and can be obtained by typing: | |
52 | ||
53 | $ git clone git://repo.or.cz/gitmagic.git # Creates "gitmagic" directory. | |
54 | ||
55 | or from one of the mirrors: | |
56 | ||
57 | $ git clone git://github.com/blynn/gitmagic.git | |
58 | $ git clone git://gitorious.org/gitmagic/mainline.git |
0 | == Secrets Revealed == | |
1 | ||
2 | We take a peek under the hood and explain how Git performs its miracles. I will skimp over details. For in-depth descriptions refer to http://www.kernel.org/pub/software/scm/git/docs/user-manual.html[the user manual]. | |
3 | ||
4 | === Invisibility === | |
5 | ||
6 | How can Git be so unobtrusive? Aside from occasional commits and merges, you can work as if you were unaware that version control exists. That is, until you need it, and that's when you're glad Git was watching over you the whole time. | |
7 | ||
8 | Other version control systems don't let you forget about them. Permissions of files may be read-only unless you explicitly tell the server which files you intend to edit. The central server might be keeping track of who's checked out which code, and when. When the network goes down, you'll soon suffer. Developers constantly struggle with virtual red tape and bureaucracy. | |
9 | ||
10 | The secret is the `.git` directory in your working directory. Git keeps the history of your project here. The initial "." stops it showing up in `ls` listings. Except when you're pushing and pulling changes, all version control operations operate within this directory. | |
11 | ||
12 | You have total control over the fate of your files because Git doesn't care what you do to them. Git can easily recreate a saved state from `.git` at any time. | |
13 | ||
14 | === Integrity === | |
15 | ||
16 | Most people associate cryptography with keeping information secret, but another equally important goal is keeping information safe. Proper use of cryptographic hash functions can prevent accidental or malicious data corruption. | |
17 | ||
18 | A SHA1 hash can be thought of as a unique 160-bit ID number for every string of bytes you'll encounter in your life. Actually more than that: every string of bytes that any human will ever use over many lifetimes. | |
19 | ||
20 | As a SHA1 hash is itself a string of bytes, we can hash strings of bytes containing other hashes. This simple observation is surprisingly useful: look up 'hash chains'. We'll later see how Git uses it to efficiently guarantee data integrity. | |
21 | ||
22 | Briefly, Git keeps your data in the ".git/objects" subdirectory, where instead of normal filenames, you'll find only IDs. By using IDs as filenames, as well as a few lockfiles and timestamping tricks, Git transforms any humble filesystem into an efficient and robust database. | |
23 | ||
24 | === Intelligence === | |
25 | ||
26 | How does Git know you renamed a file, even though you never mentioned the fact explicitly? Sure, you may have run *git mv*, but that is exactly the same as a *git rm* followed by a *git add*. | |
27 | ||
28 | Git heuristically ferrets out renames and copies between successive versions. In fact, it can detect chunks of code being moved or copied around between files! Though it cannot cover all cases, it does a decent job, and this feature is always improving. If it fails to work for you, try options enabling more expensive copy detection, and consider upgrading. | |
29 | ||
30 | === Indexing === | |
31 | ||
32 | For every tracked file, Git records information such as its size, creation time and last modification time in a file known as the 'index'. To determine whether a file has changed, Git compares its current stats with that held the index. If they match, then Git can skip reading the file again. | |
33 | ||
34 | Since stat calls are considerably faster than file reads, if you only edit a | |
35 | few files, Git can update its state in almost no time. | |
36 | ||
37 | === Bare Repositories === | |
38 | ||
39 | You may have been wondering what format those online Git repositories use. | |
40 | They're plain Git repositories, just like your `.git` directory, except they've got names like `proj.git`, and they have no working directory associated with them. | |
41 | ||
42 | Most Git commands expect the Git index to live in `.git`, and will fail on these bare repositories. Fix this by setting the `GIT_DIR` environment variable to the path of the bare repository, or running Git within the directory itself with the `--bare` option. | |
43 | ||
44 | === Git's Origins === | |
45 | ||
46 | This http://lkml.org/lkml/2005/4/6/121[Linux Kernel Mailing List post] describes the chain of events that led to Git. The entire thread is a fascinating archaeological site for Git historians. | |
47 | ||
48 | === The Object Database === | |
49 | ||
50 | Here's how to write a Git-like system from scratch in a few hours. | |
51 | ||
52 | ==== Blobs ==== | |
53 | ||
54 | First, a magic trick. Pick a filename, any filename. In an empty directory: | |
55 | ||
56 | $ echo sweet > YOUR_FILENAME | |
57 | $ git init | |
58 | $ git add . | |
59 | $ find .git/objects -type f | |
60 | ||
61 | You'll see +.git/objects/aa/823728ea7d592acc69b36875a482cdf3fd5c8d+. | |
62 | ||
63 | How do I know this without knowing the filename? It's because the | |
64 | SHA1 hash of: | |
65 | ||
66 | "blob" SP "6" NUL "sweet" LF | |
67 | ||
68 | is aa823728ea7d592acc69b36875a482cdf3fd5c8d, | |
69 | where SP is a space, NUL is a zero byte and LF is a linefeed. You can verify | |
70 | this by typing: | |
71 | ||
72 | $ printf "blob 6\000sweet\n" | sha1sum | |
73 | ||
74 | Git is 'content-addressable': files are not stored according to their filename, | |
75 | but rather by the hash of the data they contain, in a file we call a 'blob | |
76 | object'. We can think of the hash as a unique ID for a file's contents, so | |
77 | in a sense we are addressing files by their content. The initial "blob 6" is | |
78 | merely a header consisting of the object type and its length in bytes; it | |
79 | simplifies internal bookkeeping. | |
80 | ||
81 | Thus I could easily predict what you would see. The file's name is irrelevant: | |
82 | only the data inside is used to construct the blob object. | |
83 | ||
84 | You may be wondering what happens to identical files. Try adding copies of | |
85 | your file, with any filenames whatsoever. The contents of +.git/objects+ stay | |
86 | the same no matter how many you add. Git only stores the data once. | |
87 | ||
88 | By the way, the files within +.git/objects+ are compressed with zlib so you | |
89 | should not stare at them directly. Filter them through | |
90 | http://www.zlib.net/zpipe.c[zpipe -d], or type: | |
91 | ||
92 | $ git cat-file -p aa823728ea7d592acc69b36875a482cdf3fd5c8d | |
93 | ||
94 | which pretty-prints the given object. | |
95 | ||
96 | ==== Trees ==== | |
97 | ||
98 | But where are the filenames? They must be stored somewhere at some stage. | |
99 | Git gets around to the filenames during a commit: | |
100 | ||
101 | $ git commit # Type some message. | |
102 | $ find .git/objects -type f | |
103 | ||
104 | You should now see 3 objects. This time I cannot tell you what the 2 new files are, as it partly depends on the filename you picked. We'll proceed assuming you chose "rose". If you didn't, you can rewrite history to make it look like you did: | |
105 | ||
106 | $ git filter-branch --tree-filter 'mv YOUR_FILENAME rose' | |
107 | $ find .git/objects -type f | |
108 | ||
109 | Now you should see the file | |
110 | +.git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9+, because this is the | |
111 | SHA1 hash of its contents: | |
112 | ||
113 | "tree" SP "32" NUL "100644 rose" NUL 0xaa823728ea7d592acc69b36875a482cdf3fd5c8d | |
114 | ||
115 | Check this file does indeed contain the above by typing: | |
116 | ||
117 | $ echo 05b217bb859794d08bb9e4f7f04cbda4b207fbe9 | git cat-file --batch | |
118 | ||
119 | With zpipe, it's easy to verify the hash: | |
120 | ||
121 | $ zpipe -d < .git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9 | sha1sum | |
122 | ||
123 | Hash verification is trickier via cat-file because its output contains more | |
124 | than the raw uncompressed object file. | |
125 | ||
126 | This file is a 'tree' object: a list of tuples consisting of a file | |
127 | type, a filename, and a hash. In our example, the file type is "100644", which | |
128 | means "rose" is a normal file, and the hash is the blob object that contains | |
129 | the contents of "rose". Other possible file types are executables, symlinks or | |
130 | directories. In the last case, the hash points to a tree object. | |
131 | ||
132 | If you ran filter-branch, you'll have old objects you no longer need. Although | |
133 | they will be jettisoned automatically once the grace period expires, we'll | |
134 | delete them now to make our toy example easier to follow: | |
135 | ||
136 | $ rm -r .git/refs/original | |
137 | $ git reflog expire --expire=now --all | |
138 | $ git prune | |
139 | ||
140 | For real projects you should typically avoid commands like this, as you are | |
141 | destroying backups. If you want a clean repository, it is usually best to make | |
142 | a fresh clone. Also, take care when directly manipulating +.git+: what if a Git | |
143 | command is running at the same time, or a sudden power outage occurs? | |
144 | In general, refs should be deleted with *git update-ref -d*, | |
145 | though usually it's safe to remove +refs/original+ by hand. | |
146 | ||
147 | ==== Commits ==== | |
148 | ||
149 | We've explained 2 of the 3 objects. The third is a 'commit' object. Its | |
150 | contents depend on the commit message as well as the date and time it was | |
151 | created. To match what we have here, we'll have to tweak it a little: | |
152 | ||
153 | $ git commit --amend -m Shakespeare # Change the commit message. | |
154 | $ git filter-branch --env-filter 'export | |
155 | GIT_AUTHOR_DATE="Fri 13 Feb 2009 15:31:30 -0800" | |
156 | GIT_AUTHOR_NAME="Alice" | |
157 | GIT_AUTHOR_EMAIL="alice@example.com" | |
158 | GIT_COMMITTER_DATE="Fri, 13 Feb 2009 15:31:30 -0800" | |
159 | GIT_COMMITTER_NAME="Bob" | |
160 | GIT_COMMITTER_EMAIL="bob@example.com"' # Rig timestamps and authors. | |
161 | $ find .git/objects -type f | |
162 | ||
163 | You should now see | |
164 | +.git/objects/49/993fe130c4b3bf24857a15d7969c396b7bc187+ | |
165 | which is the SHA1 hash of its contents: | |
166 | ||
167 | "commit 158" NUL | |
168 | "tree 05b217bb859794d08bb9e4f7f04cbda4b207fbe9" LF | |
169 | "author Alice <alice@example.com> 1234567890 -0800" LF | |
170 | "committer Bob <bob@example.com> 1234567890 -0800" LF | |
171 | LF | |
172 | "Shakespeare" LF | |
173 | ||
174 | As before, you can run zpipe or cat-file to see for yourself. | |
175 | ||
176 | This is the first commit, so there are no parent commits, but later commits | |
177 | will always contain at least one line identifying a parent commit. | |
178 | ||
179 | ==== Indistinguishable From Magic ==== | |
180 | ||
181 | There's little else to say. We have just exposed the secret behind Git's | |
182 | powers. It seems too simple: it looks like you could mix together a few shell | |
183 | scripts and add a dash of C code to cook up the above in a matter of hours, | |
184 | mixing in lock files and fsyncs for robustness. In fact, this accurately | |
185 | describes the earliest versions of Git. Nonetheless, apart from ingenious | |
186 | packing tricks to save space, and ingenious indexing tricks to save time, we | |
187 | now know how Git deftly changes a filesystem into a database perfect for | |
188 | version control. | |
189 | ||
190 | For example, if any file within the object database is corrupted by a disk | |
191 | error, then its hash will no longer match, alerting us to the problem. By | |
192 | hashing hashes of other objects, we maintain integrity at all levels. Commits | |
193 | are atomic, that is, a commit can never only partially record changes: we can | |
194 | only compute the hash of a commit and store it in the database after we already | |
195 | have stored all relevant trees, blobs and parent commits. The object | |
196 | database is immune to unexpected interruptions such as power outages. | |
197 | ||
198 | We defeat even the most devious adversaries. Suppose somebody attempts to | |
199 | stealthily modify the contents of a file in an ancient version of a project. To | |
200 | keep the object database looking healthy, they must also change the hash of the | |
201 | corresponding blob object since it's now a different string of bytes. This | |
202 | means they'll have to change the hash of any tree object referencing the file, | |
203 | and in turn change the hash of all commit objects involving such a tree, in | |
204 | addition to the hashes of all the descendants of these commits. This implies the | |
205 | hash of the official head differs to that of the bad repository. By | |
206 | following the trail of mismatching hashes we can pinpoint the mutilated file, | |
207 | as well as the commit where it was first corrupted. | |
208 | ||
209 | In short, so long as the 20 bytes representing the last commit are safe, | |
210 | it's impossible to tamper with a Git repository. | |
211 | ||
212 | What about Git's famous features? Branching? Merging? Tags? | |
213 | Mere details. The current head is kept in the file +.git/HEAD+, | |
214 | which contains a hash of a commit object. The hash gets updated during a commit | |
215 | as well as many other commands. Branches are almost the same: they are files in | |
216 | +.git/refs/heads+. Tags too: they live in +.git/refs/tags+ but they | |
217 | are updated by a different set of commands. |
0 | == Appendix B: Translating This Guide == | |
1 | ||
2 | Clone the source, then create a directory corresponding to the target http://www.iana.org/assignments/language-subtag-registry[language's IETF tag]: see | |
3 | http://www.w3.org/International/articles/language-tags/Overview.en.php[the W3C article on internationalization]. For example, English is "en", Japanese is "ja", and Traditional Chinese is "zh-Hant". In the new directory, and translate the +txt+ files from the "en" subdirectory. | |
4 | ||
5 | For instance, to translate the guide into http://en.wikipedia.org/wiki/Klingon_language[Klingon], you might type: | |
6 | ||
7 | $ git clone git://repo.or.cz/gitmagic.git | |
8 | $ cd gitmagic | |
9 | $ mkdir tlh # "tlh" is the IETF language code for Klingon. | |
10 | $ cd tlh | |
11 | $ cp ../en/intro.txt . | |
12 | $ edit intro.txt # Translate the file. | |
13 | ||
14 | and so on for each text file. You can review your work incrementally: | |
15 | ||
16 | $ make LANG=tlh | |
17 | $ firefox book.html | |
18 | ||
19 | Commit your changes often, then let me know when they're ready. | |
20 | GitHub.com has an interface that facilitates this: fork the "gitmagic" project, | |
21 | push your changes, then ask me to merge. | |
22 | ||
23 | I like to have translations follow the above scheme so my scripts can produce | |
24 | HTML and PDF versions. Also, it conveniently keeps all the translations in the | |
25 | official repository. But please do whatever suits you best: for example, the | |
26 | Chinese translators used Google Docs. I'm happy as long as your work | |
27 | enables more people to access my work. |
0 | == Trucos Básicos == | |
1 | ||
2 | En lugar de sumergirte en un mar de comandos de Git, usa estos ejemplos elementales para mojarte los pies. A pesar de sus simplicidad, todos son útiles. | |
3 | De hecho, en mis primeros meses con Git nunca fui más allá del material en este capítulo. | |
4 | ||
5 | === Guardando Estados === | |
6 | ||
7 | Estás a punto de intentar algo drástico? Antes de hacerlo, toma una instantánea de todos los archivos en el directorio actual con: | |
8 | ||
9 | $ git init | |
10 | $ git add . | |
11 | $ git commit -m "My first backup" | |
12 | ||
13 | Ahora, si tu edición se vuelve irrecuperable, ejecuta: | |
14 | ||
15 | $ git reset --hard | |
16 | ||
17 | para volver a donde estabas. Para volver a salvar el estado: | |
18 | ||
19 | $ git commit -a -m "Otro respaldo" | |
20 | ||
21 | ==== Agrega, Elimina, Renombra ==== | |
22 | ||
23 | El comando anterior solo seguirá la pista de los archivos que estaban presentes la primera vez que ejecutaste *git add*. Si añades nuevos archivos o subdirectorios, deberás decirle a Git: | |
24 | ||
25 | $ git add ARCHIVOSNUEVOS... | |
26 | ||
27 | De manera similar, si quieres que Git se olvide de determinados archivos, porque (por ejemplo) los borraste: | |
28 | ||
29 | $ git rm ARCHIVOSVIEJOS... | |
30 | ||
31 | Renombrar un archivo es lo mismo que eliminar el nombre anterior y agregar el nuevo. También puedes usar *git mv* que tiene la misma sintaxis que el comando *mv*. Por ejemplo: | |
32 | ||
33 | $ git mv ARCHIVOVIEJO ARCHIVONUEVO | |
34 | ||
35 | === Deshacer/Rehacer Avanzado === | |
36 | ||
37 | Algunas veces solo quieres ir hacia atrás y olvidarte de todos los cambios a partir de cierto punto, porque estaban todos mal. Entonces: | |
38 | ||
39 | $ git log | |
40 | ||
41 | te muestra una lista de commits recientes, y sus hashes SHA1. A continuación, escribe: | |
42 | ||
43 | $ git reset --hard SHA1_HASH | |
44 | ||
45 | para recuperar el estado de un commit dado, y borrar para siempre cualquier recuerdo de commits más nuevos. | |
46 | ||
47 | Otras veces, quieres saltar a un estado anterior temporalmente. En ese caso escribe: | |
48 | ||
49 | $ git checkout SHA1_HASH | |
50 | ||
51 | Esto te lleva atrás en el tiempo, sin tocar los commits más nuevos. Sin embargo, como en los viajes en el tiempo de las películas de ciencia ficción, estarás en una realidad alternativa, porque tus acciones fueron diferentes a las de la primera vez. | |
52 | ||
53 | Esta realidad alternativa se llama 'branch' (rama), y <<branch,tendremos más cosas para decir al respecto luego>>. Por ahora solo recuerda que | |
54 | ||
55 | $ git checkout master | |
56 | ||
57 | te llevará al presente. También, para que Git no se queje, siempre haz un commit o resetea tus cambios antes de ejecutar checkout. | |
58 | ||
59 | Para retomar la analogía de los videojuegos: | |
60 | ||
61 | - *`git reset \--hard`*: carga un juego viejo y borra todos los que son mas nuevos que el que acabas de cargar. | |
62 | ||
63 | - *`git checkout`*: carga un juego viejo, pero si continúas jugando, el estado del juego se desviará de los juegos que salvaste la primera vez. Cualquierpartido nuevo que guardes, terminará en una branch separada, representando la realidad alternativa a la que entraste. <<branch,Luego nos encargaremos de esto>> | |
64 | ||
65 | Puedes elegir el restaurar solo archivos o directorios en particular, al agregarlos al final del comando: | |
66 | You can choose only to restore particular files and subdirectories by appending them after the command: | |
67 | ||
68 | $ git checkout SHA1_HASH algun.archivo otro.archivo | |
69 | ||
70 | Ten cuidado, esta forma de *checkout* puede sobreescribir archivos sin avisar. Para prevenir accidentes, haz commit antes de ejecutar cualquier comando de checkout, especialmente cuando estás aprendiendo a usar Git. En general, cuando te sientas inseguro del resultado de una operación, sea o no de Git, ejecuta antes *git commit -a*. | |
71 | ||
72 | ¿No te gusta cortar y pegar hashes? Entonces usa: | |
73 | ||
74 | $ git checkout :/"Mi primer r" | |
75 | ||
76 | para saltar al commit que comienza con el mensaje dado. | |
77 | ||
78 | También puedes pedir el 5to estado hacia atrás: | |
79 | ||
80 | $ git checkout master~5 | |
81 | ||
82 | ==== Revirtiendo ==== | |
83 | ||
84 | En una corte, los eventos pueden ser eliminados del registro. Igualmente, puedes elegir commits específicos para deshacer. | |
85 | ||
86 | $ git commit -a | |
87 | $ git revert SHA1_HASH | |
88 | ||
89 | va a deshacer solo el commit con el hash dado. Ejecutar *git log* revela que el revert es registrado como un nuevo commit. | |
90 | ||
91 | === Descargando Archivos === | |
92 | ||
93 | Obtén una copia de un proyecto administrado por git escribiendo: | |
94 | ||
95 | $ git clone git://servidor/ruta/a/los/archivos | |
96 | ||
97 | Por ejemplo, para bajar todos los archivos que usé para crear este sitio: | |
98 | ||
99 | $ git clone git://git.or.cz/gitmagic.git | |
100 | ||
101 | Pronto tendremos más para decir acerca del comando *clone*. | |
102 | ||
103 | === Lo Más Nuevo === | |
104 | ||
105 | Si ya descargaste una copia de un proyecto usando *git clone*, puedes actualizarte a la última versión con: | |
106 | ||
107 | $ git pull | |
108 | ||
109 | === Publicación Al Instante === | |
110 | ||
111 | Imagina que has escrito un script que te gustaría compartir con otros. Puedes decirles que simplemente lo bajen de tu computadora, pero si lo hacen mientras estás haciendo una modificación, pueden terminar en problemas. Es por esto que existen los ciclos de desarrollo. Los programadores pueden trabajar en un proyecto de manera frecuente, pero solo hacen público el código cuando consideran que es presentable. | |
112 | ||
113 | Para hacer esto con Git, en el directorio donde guardas tu script: | |
114 | ||
115 | $ git init | |
116 | $ git add . | |
117 | $ git commit -m "Primer lanzamiento" | |
118 | ||
119 | Entonces puedes decirle a tus usuarios que ejecuten: | |
120 | ||
121 | $ git clone tu.maquina:/ruta/al/script | |
122 | ||
123 | para descargar tu script. Esto asume que tienen acceso por ssh. Si no es así, ejecuta *git daemon* y dile a tus usuarios que usen: | |
124 | ||
125 | $ git clone git://tu.maquina/ruta/al/script | |
126 | ||
127 | De ahora en más, cada vez que tu script esté listo para el lanzamiento, escribe: | |
128 | ||
129 | $ git commit -a -m "Siguiente lanzamiento" | |
130 | ||
131 | y tus usuarios puede actualizar su versión yendo al directorio que tiene tu script y ejecutando: | |
132 | ||
133 | $ git pull | |
134 | ||
135 | Tus usuarios nunca terminarán usando una versión de tu script que no quieres que vean. Obviamente este truco funciona para lo que sea, no solo scripts. | |
136 | ||
137 | === Que es lo que hice? === | |
138 | ||
139 | Averigua que cambios hiciste desde el último commit con: | |
140 | ||
141 | $ git diff | |
142 | ||
143 | O desde ayer: | |
144 | ||
145 | $ git diff "@{yesterday}" | |
146 | ||
147 | O entre una versión en particular y 2 versiones hacia atrás: | |
148 | ||
149 | $ git diff SHA1_HASH "master~2" | |
150 | ||
151 | En cado caso la salida es un patch (parche) que puede ser aplicado con *git apply* | |
152 | Para ver cambios desde hace 2 semanas, puedes intentar: | |
153 | ||
154 | $ git whatchanged --since="2 weeks ago" | |
155 | ||
156 | Usualmente recorro la historia con http://sourceforge.net/projects/qgit[qgit] | |
157 | , dada su interfaz pulida y fotogénica, o http://jonas.nitro.dk/tig/[tig], una interfaz en modo texto | |
158 | que funciona bien a través conexiones lentas. Como alternativa, puedes instalar un servidor web, | |
159 | ejecutar *git instaweb* y utilizar cualquier navegador web. | |
160 | ||
161 | === Ejercicio === | |
162 | ||
163 | Siendo A, B, C, y D cuatro commits sucesivos, donde B es el mismo que A pero con algunos archivos eliminados. Queremos volver a agregar los archivos en D pero no en B. ¿Cómo podemos hacer esto? | |
164 | ||
165 | Hay por lo menos tres soluciones. Asumiendo que estamos en D: | |
166 | ||
167 | 1. La diferencia entre A y B son los archivos eliminados. Podemos crear un patch representando esta diferencia y aplicarlo: | |
168 | ||
169 | $ git diff B A | git apply | |
170 | ||
171 | 2. Como en A tenemos los archivos guardados, podemos recuperarlos : | |
172 | ||
173 | $ git checkout A ARCHIVOS... | |
174 | ||
175 | 3. Podemos ver el pasaje de A a B como un cambio que queremos deshacer: | |
176 | ||
177 | $ git revert B | |
178 | ||
179 | ¿Cuál alternativa es la mejor? Cualquiera que prefieras. Es fácil obtener lo que quieres con Git, y normalmente hay varias formas de hacerlo. |
0 | == Magia Con Los Branches == | |
1 | ||
2 | El hacer branches (ramificar) y merges (unir) de manera instantánea, son dos de las prestaciones más letales de Git. | |
3 | ||
4 | *Problema*: Factores externos necesitan inevitablemente de cambios de contexto. | |
5 | Un bug severo se manifiesta en la última versión sin previo aviso. El plazo para | |
6 | alguna prestación se acorta. Un desarrollador que tiene que ayudar en una sección indispensable | |
7 | del proyecto está por tomar licencia. En cualquier caso, debes soltar abruptamente lo que estás haciendo | |
8 | y enfocarte en una tarea completamente diferente. | |
9 | ||
10 | Interrumpir tu línea de pensamiento puede ser negativo para tu productividad, y cuanto más engorroso sea el cambiar contextos, mayor es la pérdida. Con los sistemas centralizados, debemos descargar una nueva copia. Los sistemas distribuídos se comportan mejor, dado que podemos clonar la versión deseada localmente. | |
11 | ||
12 | Pero el clonar igual implica copiar todo el directorio junto con toda la historia hasta el momento. Aunque Git reduce el costousando hard links y el compartir archivos, los archivos del proyecto deben ser recreados enteramente en el nuevo directorio. | |
13 | ||
14 | *Solución*: Git tiene una mejor herramienta para estas situaciones que es mucho más rápida y eficiente en tamaño que clonar *git branch*. | |
15 | ||
16 | Con esta palabra mágica, los archivos en tu directorio se transforman súbitamente de una versión en otra. Esta transformación puede hacer más que simplemente ir hacia atrás o adelante en la historia. Tus archivos pueden mutar desde la última versión lanzada, a la versión experimental, a la versión en desarrollo, a la versión de un amigo y así sucesivamente. | |
17 | ||
18 | === La Tecla Del Jefe === | |
19 | ||
20 | ¿Alguna vez jugaste uno de esos juegos donde con solo presionar un botón ("la tecla del jefe"), la pantalla inmediatamente muestra una hoja de cálculo o algo así? La idea es que si el jefe entra a la oficina mientras estás en el juego, lo puedes esconder rápidamente. | |
21 | ||
22 | En algún directorio: | |
23 | ||
24 | $ echo "Soy más inteligente que mi jefe" > miarchivo.txt | |
25 | $ git init | |
26 | $ git add . | |
27 | $ git commit -m "Commit inicial" | |
28 | ||
29 | Creamos un repositorio de Git que guarda un archivo de texto conteniendo un mensaje dado. Ahora escribe: | |
30 | ||
31 | $ git checkout -b jefe # nada parece cambiar luego de esto | |
32 | $ echo "Mi jefe es más inteligente que yo" > miarchivo.txt | |
33 | $ git commit -a -m "Otro commit" | |
34 | ||
35 | Parecería que sobreescribimos nuestro archivo y le hicimos commit. Pero es una ilusión. Escribe: | |
36 | ||
37 | $ git checkout master # cambia a la versión original del archivo | |
38 | ||
39 | y presto! El archivo de texto es restaurado. Y si el jefe decide investigar este directorio, escribimos: | |
40 | ||
41 | $ git checkout jefe # cambia a la versión adecuada para los ojos del jefe | |
42 | ||
43 | Puedes cambiar entre ambas versiones del archivo cuantas veces quieras, y hacer commit en ambas de manera independiente. | |
44 | ||
45 | === Trabajo Sucio === | |
46 | ||
47 | [[branch]] | |
48 | Supongamos que estás trabajando en alguna prestación, y que por alguna razón, necesitas volver a una versión vieja y poner temporalmente algunos "print" para ver como funciona algo. Entonces: | |
49 | ||
50 | $ git commit -a | |
51 | $ git checkout SHA1_HASH | |
52 | ||
53 | Ahora puedes agregar cualquier código temporal horrible por todos lados. | |
54 | Incluso puedes hacer commit de estos cambios. Cuando termines, | |
55 | ||
56 | $ git checkout master | |
57 | ||
58 | para volver a tu trabajo original. Observa que arrastrarás cualquier cambio del que no hayas hecho commit. | |
59 | ||
60 | ¿Que pasa si quisieras cambiar los cambios temporales? Facil: | |
61 | ||
62 | $ git checkout -b sucio | |
63 | ||
64 | y haz commit antes de volver a la branch master. Cuando quieras volver a los cambios sucios, simplemente escribe: | |
65 | ||
66 | $ git checkout sucio | |
67 | ||
68 | Mencionamos este comando en un capítulo anterior, cuando discutíamos sobre cargar estados antiguos. Al fin podemos contar toda la historia:los archivos cambian al estado pedido, pero debemos dejar la branch master. Cualquier commit de aquí en adelante, llevan tus archivos por un nuevo camino, el podrá ser nombrado posteriormente. | |
69 | ||
70 | En otras palabras, luego de traer un estado viejo, Git automáticamente te pone en una nueva branch sin nombre, la cual puede ser nombrada y salvada con *git checkout -b*. | |
71 | ||
72 | === Arreglos Rápidos === | |
73 | ||
74 | Estás en medio de algo cuando te piden que dejes todo y soluciones un bug recién descubierto: | |
75 | ||
76 | $ git commit -a | |
77 | $ git checkout -b arreglos SHA1_HASH | |
78 | ||
79 | Luego, una vez que solucionaste el bug: | |
80 | ||
81 | $ git commit -a -m "Bug arreglado" | |
82 | $ git push # al repositorio central | |
83 | $ git checkout master | |
84 | ||
85 | y continúa con el trabajo en tu tarea original. | |
86 | ||
87 | === Flujo De Trabajo Ininterrumpido === | |
88 | ||
89 | Algunos proyectos requieren que tu código sea evaluado antes de que puedas subirlo. Para hacer la vida más fácil para aquellos que revisan tu código, si tienes algún cambio grande para hacer, puedes partirlo en dos o mas partes, y hacer que cada parte sea evaluada por separado. | |
90 | ||
91 | ¿Que pasa si la segunda parte no puede ser escrita hasta que la primera sea aprobada y subida? En muchos sistemas de control de versiones, deberías enviar primero el código a los evaluadores, y luego esperar hasta que esté aprobado antes de empezar con la segunda parte. | |
92 | ||
93 | En realidad, eso no es del todo cierto, pero en estos sistemas, editar la Parte II antes de subir la Parte I involucra sufrimiento e infortunio. En Git, los branches y merges son indoloros (un termino técnico que significa rápidos y locales). Entonces, luego de que hayas hecho commit de la primera parte y la hayas enviado a ser revisada: | |
94 | ||
95 | $ git checkout -b parte2 | |
96 | ||
97 | Luego, escribe la segunda parte del gran cambio sin esperar a que la primera sea aceptada. Cuando la primera parte sea aprobada y subida, | |
98 | ||
99 | $ git checkout master | |
100 | $ git merge parte2 | |
101 | $ git branch -d parte2 # ya no se necesita esta branch | |
102 | ||
103 | y la segunda parte del cambio está lista para la evaluación. | |
104 | ||
105 | ¡Pero esperen! ¿Qué pasa si no fuera tan simple? Digamos que tuviste un error en la primera parte, el cual hay que corregir antes de subir los cambios. ¡No hay problema! Primero, vuelve a la branch master usando | |
106 | ||
107 | $ git checkout master | |
108 | ||
109 | Soluciona el error en la primera parte del cambio y espera que sea aprobado. Si no lo es, simplemente repite este paso. Probablemente quieras hacer un merge de la versión arreglada de la Parte I con la Parte II: | |
110 | ||
111 | $ git checkout parte2 | |
112 | $ git merge master | |
113 | ||
114 | Ahora es igual que lo anterior. Una vez que la primera parte sea aprobada: | |
115 | ||
116 | $ git checkout master | |
117 | $ git merge parte2 | |
118 | $ git branch -d parte2 | |
119 | ||
120 | y nuevamente, la segunda parte está lista para ser revisada. | |
121 | ||
122 | Es fácil extender este truco para cualquier cantidad de partes. | |
123 | ||
124 | === Reorganizando Una Mezcla === | |
125 | ||
126 | Quizás quieras trabajar en todos los aspectos de un proyecto sobre la misma branch. Quieres dejar los trabajos-en-progreso para ti y quieres que otros vean tus commits solo cuando han sido pulcramente organizados. Inicia un par de branches: | |
127 | ||
128 | $ git checkout -b prolijo | |
129 | $ git checkout -b mezcla | |
130 | ||
131 | A continuación, trabaja en lo que sea: soluciona bugs, agrega prestaciones, agrega código temporal o lo que quieras, haciendo commits seguidos a medida que avanzas. Entonces: | |
132 | ||
133 | $ git checkout prolijo | |
134 | $ git cherry-pick SHA1_HASH | |
135 | ||
136 | aplica un commit dado a la branch "prolijo". Con cherry-picks apropiados, puedes construir una rama que contenga solo el código permanente, y los commits relacionados juntos en un grupo. | |
137 | ||
138 | === Administrando branches === | |
139 | ||
140 | Lista todas las branches escribiendo: | |
141 | ||
142 | $ git branch | |
143 | ||
144 | Siempre hay una branch llamada "master", y es en la que comienzas por defecto. | |
145 | Algunos aconsejan dejar la rama "master" sin tocar y el crear nuevas branches | |
146 | para tus propios cambios. | |
147 | ||
148 | Las opciones *-d* y *-m* te permiten borrar y mover (renombrar) branches. | |
149 | Mira en *git help branch* | |
150 | ||
151 | La branch "master" es una convención útil. Otros pueden asumir que tu | |
152 | repositorio tiene una branch con este nombre, y que contiene la versión | |
153 | oficial del proyecto. Puedes renombrar o destruir la branch "master", pero | |
154 | también podrías respetar esta costumbre. | |
155 | ||
156 | === Branches Temporales === | |
157 | ||
158 | Después de un rato puedes notar que estás creando branches de corta vida | |
159 | de manera frecuente por razones similares: cada branch sirve simplemente | |
160 | para salvar el estado actual y permitirte saltar a un estado anterior | |
161 | para solucionar un bug de alta prioridad o algo. | |
162 | ||
163 | Es análogo a cambiar el canal de la TV temporalmente, para ver que otra | |
164 | cosa están dando. Pero en lugar de apretar un par de botones, tienes que | |
165 | crear, hacer checkout y eliminar branches y commits temporales. Por suerte, | |
166 | Git tiene un aatajo que es tan conveniente como un control remoto de TV: | |
167 | ||
168 | $ git stash | |
169 | ||
170 | Esto guarda el estado actual en un lugar temporal (un 'stash') y restaura | |
171 | el estado anterior. Tu directorio de trabajo se ve idéntico a como estaba | |
172 | antes de que comenzaras a editar, y puedes solucionar bugs, traer cambios | |
173 | desde otros repositorios, etc. Cuando quieras volver a los cambios | |
174 | del stash, escribe: | |
175 | ||
176 | $ git stash apply # Puedes necesitar corregir conflictos | |
177 | ||
178 | Puedes tener varios stashes, y manipularlos de varias maneras. Mira *git help stash*. | |
179 | Como es de imaginar, Git mantiene branches de manera interna para lograr este truco mágico. | |
180 | ||
181 | === Trabaja como quieras === | |
182 | ||
183 | Aplicaciones como http://www.mozilla.com/[Mozilla Firefox] permiten tener varias pestañas y ventanas abiertas. Cambiar de pestaña te da diferente contenido en la misma ventana. Los branches en git son como pestañas para tu directorio de trabajo. Siguiendo esta analogía, el clonar es como abrir una nueva ventana. La posibilidad de ambas cosas es lo que mejora la experiencia del usuario. | |
184 | ||
185 | En un nivel más alto, varios window managers en Linux soportan múltiples escritorios. | |
186 | Usar branches en Git es similar a cambiar a un escritorio diferente, mientras | |
187 | clonar es similar a conectar otro monitor para ganar un nuevo escritorio. | |
188 | ||
189 | Otro ejemplo es el programa http://www.gnu.org/software/screen/[*screen*]. Esta joya permite crear, destruir e intercambiar entre varias sesiones de terminal sobre la misma terminal. En lugar de abrir terminales nuevas (clone), puedes usar la misma si ejecutas *screen* (branch). De hecho, puedes hacer mucho más con *screen*, pero eso es un asunto para otro manual. | |
190 | ||
191 | Usar clone, branch y merge, es rápido y local en Git, animándote a usar la combinación que más te favorezca. Git te permite trabajar exactamente como prefieras. |
0 | == Clonando == | |
1 | ||
2 | En sistemas de control de versiones antiguos, checkout es la operación standard para obtener archivos. Obtienes un conjunto de archivos en estado guardado que solicistaste. | |
3 | ||
4 | En Git, y otros sistemas de control de versiones distribuídos, clonar es la operación standard. Para obtener archivos se crea un clon de un repositorio entero. En otras palabras, practicamente se crea una copia idéntica del servidor central. Todo lo que se pueda hacer en el repositorio principal, también podrás hacerlo. | |
5 | ||
6 | === Sincronizar Computadoras === | |
7 | ||
8 | Este es el motivo por el que usé Git por primera vez. Puedo tolerar hacer tarballs o usar *rsync* para backups y sincronización básica. Pero algunas veces edito en mi laptop, otras veces en mi desktop, y ambas pueden no haberse comunicado en el medio. | |
9 | ||
10 | Inicializa un repositorio de Git y haz haz commit de tus archivos en una máquina, luego en la otra: | |
11 | ||
12 | $ git clone otra.computadora:/ruta/a/archivos | |
13 | ||
14 | para crear una segunda copia de los archivos y el repositorio Git. De ahora en más, | |
15 | ||
16 | $ git commit -a | |
17 | $ git pull otra.computadora:/ruta/a/archivos HEAD | |
18 | ||
19 | va a traer (pull) el estado de los archivos desde la otra máquina hacia la que estás trabajando. Si haz hecho cambios que generen conflictos en un archivo, Git te va a avisar y deberías hacer commit luego de resolverlos. | |
20 | ||
21 | === Control Clásico de Fuentes === | |
22 | ||
23 | Inicializa un repositorio de Git para tus archivos: | |
24 | ||
25 | $ git init | |
26 | $ git add . | |
27 | $ git commit -m "Commit Inicial" | |
28 | ||
29 | En el servidor central, inicializa un repositorio vacío de Git con algún nombre, | |
30 | y abre el Git daemon si es necesario: | |
31 | ||
32 | $ GIT_DIR=proj.git git init | |
33 | $ git daemon --detach # podría ya estar corriendo | |
34 | ||
35 | Algunos servidores publicos, como http://repo.or.cz[repo.or.cz], tienen un método diferente para configurar el repositorio inicialmente vacío de Git, como llenar un formulario en una página. | |
36 | ||
37 | Empuja (push) tu proyecto hacia el servidor central con: | |
38 | ||
39 | $ git push git://servidor.central/ruta/al/proyecto.git HEAD | |
40 | ||
41 | Ya estamos listos. Para copiarse los fuentes, un desarrollador escribe: | |
42 | ||
43 | $ git clone git://servidor.central/ruta/al/proyecto.git | |
44 | ||
45 | Luego de hacer cambios, el código en envía al servidor central con: | |
46 | ||
47 | $ git commit -a | |
48 | $ git push | |
49 | ||
50 | Si hubo actualizaciones en el servidor principal, la última versión debe ser traída antes de enviar lo nuevo. Para sincronizar con la última versión: | |
51 | ||
52 | $ git commit -a | |
53 | $ git pull | |
54 | ||
55 | === Bifurcando (fork) un proyecto === | |
56 | ||
57 | ¿Harto de la forma en la que se maneja un proyecto?¿Crees que podrías hacerlo mejor? Entonces en tu servidor: | |
58 | ||
59 | $ git clone git://servidor.principal/ruta/a/archivos | |
60 | ||
61 | Luego avísale a todos de tu fork del proyecto en tu servidor. | |
62 | ||
63 | Luego, en cualquier momento, puedes unir (merge) los cambios del proyecto original con: | |
64 | ||
65 | $ git pull | |
66 | ||
67 | === Respaldos Definitivos === | |
68 | ||
69 | ¿Quieres varios respaldos redundantes a prueba de manipulación y geográficamente diversos? Si tu proyecto tiene varios desarrolladores, ¡no hagas nada! Cada clon de tu código es un backup efectivo. No sólo del estado actual, sino que también de la historia completa de tu proyecto. Gracias al hashing criptográfico, si hay corrupción en cualquiera de los clones, va a ser detectado tan pronto como intente comunicarse con otros. | |
70 | ||
71 | Si tu proyecto no es tan popular, busca tantos servidores como puedas para hospedar tus clones. | |
72 | ||
73 | El verdadero paranoico debería siempre escribir el último hash SHA1 de 20-bytes de su HEAD en algún lugar seguro. Tiene que ser seguro, no privado. Por ejemplo, publicarlo en un diario funcionaría bien, porque es difícil para un atacante el alterar cada copia de un diario. | |
74 | ||
75 | === Multitask A La Velocidad De La Luz === | |
76 | ||
77 | Digamos que quieres trabajar en varias prestaciones a la vez. Haz commit de tu proyecto y ejecuta: | |
78 | ||
79 | $ git clone . /un/nuevo/directorio | |
80 | ||
81 | Git se aprovecha de los hard links y de compartir archivos de la manera mas segura posible para crear este clon, por lo que estará listo en un segundo, y podrás trabajar en dos prestaciones independientes de manera simultánea. Por ejemplo, puedes editar un clon mientras el otro está compilando. | |
82 | ||
83 | En cualquier momento, puedes hacer commit y pull de los cambios desde el otro clon. | |
84 | ||
85 | $ git pull /el/otro/clon HEAD | |
86 | ||
87 | === Control Guerrillero De Versiones === | |
88 | ||
89 | ¿Estás trabajando en un proyecto que usa algún otro sistema de control de versiones y extrañas mucho a Git? Entonces inicializa un repositorio de Git en tu directorio de trabajo. | |
90 | ||
91 | $ git init | |
92 | $ git add . | |
93 | $ git commit -m "Commit Inicial" | |
94 | ||
95 | y luego clónalo: | |
96 | ||
97 | $ git clone . /un/nuevo/directorio | |
98 | ||
99 | Ahora debes trabajar en el nuevo directorio, usando Git como te sea más cómodo. Cada tanto, querrás sincronizar con los demás, en ese caso, ve al directorio original, sincroniza usando el otro sistema de control de versiones y escribe: | |
100 | ||
101 | $ git add . | |
102 | $ git commit -m "Sincronizo con los demás" | |
103 | ||
104 | Luego ve al nuevo directorio y escribe: | |
105 | ||
106 | $ git commit -a -m "Descripción de mis cambios" | |
107 | $ git pull | |
108 | ||
109 | El procedimiento para pasarle tus cambios a los demás depende de cuál es tu otro sistema de control de versiones. El nuevo directorio contiene los archivos con tus cambios. Ejecuta los comandos que sean necesarios para subirlos al repositorio central del otro sistema de control de versiones. | |
110 | ||
111 | El comando *git svn* automatiza lo anterior para repositorios de Subversion, | |
112 | y también puede ser usado para http://google-opensource.blogspot.com/2008/05/export-git-project-to-google-code.html[exportar un proyecto de Git a un repositorio de Subversion]. |
0 | == Introducción == | |
1 | ||
2 | Voy a usar una analogía para explicar el control de versiones. Mira http://es.wikipedia.org/wiki/Control_de_versiones[el artículo de wikipedia sobre control de versiones] para una explicación más cuerda. | |
3 | ||
4 | === Trabajar Es Jugar === | |
5 | ||
6 | He jugado juegos de PC casi toda mi vida. En cambio, empecé a usar sistemas de control de versiones siendo adulto. Sospecho que no soy el único, y comparar ambas cosas puede hacer que estos conceptos sean más fáciles de explicar y entender. | |
7 | ||
8 | Piensa en editar tu código o documento, o lo que sea, como si fuera jugar un juego. Una vez que progresaste mucho, te gustaría guardar. Para lograrlo, haces click en el botón de "Guardar" en tu editor de confianza. | |
9 | ||
10 | Pero esto va a sobreescribir tu versión antigua. Es como esos viejos juegos que solo tenían un slot para guardar: se podía guardar, pero nunca podías volver a un estado anterior. Esto era una pena, porque tu versión anterior podía haber estado justo en una parte que era particularmente divertida, y podías querer volver a jugarla algún día. O peor aún, tu partida actual está en un estado donde es imposible ganar, y tienes que volver a empezar. | |
11 | ||
12 | === Control De Versiones === | |
13 | ||
14 | Cuando estás editando, puedes "Guardar Como..." un archivo diferente, o copiar el archivo a otro lugar antes de guardar si quieres probar versiones viejas. También puedes usar compresión para ahorrar espacio. Esta es una forma primitiva y muy trabajosa de control de versiones. Los videojuegos han mejorado esto hace ya tiempo, muchas veces permitiendo guardar en varios slots, fechados automáticamente. | |
15 | ||
16 | Hagamos que el problema sea un poco más complejo. Imagina que tienes un montón de archivos que van juntos, como el código fuente de un proyecto, o archivos para un sitio web. Ahora, si quieres mantener una vieja versión, debes archivar un directorio completo. Tener muchar versiones a mano es inconveniente y rápidamente se vuelve costoso. | |
17 | ||
18 | Con algunos juegos, una partida guardada en realidad consiste de un directorio lleno de archivos. Estos videojuegos ocultan este detalle del jugador y presentan una interfaz conveniente para administrar diferentes versiones de este directorio. | |
19 | ||
20 | Los sistemas de control de versiones no son diferentes. Todos tienen lindas interfaces para administrar un directorio de cosas. Puedes guardar el estado del directorio tantas veces como quieras, y tiempo después puedes cargar cualquiera de los estados guardados. A diferencia de la mayoría de los juegos, normalmente estos sistemas son inteligentes en cuanto la conservación del espacio. Por lo general, solo algunos pocos archivos cambian de versión a versión, y no es un gran cambio. Guardar las diferencias en lugar de nuevas copias ahorra espacio. | |
21 | ||
22 | === Control Distribuído === | |
23 | ||
24 | Ahora imagina un juego muy difícil. Tan difícil para terminar, que muchos jugadores experientes alrededor del mundo deciden agruparse e intercambiar sus juegos guardados para intentar terminarlo. Los "Speedruns" son ejemplos de la vida real: los jugadores se especializan en diferents niveles del mismo juego y colaboran para lograr resultados sorprendentes. | |
25 | ¿Cómo armarías un sistema para que puedan descargar las partidas de los otros de manera simple? ¿Y para que suban las nuevas? | |
26 | ||
27 | Antes, cada proyecto usaba un control de versiones centralizado. Un servidor en algún lado contenía todos los juegos salvados. Nadie más los tenía. Cada jugador tenía a lo sumo un un par de juegos guardados en su máquina. Cuando un jugador quería progresar, obtenía la última versión del servidor principal, jugaba un rato, guardaba y volvía a subir al servidor para que todos los demás pudieran usarlo. | |
28 | ||
29 | ¿Qué pasa si un jugador quería obtener un juego anterior por algún motivo? Tal vez el juego actual está en un estado donde es imposible ganar, porque alguien olvidó obtener un objeto antes de pasar el nivel tres, por que que se quiere obtener el último juego guardado donde todavía es posible completarlo. O tal vez quieren comparar dos estados antiguos, para ver cuánto trabajo hizo un jugador en particular. | |
30 | ||
31 | Puede haber varias razones para querer ver una revisión antigua, pero el resultado es siempre el mismo. Tienen que pedirle esa vieja partida al servidor central. Mientras mas juegos guardados se quieran, más se necesita esa comunicación. | |
32 | ||
33 | La nueva generación de sistemas de control de versiones, de la cual Git es miembro, se conoce como sistemas distribuídos, y se puede pensar en ella como una generalización de sistemas centralizados. Cuando los jugadores descargan del servidor central, obtienen todos los juegos guardados, no solo el último. Es como si tuvieran un mirror del servidor central. | |
34 | ||
35 | Esta operación inicial de clonado, puede ser cara, especialmente si el historial es largo, pero a la larga termina siendo mejor. Un beneficio inmediato es que cuando se quiere una versión vieja por el motivo que sea, la comunicación con el servidor es innecesaria. | |
36 | ||
37 | ==== Una Tonta Superstición ==== | |
38 | ||
39 | Una creencia popular errónea es que los sistemas distribuídos son poco apropiados para proyectos que requieren un repositorio central oficial. Nada podría estar más lejos de la verdad. Fotografiar a alguien no hace que su alma sea robada, clonar el repositorio central no disminuye su importancia. | |
40 | ||
41 | Una buena aproximación inicial, es que cualquier cosa que se puede hacer con un sistema de control de versiones centralizado, se puede hacer mejor con un sistema de versiones distribuído que esté bien diseñado. Los recursos de red son simplemente más costosos que los recursos locales. Aunque luego veremos que hay algunas desventajas para un sistema distribuído, hay menos probabilidad de hacer comparaciones erroneas al tener esto en cuenta. | |
42 | ||
43 | Un proyecto pequeño, puede necesitar solo una fracción de de las características que un sistema así ofrece. Pero, ¿usarías números romanos si solo necesitas usar números pequeños?. Además, tu proyecto puede crecer más allá de tus expectativas originales. Usar Git desde el comienzo, es como llevar una navaja suiza, aunque solo pretendas usarla para abrir botellas. El día que necesites desesperadamente un destornillador, vas a agradecer el tener más que un simple destapador. | |
44 | ||
45 | === Conflictos al fusionar === | |
46 | ||
47 | Para este tema, habría que estirar demasiado nuestra analogía con un videojuego. En lugar de eso, esta vez consideremos editar un documento. | |
48 | ||
49 | Supongamos que Alice inserta una línea al comienzo de un archivo, y Bob agrega una línea al final de su copia. Ambos suben sus cambios. La mayoría de los sistemas automáticamente van a deducir un accionar razonable: aceptar y hacer merge (Nota del Traductor: fusionar en inglés) de los cambios, para que tanto la edición de Alice como la de Bob sean aplicadas. | |
50 | ||
51 | Ahora supongamos que Alice y Bob han hecho ediciones distintas sobre la misma línea. Entonces es imposible resolver el conflicto sin intervención humana.Se le informa a la segunda persona en hacer upload que hay un conflicto de merge, y ellos deben elegir entre ambas ediciones, o cambiar la línea por completo. | |
52 | ||
53 | Pueden surgir situaciones más complejas. Los sistemas de control de versiones manejan automáticamente los casos simples, y dejan los más complejos para los humanos. Usualmente este comportamiento es configurable. |
0 | = Git Magic = | |
1 | Ben Lynn | |
2 | August 2007 | |
3 | ||
4 | == Prólogo == | |
5 | ||
6 | http://git.or.cz/[Git] es la navaja suiza del control de versiones. Una herramienta de control de revisiones confiable, versátil y multipropósito, que por su extraordinaria flexibilidad es complicada de aprender, y más aún de dominar. Estoy documentando lo que he aprendido hasta ahora en estas páginas, porque inicialmente tuve dificultades para comprender http://www.kernel.org/pub/software/scm/git/docs/user-manual.html[el manual de usuario de Git]. | |
7 | ||
8 | Tal como observó Arthur C. Clarke, cualquier tecnología suficientemente avanzada, es indistinguible de la magia. Este es un gran modo de acercarce a Git: los novatos pueden ignorar su funcionamiento interno, y ver a Git como un artefacto que puede asombrar a los amigos y enfurecer a los enemigos con sus maravillosas habilidades. | |
9 | ||
10 | En lugar de ser detallados, proveemos instrucciones generales para efectos particulares. Luego de un uso reiterado, gradualmente irás entendiendo como funciona cada truco, y como adaptar las recetas a tus necesidades. | |
11 | ||
12 | .Otras ediciones | |
13 | ||
14 | - http://docs.google.com/View?id=dfwthj68_675gz3bw8kj[Traducción al chino]: por JunJie, Meng y JiangWei. | |
15 | - link:book.html[Una única página]: HTML simple, sin CSS. | |
16 | - link:book.pdf[Archivo PDF]: Listo para imprimir. | |
17 | - http://packages.debian.org/search?searchon=names&keywords=gitmagic[Paquete gitmagic para Debian]: Consigue una copia rápida y local de este sitio. http://packages.ubuntu.com/jaunty/gitmagic[Paquete para Ubuntu (Jaunty Jackalope)] también disponible. Útil http://csdcf.stanford.edu/status/[cuando este servidor está offline para mantenimiento]. | |
18 | ||
19 | === Gracias! === | |
20 | ||
21 | Agradezco a Dustin Sallings, Alberto Bertogli, James Cameron, Douglas Livingstone, Michael Budde, Richard Albury, Tarmigan, Derek Mahar y Frode Aannevik por sugerencias y mejoras. Gracias a Daniel Baumann por crear y mantener el paquete para Debian. También gracias a JunJie, Meng y JiangWei por la traduccción al chino. [Si me olvidé de tí, por favor recuérdamelo, porque suelo olvidarme de actualizar esta sección] | |
22 | ||
23 | Estoy muy agradecido por todos los que me han dado apoyo y elogios. Me gustaría que este fuera un libro real impreso, para poder citar sus generosas palabras en la tapa a modo de promoción. Hablando en serio, aprecio enormemente cada mensaje. El leerlos siempre ilumina mi ánimo. | |
24 | ||
25 | === Licencia === | |
26 | ||
27 | Esta guía se publica bajo la http://www.gnu.org/licenses/gpl-3.0.html[GNU General Public License versión 3]. Naturalmente, los fuentes se guardan en un repositorio Git, y pueden ser obtenidos escribiendo: | |
28 | ||
29 | $ git clone git://repo.or.cz/gitmagic.git # Crea el directorio "gitmagic". | |
30 | ||
31 | Ver debajo por otros mirrors. | |
32 | ||
33 | === Hosting Git gratuito === | |
34 | ||
35 | - http://repo.or.cz/[http://repo.or.cz/] hospeda proyectos gratuitos, | |
36 | http://repo.or.cz/w/gitmagic.git[incluyendo esta guía]. | |
37 | - http://gitorious.org/[http://gitorious.org/] es un sitio que apunta al hosting de proyectos open-source. | |
38 | - http://github.com/[http://github.com/] hospeda proyectos open-source gratis, http://github.com/blynn/gitmagic/tree/master[incluyendo esta guía], y proyectos privados por una cuota. |
0 | === Last revision in which the translation was synchronized === | |
1 | preface.txt 09751f37469d32da649b1c64862023820e0d0499 | |
2 | intro.txt 09751f37469d32da649b1c64862023820e0d0499 | |
3 | basic.txt 09751f37469d32da649b1c64862023820e0d0499 | |
4 | clone.txt 46c05532226868b8b3b121d9320c0150491fd181 | |
5 | branch.txt 46c05532226868b8b3b121d9320c0150491fd181 | |
6 | history.txt | |
7 | grandmaster.txt | |
8 | secrets.txt | |
9 | drawbacks.txt |
0 | // From my own website(!) | |
1 | //TODO: only do this for links in the table of contents menu | |
2 | ||
3 | function find_selflink() { | |
4 | var a = document.links; | |
5 | var i = 0; | |
6 | while (i < a.length) { | |
7 | if (a[i].href == document.URL) { | |
8 | var c; | |
9 | var j; | |
10 | var s_new = document.createElement("span"); | |
11 | s_new.className = "currentlink"; | |
12 | c = a[i].childNodes; | |
13 | for (j=0; j<c.length; j++) { | |
14 | s_new.appendChild(c[j]); | |
15 | } | |
16 | a[i].parentNode.replaceChild(s_new, a[i]); | |
17 | } else { | |
18 | i++; | |
19 | } | |
20 | ||
21 | /* | |
22 | if (a[i].href == document.URL) { | |
23 | a[i].className = "currentlink"; | |
24 | if (0) { | |
25 | var s_new = document.createElement("span"); | |
26 | s_new.className = "currentlink"; | |
27 | s_new.appendChild(a[i]); | |
28 | a[i].parentNode.replaceChild(s_new, a[i]); | |
29 | } | |
30 | } | |
31 | i++; | |
32 | */ | |
33 | } | |
34 | } | |
35 | ||
36 | find_selflink(); |
0 | #!/bin/bash | |
1 | ||
2 | # Extract table of contents from index.html and delete preface link. | |
3 | BOOKDIR=book | |
4 | TITLE="Git Magic" | |
5 | gawk ' | |
6 | /<div class="toc">/ { | |
7 | print $0 | |
8 | getline | |
9 | print $0 | |
10 | print "<li><b>'"$TITLE"'</b></li>" | |
11 | getline | |
12 | while (!match($0, "</div>")) { | |
13 | gsub("pr01.html", "index.html") | |
14 | print $0 | |
15 | getline | |
16 | } | |
17 | print $0 | |
18 | exit | |
19 | } | |
20 | ' < $BOOKDIR/index.html > toc.tmp | |
21 | ||
22 | # For every file except the index... | |
23 | for FILE in $BOOKDIR/*.html | |
24 | do | |
25 | if [ $FILE != "$BOOKDIR/index.html" ] | |
26 | then | |
27 | # Prepend "Git Magic - " to titles of all pages. | |
28 | sed '/<title>/ s/<title>/&Git Magic - /' -i $FILE | |
29 | sed 's/pr01\.html/index.html/g' -i $FILE | |
30 | # Paste ToC into beginning and add div section with class content for CSS. | |
31 | sed '/<body/{n; r toc.tmp | |
32 | a <div class="content"> | |
33 | }' -i $FILE | |
34 | sed '/^<\/body/i </div>' -i $FILE | |
35 | fi | |
36 | done | |
37 | ||
38 | # Originally this link was "My Homepage". Since it appears on translations of | |
39 | # the guide, I changed it to my name so it doesn't have to be translated. | |
40 | sed '/^<\/body/i </div><div class="footer"><a href="/~blynn/">Ben Lynn</a></div>' -i $BOOKDIR/*.html | |
41 | ||
42 | cp $BOOKDIR/pr01.html $BOOKDIR/index.html | |
43 | rm toc.tmp |