1 # Git Magic - A guide to using Git
2 # This file is distributed under the GNU GENERAL PUBLIC LICENSE Version 3.
3 # Benn Lynn <benlynn@gmail.com>, 2007.
4 # Armin Stebich <armin@lordofbikes.de>, 2010.
7 "Project-Id-Version: Git Magic deutsch\n"
8 "Report-Msgid-Bugs-To: bennlynn@gmail.com\n"
9 "POT-Creation-Date: 2010-10-30 08:21+0300\n"
10 "PO-Revision-Date: 2010-10-26 18:38+0300\n"
11 "Last-Translator: Armin Stebich <armin@lordofbikes.de>\n"
12 "Language-Team: de <git-magic@lordofbikes.de>\n"
15 "Content-Type: text/plain; charset=UTF-8\n"
16 "Content-Transfer-Encoding: 8bit\n"
19 #: ../en/secrets.txt:2
20 msgid "== Secrets Revealed =="
24 #: ../en/secrets.txt:4
26 "We take a peek under the hood and explain how Git performs its miracles. I "
27 "will skimp over details. For in-depth descriptions refer to http://www."
28 "kernel.org/pub/software/scm/git/docs/user-manual.html[the user manual]."
32 #: ../en/secrets.txt:6
33 msgid "=== Invisibility ==="
37 #: ../en/secrets.txt:8
39 "How can Git be so unobtrusive? Aside from occasional commits and merges, you "
40 "can work as if you were unaware that version control exists. That is, until "
41 "you need it, and that's when you're glad Git was watching over you the whole "
46 #: ../en/secrets.txt:10
48 "Other version control systems force you to constantly struggle with red tape "
49 "and bureaucracy. Permissions of files may be read-only unless you explicitly "
50 "tell a central server which files you intend to edit. The most basic "
51 "commands may slow to a crawl as the number of users increases. Work grinds "
52 "to a halt when the network or the central server goes down."
56 #: ../en/secrets.txt:12
58 "In contrast, Git simply keeps the history of your project in the `.git` "
59 "directory in your working directory. This is your own copy of the history, "
60 "so you can stay offline until you want to communicate with others. You have "
61 "total control over the fate of your files because Git can easily recreate a "
62 "saved state from `.git` at any time."
66 #: ../en/secrets.txt:14
67 msgid "=== Integrity ==="
71 #: ../en/secrets.txt:16
73 "Most people associate cryptography with keeping information secret, but "
74 "another equally important goal is keeping information safe. Proper use of "
75 "cryptographic hash functions can prevent accidental or malicious data "
80 #: ../en/secrets.txt:18
82 "A SHA1 hash can be thought of as a unique 160-bit ID number for every string "
83 "of bytes you'll encounter in your life. Actually more than that: every "
84 "string of bytes that any human will ever use over many lifetimes."
88 #: ../en/secrets.txt:20
90 "As a SHA1 hash is itself a string of bytes, we can hash strings of bytes "
91 "containing other hashes. This simple observation is surprisingly useful: "
92 "look up 'hash chains'. We'll later see how Git uses it to efficiently "
93 "guarantee data integrity."
97 #: ../en/secrets.txt:22
99 "Briefly, Git keeps your data in the `.git/objects` subdirectory, where "
100 "instead of normal filenames, you'll find only IDs. By using IDs as "
101 "filenames, as well as a few lockfiles and timestamping tricks, Git "
102 "transforms any humble filesystem into an efficient and robust database."
106 #: ../en/secrets.txt:24
107 msgid "=== Intelligence ==="
111 #: ../en/secrets.txt:26
113 "How does Git know you renamed a file, even though you never mentioned the "
114 "fact explicitly? Sure, you may have run *git mv*, but that is exactly the "
115 "same as a *git rm* followed by a *git add*."
119 #: ../en/secrets.txt:28
121 "Git heuristically ferrets out renames and copies between successive "
122 "versions. In fact, it can detect chunks of code being moved or copied around "
123 "between files! Though it cannot cover all cases, it does a decent job, and "
124 "this feature is always improving. If it fails to work for you, try options "
125 "enabling more expensive copy detection, and consider upgrading."
129 #: ../en/secrets.txt:30
130 msgid "=== Indexing ==="
134 #: ../en/secrets.txt:32
136 "For every tracked file, Git records information such as its size, creation "
137 "time and last modification time in a file known as the 'index'. To determine "
138 "whether a file has changed, Git compares its current stats with those cached "
139 "in the index. If they match, then Git can skip reading the file again."
143 #: ../en/secrets.txt:35
145 "Since stat calls are considerably faster than file reads, if you only edit a "
146 "few files, Git can update its state in almost no time."
150 #: ../en/secrets.txt:40
152 "We stated earlier that the index is a staging area. Why is a bunch of file "
153 "stats a staging area? Because the add command puts files into Git's database "
154 "and updates these stats, while the commit command, without options, creates "
155 "a commit based only on these stats and the files already in the database."
159 #: ../en/secrets.txt:42
160 msgid "=== Git's Origins ==="
164 #: ../en/secrets.txt:44
166 "This http://lkml.org/lkml/2005/4/6/121[Linux Kernel Mailing List post] "
167 "describes the chain of events that led to Git. The entire thread is a "
168 "fascinating archaeological site for Git historians."
172 #: ../en/secrets.txt:46
173 msgid "=== The Object Database ==="
177 #: ../en/secrets.txt:52
179 "Every version of your data is kept in the 'object database', which lives in "
180 "the subdirectory `.git/objects`; the other residents of `.git/` hold lesser "
181 "data: the index, branch names, tags, configuration options, logs, the "
182 "current location of the head commit, and so on. The object database is "
183 "elementary yet elegant, and the source of Git's power."
187 #: ../en/secrets.txt:55
189 "Each file within `.git/objects` is an 'object'. There are 3 kinds of objects "
190 "that concern us: 'blob' objects, 'tree' objects, and 'commit' objects."
194 #: ../en/secrets.txt:57
195 msgid "=== Blobs ==="
199 #: ../en/secrets.txt:59
201 "First, a magic trick. Pick a filename, any filename. In an empty directory:"
205 #: ../en/secrets.txt:64
208 " $ echo sweet > YOUR_FILENAME\n"
211 " $ find .git/objects -type f\n"
215 #: ../en/secrets.txt:66
216 msgid "You'll see +.git/objects/aa/823728ea7d592acc69b36875a482cdf3fd5c8d+."
220 #: ../en/secrets.txt:69
222 "How do I know this without knowing the filename? It's because the SHA1 hash "
227 #: ../en/secrets.txt:71
229 msgid " \"blob\" SP \"6\" NUL \"sweet\" LF\n"
233 #: ../en/secrets.txt:75
235 "is aa823728ea7d592acc69b36875a482cdf3fd5c8d, where SP is a space, NUL is a "
236 "zero byte and LF is a linefeed. You can verify this by typing:"
240 #: ../en/secrets.txt:77
242 msgid " $ printf \"blob 6\\000sweet\\n\" | sha1sum\n"
246 #: ../en/secrets.txt:84
248 "Git is 'content-addressable': files are not stored according to their "
249 "filename, but rather by the hash of the data they contain, in a file we call "
250 "a 'blob object'. We can think of the hash as a unique ID for a file's "
251 "contents, so in a sense we are addressing files by their content. The "
252 "initial `blob 6` is merely a header consisting of the object type and its "
253 "length in bytes; it simplifies internal bookkeeping."
257 #: ../en/secrets.txt:87
259 "Thus I could easily predict what you would see. The file's name is "
260 "irrelevant: only the data inside is used to construct the blob object."
264 #: ../en/secrets.txt:91
266 "You may be wondering what happens to identical files. Try adding copies of "
267 "your file, with any filenames whatsoever. The contents of +.git/objects+ "
268 "stay the same no matter how many you add. Git only stores the data once."
272 #: ../en/secrets.txt:95
274 "By the way, the files within +.git/objects+ are compressed with zlib so you "
275 "should not stare at them directly. Filter them through http://www.zlib.net/"
276 "zpipe.c[zpipe -d], or type:"
280 #: ../en/secrets.txt:97
282 msgid " $ git cat-file -p aa823728ea7d592acc69b36875a482cdf3fd5c8d\n"
286 #: ../en/secrets.txt:99
287 msgid "which pretty-prints the given object."
291 #: ../en/secrets.txt:101
292 msgid "=== Trees ==="
296 #: ../en/secrets.txt:104
298 "But where are the filenames? They must be stored somewhere at some stage. "
299 "Git gets around to the filenames during a commit:"
303 #: ../en/secrets.txt:107
306 " $ git commit # Type some message.\n"
307 " $ find .git/objects -type f\n"
311 #: ../en/secrets.txt:109
313 "You should now see 3 objects. This time I cannot tell you what the 2 new "
314 "files are, as it partly depends on the filename you picked. We'll proceed "
315 "assuming you chose ``rose''. If you didn't, you can rewrite history to make "
316 "it look like you did:"
320 #: ../en/secrets.txt:112
323 " $ git filter-branch --tree-filter 'mv YOUR_FILENAME rose'\n"
324 " $ find .git/objects -type f\n"
328 #: ../en/secrets.txt:116
330 "Now you should see the file +.git/objects/05/"
331 "b217bb859794d08bb9e4f7f04cbda4b207fbe9+, because this is the SHA1 hash of "
336 #: ../en/secrets.txt:118
338 msgid " \"tree\" SP \"32\" NUL \"100644 rose\" NUL 0xaa823728ea7d592acc69b36875a482cdf3fd5c8d\n"
342 #: ../en/secrets.txt:120
343 msgid "Check this file does indeed contain the above by typing:"
347 #: ../en/secrets.txt:122
349 msgid " $ echo 05b217bb859794d08bb9e4f7f04cbda4b207fbe9 | git cat-file --batch\n"
353 #: ../en/secrets.txt:124
354 msgid "With zpipe, it's easy to verify the hash:"
358 #: ../en/secrets.txt:126
360 msgid " $ zpipe -d < .git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9 | sha1sum\n"
364 #: ../en/secrets.txt:129
366 "Hash verification is trickier via cat-file because its output contains more "
367 "than the raw uncompressed object file."
371 #: ../en/secrets.txt:135
373 "This file is a 'tree' object: a list of tuples consisting of a file type, a "
374 "filename, and a hash. In our example, the file type is 100644, which means "
375 "`rose` is a normal file, and the hash is the blob object that contains the "
376 "contents of `rose'. Other possible file types are executables, symlinks or "
377 "directories. In the last case, the hash points to a tree object."
381 #: ../en/secrets.txt:139
383 "If you ran filter-branch, you'll have old objects you no longer need. "
384 "Although they will be jettisoned automatically once the grace period "
385 "expires, we'll delete them now to make our toy example easier to follow:"
389 #: ../en/secrets.txt:143
392 " $ rm -r .git/refs/original\n"
393 " $ git reflog expire --expire=now --all\n"
398 #: ../en/secrets.txt:150
400 "For real projects you should typically avoid commands like this, as you are "
401 "destroying backups. If you want a clean repository, it is usually best to "
402 "make a fresh clone. Also, take care when directly manipulating +.git+: what "
403 "if a Git command is running at the same time, or a sudden power outage "
404 "occurs? In general, refs should be deleted with *git update-ref -d*, though "
405 "usually it's safe to remove +refs/original+ by hand."
409 #: ../en/secrets.txt:152
410 msgid "=== Commits ==="
414 #: ../en/secrets.txt:156
416 "We've explained 2 of the 3 objects. The third is a 'commit' object. Its "
417 "contents depend on the commit message as well as the date and time it was "
418 "created. To match what we have here, we'll have to tweak it a little:"
422 #: ../en/secrets.txt:166
425 " $ git commit --amend -m Shakespeare # Change the commit message.\n"
426 " $ git filter-branch --env-filter 'export\n"
427 " GIT_AUTHOR_DATE=\"Fri 13 Feb 2009 15:31:30 -0800\"\n"
428 " GIT_AUTHOR_NAME=\"Alice\"\n"
429 " GIT_AUTHOR_EMAIL=\"alice@example.com\"\n"
430 " GIT_COMMITTER_DATE=\"Fri, 13 Feb 2009 15:31:30 -0800\"\n"
431 " GIT_COMMITTER_NAME=\"Bob\"\n"
432 " GIT_COMMITTER_EMAIL=\"bob@example.com\"' # Rig timestamps and authors.\n"
433 " $ find .git/objects -type f\n"
437 #: ../en/secrets.txt:170
439 "You should now see +.git/objects/49/993fe130c4b3bf24857a15d7969c396b7bc187+ "
440 "which is the SHA1 hash of its contents:"
444 #: ../en/secrets.txt:177
447 " \"commit 158\" NUL\n"
448 " \"tree 05b217bb859794d08bb9e4f7f04cbda4b207fbe9\" LF\n"
449 " \"author Alice <alice@example.com> 1234567890 -0800\" LF\n"
450 " \"committer Bob <bob@example.com> 1234567890 -0800\" LF\n"
452 " \"Shakespeare\" LF\n"
456 #: ../en/secrets.txt:179
457 msgid "As before, you can run zpipe or cat-file to see for yourself."
461 #: ../en/secrets.txt:182
463 "This is the first commit, so there are no parent commits, but later commits "
464 "will always contain at least one line identifying a parent commit."
468 #: ../en/secrets.txt:184
469 msgid "=== Indistinguishable From Magic ==="
473 #: ../en/secrets.txt:186
475 "Git's secrets seem too simple. It looks like you could mix together a few "
476 "shell scripts and add a dash of C code to cook it up in a matter of hours: a "
477 "melange of basic filesystem operations and SHA1 hashing, garnished with lock "
478 "files and fsyncs for robustness. In fact, this accurately describes the "
479 "earliest versions of Git. Nonetheless, apart from ingenious packing tricks "
480 "to save space, and ingenious indexing tricks to save time, we now know how "
481 "Git deftly changes a filesystem into a database perfect for version control."
485 #: ../en/secrets.txt:194
487 "For example, if any file within the object database is corrupted by a disk "
488 "error, then its hash will no longer match, alerting us to the problem. By "
489 "hashing hashes of other objects, we maintain integrity at all levels. "
490 "Commits are atomic, that is, a commit can never only partially record "
491 "changes: we can only compute the hash of a commit and store it in the "
492 "database after we already have stored all relevant trees, blobs and parent "
493 "commits. The object database is immune to unexpected interruptions such as "
498 #: ../en/secrets.txt:205
500 "We defeat even the most devious adversaries. Suppose somebody attempts to "
501 "stealthily modify the contents of a file in an ancient version of a project. "
502 "To keep the object database looking healthy, they must also change the hash "
503 "of the corresponding blob object since it's now a different string of bytes. "
504 "This means they'll have to change the hash of any tree object referencing "
505 "the file, and in turn change the hash of all commit objects involving such a "
506 "tree, in addition to the hashes of all the descendants of these commits. "
507 "This implies the hash of the official head differs to that of the bad "
508 "repository. By following the trail of mismatching hashes we can pinpoint the "
509 "mutilated file, as well as the commit where it was first corrupted."
513 #: ../en/secrets.txt:208
515 "In short, so long as the 20 bytes representing the last commit are safe, "
516 "it's impossible to tamper with a Git repository."
520 #: ../en/secrets.txt:214
522 "What about Git's famous features? Branching? Merging? Tags? Mere details. "
523 "The current head is kept in the file +.git/HEAD+, which contains a hash of a "
524 "commit object. The hash gets updated during a commit as well as many other "
525 "commands. Branches are almost the same: they are files in +.git/refs/heads+. "
526 "Tags too: they live in +.git/refs/tags+ but they are updated by a different "