first quick and dirty translation from german translation using omegat
[gitmagic.git] / tmp / secrets.txt
blob79dec33ceb9096719c1af28bf27486262675845f
1 == Uchylenie tajemnicy ==
3 Rzućmy spojrzenie pod maskę silnika i wytłumaczymy w jaki sposób Git realizuje swoje cuda. Nie będę wchodził w szczegóły. Dla pogłębienia tematu odsyłam na http://www.kernel.org/pub/software/scm/git/docs/user-manual.html[anielskojęzychny podręcznik użytkownika].
5 === Niewidzialność ===
7 Jak to możliwe, że Git jest taki niepostrzeżony? Zapominając na chwilę o sporadycznych 'commits' i 'merges', możesz pracować w sposób, jakby kontrola wersji wogóle nie istniała. To znaczy - do czasu aż będzie ci potrzebna. A oto chodzi, byś był zadoowolony z tego, że Git cały czas czuwa nad twoją pracą
9 Inne systemy kontroli wersji ciągle zmuszają cię do ciągłego borykania się z zagadnieniem samej kontroli i związanej z tym biurokracji.  Pliki mogą być zapezpieczone przed zapisem, aż do momentu gdy uda ci się poinformować centralny serwer o tym, że chciałabyś nad nimi popracować. Przy wzroście liczby użytkowników nawet najprostsze polecenia stają się wolne jak ślimak. Gdy tylko zniknie sieć lub centralny serwer praca staje.
11 W przeciwieństwie do tego, Git posiada kronikę całej swojej historii w podkatalogu .git twojego katalogu roboczego. Jest to twoja własna kopie całej historii, z którą mogłabyś pracować offline, aż do momentu gdy zechcesz wymienić dane z innymi. Posiadasz absolutną kontrolę nad losem twoich danych, ponieważ Git potrafi dla ciebie w każdej chwili odtworzyć zapamiętany poprzednio stan z właśnie podkatalogu .git.
13 === Integralność ===
15 Z kryptografią przez większość ludzi łączona jest poufność informacji, jednak równie ważnym jej celem jest zabezpieczenie danych. Właściwe zastosowanie kraptograficznych funkcji hashujących (funkcji skrótu) może uchronić przed nieumyślnym lub celowym zniszczeniem danych. 
17 Klucz hashujący SHA1 mogłabyś wyobrazić sobie jako składający się ze 160 bitów numer identyfikacyjny jednoznacznie opisujący dowolny łańcuch znaków, i który spotkasz w sowim życiu jeden jedyny raz. Nawet i więcej niż to: wszystkie łańcuchy znaków, jakie ludzkość przez wiele generacji stworzyła.
19 sam kluch SHA1 też jest łańcuchem znaków w formie Bajtów. Możemy generować klucze SHA1 z łańcuchów samych zawierających klucze SHA1. Ta prosta obserwacja okazała się niesamowicie pożyteczna: jeśli cię to zainteresowało poszukaj informacji na temat 'hash chains'. Zobaczymy później w jaki sposób wykorzystje je Git dla zapewnienia produktywności i integralności danych.
21 Krótko mówiąc, Git przechowuje twoje dane w podkatalogu `.git/objects`, gdzie zamiast nazw plików znajdziesz numery identyfikacyjne.  Poprzez wykorzystanie tych numerów identyfikacyjnych jako nazwy plików razem z kilkoma innymi trikami związanymi z plikami blokującymi i znacznikami czasu, Git zamienia twój prosty system plików na produktywną i solidną bazę danych. 
23 === Inteligencja ===
25 Skąd Git wie o tym, że zmieniłaś nazwę jakiegoś pliku, jeśli nigdy go o tym wyraźnie nie poinformowałaś? Oczywiście, być może użyłaś polecenia *git mv*, jest to jednak to samo jakbyś użyła *git rm*, a następnie *git add*.
27 Git poszukuje heurystycznie zmian nazw w następującymch po sobie wersjach kopii. Dodatkowo potrafi czasami nawet znaleźć całe bloki z kodem przenoszonym tam i spowrotem między plikami! Mimo iż wykonuje kawał dobrej roboty, a ta właściwość staje się coraz lepsza, nie potrafi niestety jeszcze poradzić sobie z wszystkimi możliwymi przypadkami. Jeśli to u ciebie nie działa, spróbuj poszukać opcji rozszerzonego rozpoznawania kopii, aktualizacja samegi Git, też może pomóc.
29 === Indeksowanie ===
31 Dla każdego kontrolowanego pliku, Git zapamiętuje informacje o jego wielkości, czasie utworzenia i czasie ostatniej edycji w pliku znanym nam jako index. By ustalić, czy nastąpiła jakaś zmiana, Git porównuje stan aktualny ze stanem zapamiętanym w indeksie. Jeśli dane te nie różnią się, Git może pominąć czytanie zawartości pliku.
33 Ponieważ sprawdzenie statusu pliku trwa dużo krócej niż jego całkowite wczytanie, to jeśli dokonałaś zmian tylko na kilku plikach Git zaktualizuje swój stan w mgnieniu oka. 
35 Stwierdziliśmy już wcześniej, że indeks jest przechowalnią (ang. staging area). Jak to możliwe, że stos informacji o statusie danych może być przechowywalnią? Ponieważ polecenie 'add' transportuje pliki do bazy danych Git i aktualizuje informacje o ich statusie, podczas gdy polecenie 'commit' (bez opcji) tworzy commit tylko wyłącznie na podstawie informacji o statusie plików, ponieważ pliki te już sie w tej bazie znajdują.
37 === Korzenie Git ===
39 Ten http://lkml.org/lkml/2005/4/6/121['Linux Kernel Mailing List' post] opisuje cały łańcuch zdarzeń, które inicjowały powstanie Git.  Cały post jest archeologicznie fascynującą stroną dla historyków zajmujących sie Gitem.
41 === Obiektowa baza danych ===
43 Każda wersja twoich danych jest przechowywana w objektowej bazie danych, która znajduje sie w podkatalogu `.git/objects`. Inne miejsca w `.git/` posiadają mniej ważne dane, jak indeks, nazwy gałęzi ('branch'), tagi, logi,konfigurację, aktualną pozycję HEAD i tak dalej. Obiektowa baza danych jest prosta, mimo to jesnak elegancka i jest źródłem siły Gita.
45 Każdy plik w `.git/objects` jest 'objektem'. Istnieją trzy rodzaje objektów, które nas interesują:  'blob', 'tree'-, i 'commit'.
47 === Bloby ===
49 Na początek magiczna sztuczka Wymyśl jakąś nazwę pliku, jakąkolwiek. W pustym katalogu:
52 $ echo sweet > TWOJA_NAZWA $ git init $ git add . $ find .git/objects -type f $ find .git/objects -type f 
54 Zobaczysz coś takiego: +.git/objects/aa/823728ea7d592acc69b36875a482cdf3fd5c8d+.
56 Skąd mogłem to wiedzieć, mimo iż nie znałem nazwy pliku? Poniewaś wartość klucza SHA1 dla:
58 "blob" SP "6" NUL "sweet" LF 
60 wynosi właśnie: aa823728ea7d592acc69b36875a482cdf3fd5c8d.  Przyczym SP to spacja, NUL - to bajt zerowy, a LF to znak nowej linii ('newline').  Możesz to skontrolować wpisując:
62 $ printf "blob 6\000sweet\n" | sha1sum 
64 Git pracuje asocjacyjnie (skojarzeniowo): dane nie są zapamiętywane na podstawie ich nazwy, tylko wartości ich własnego klucza SHA1 w pliku, który określamy mianem objektu 'blob'. Klucz SHA1 możemy sobie wyobrazić jako niepowtarzalny numer identyfikacyjny zawartości pliku, co oznacza, że pliki adresowane są na podstawie ich zawartości. Początkowe `blob 6`, to jedynie adnotacja, która określa jedynie rodzaj objektu i jego wieklość w bajtach, pozwala to na uproszczenie zarządzania wewnętrznego.
66 Przez to właśnie mogłem 'przepowiedzieć' wynik. Nazwa pliku nie ma znaczenia, jedynie jego zawartość służy do utworzenia objektu 'blob'.
68 Pytasz się, a co w przypadku identycznych plików? Spróbuj dodać kopie twojej danej pod jakąkolwiek nazwą. Zawartość +.git/objects+ nie zmieni się, niezależnie ile kopii dodałaś. Git zapamięta zawartość pliku wyłącznie jeden raz.
70 Na marginesie, dane w +.git/objects+ są spakowane poprzez zlib, nie powinieneś otwierać ich bezpośrednio. Przefiltruj je najpierw przez http://www.zlib.net/zpipe.c[zpipe -d], albo wpisz: 
72 $ git cat-file -p aa823728ea7d592acc69b36875a482cdf3fd5c8d 
74 polecenie to pokaże ci zawartość objektu jako tekst.
76 === 'Trees'  ===
78 Gdzie są więc nazwy plików? Przecież muszą być gdzieś zapisane. Podczas wykonywania 'commit' Git troszczy się o nazwy plików:
80 $ git commit # dodaj jakiś opis. $ find .git/objects -type f $ find .git/objects -type f 
82 Powinieneś ujrzeć teraz 3 objekty. Tym razem nie jestem w stanie powiedzieć, jak nazywają sie te dwa nowe pliki, ponieważ częściowo są zależne od nazwy jaką nadałeś plikom. Pójdźmy dalej, zakładając, że jedną z tych danych nazwałeś ``rose''. Jeśli nie, możesz zmienić opis, by wyglądał jakby był twój:
84 $ git filter-branch --tree-filter 'mv TWOJA_NAZWA rose' $ find .git/objects -type f
86 Powinnaś zobaczyć teraz plik +.git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9+, ponieważ jest to klucz SHA1 jego zawartości.
88 "tree" SP "32" NUL "100644 rose" NUL 0xaa823728ea7d592acc69b36875a482cdf3fd5c8d 
90 Sprawdź, czy plik na prawdę odpowiada powyższej zawartości przez polecenie:
92 $ echo 05b217bb859794d08bb9e4f7f04cbda4b207fbe9 | git cat-file --batch 
94 Za pomocą zpipe łatwo sprawdzić klucz SHA1:
97 $ zpipe -d < .git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9 | sha1sum 
99 Sprawdzanie za pomocą 'cat-file' jest troszeczkę kłopotliwe, bo jego output zawiera więcej niż tylko nieskomprymowany objekt pliku.
101 Nasz plik to takzwany objekt 'tree': lista wyrażeń, na którą składają się rodzaj pliku, jego nazwa i jego klucz SHA1. W naszym przykładzie typ pliku to 100644, co oznacza, że `rose` jest plikiem zwykłym, natomiast klucz SHA1 odpowiada kluczowi SHA1 objektu 'blob' zawierającego zawartość `rose`. Inne możliwe rodzaje plików to programy, linki symboliczne i katalogi. W ostatnim przypadku klucz SHA1 wskazuje na objekt 'tree'.
103 Jeśli użyjesz polecenia 'filter-branch', otrzymasz stare objekty, które nie są już używane. Mimo iż automatycznie zostaną usunięte po upłynięciu okresu łaski, chcemy się ich pozbyć od zaraz, aby lepiej prześledzić następne przykłady.
105 $ rm -r .git/refs/original $ git reflog expire --expire=now --all $ git prune 
107 W prawdziwych projektach powinnaś unikać takich komend, poonieważ zniszczą zabezpieczone dane. Jeśli chcesz posiadać czyste repozytorium, to najlepiej załóż  nowy klon. Bądź też ostrożna przy bezpośredniej manipulacji +.giz+: gdy równocześnie wykonywane jest polecenie Git i zgaśnie światło? Generalnie do kasowania referencji powinnaś używać *git update-ref -d*, nawet gdy ręczne usunięcie +ref/original+ jest dość bezpieczne.
109 === 'Commits' ===
111 Wytłumaczyliśmy dwa z trzech objektów. Ten trzeci to objekt 'commit' Jego zawartość jest zależna od opisu 'commit' jak i czasu jego wykonania. By wszystko do naszego przykładu pasowało, musimy trochę pokombinować.
113 $ git commit --amend -m Shakespeare # Zmień ten opis. $ git filter-branch --env-filter 'export GIT_AUTHOR_DATE="Fri 13 Feb 2009 15:31:30 -0800" GIT_AUTHOR_NAME="Alice" GIT_AUTHOR_EMAIL="alice@example.com" GIT_COMMITTER_DATE="Fri, 13 Feb 2009 15:31:30 -0800" GIT_COMMITTER_NAME="Bob" GIT_COMMITTER_EMAIL="bob@example.com"' # Zmanipuluj znacznik czasowy i nazwę autora. $ find .git/objects -type f $ find .git/objects -type f 
115 Powinieneś znaleźć +.git/objects/49/993fe130c4b3bf24857a15d7969c396b7bc187+, co odpowiada kluczowi SHA1 jego zawartości: 
117 "commit 158" NUL "tree 05b217bb859794d08bb9e4f7f04cbda4b207fbe9" LF "author Alice <alice@example.com> 1234567890 -0800" LF "committer Bob <bob@example.com> 1234567890 -0800" LF LF "Shakespeare" LF 
119 Jak i w poprzednich przykładach możesz użyć 'zpipe' albo 'cat-file' by to sprawdzić.
121 To jest pierwszy 'commit', przez to nie posiada rodziców 'commit'. Następujące 'commits' będą zawsze zawierać przynajmniej jedną linikę identyfikującą rodzica.
123 === Nie do odróżnienia od magii ===
125 Tajemnice Gita wydają się być proste. Wygląda to jak połączenie kilku skryptów, troszeczkę kodu C i w przeciągu kilku godzin jesteśmy gotowi: zmiksowanie podstawowych operacji na systemie danych obliczenia SHA1, przyprawione danymi blokującymy i synchronizacją dla stabilności. W sumie można by tak opisać najwcześniejsze wersje Gita. Tym niemniej, abstrahując od udanych trików pakujących, by oszczędnie odnosić się z pamięcią i udanych trików indeksujących by zaoszczędzić czas, wiemy jak Git sprawnie przemienia system danych i bazę danych, co jest optymalne dla kontroli wersji.
127 Przyjmijmy, gdy jakikolwiek plik w objektowej bazie danych ulegnie zniszczeniu poprzez błąd nośnika, to jego SHA1 nie będzie zgadzać i jego zawartością, co od razu wskaże nam problem. Poprzez tworzenie kluczy SHA1 z kluczy SHA1 innych objektów, osiągniemy integralność danych na wszystkich poziomach. 'commits' są elementarne, do znaczy, 'commit' nie potrafi zapamiętać jedynie części zmian: klucz SHA1 'commit' możemy obliczyć i zapamiętać dopiero po tym gdy zapamiętane zostały wszystkie objekty 'tree', 'blob' i rodziców 'commit'. Objektowa baza dynch jest osporna na nieoczekiwane przerwy, jak na przykład przerwanie dostawy prądu.
129 Możemy przetrwać nawet podstępnego przeciwnika. Wyobraź sobie,, ktoś ma zamiar zmienić treść jakiegoś pliku, która leży w jakiejś starszej wersji projektu. By sprawić pozory, że baza danych wygląda nienaruszona. musiałabyś wmienić klucze SHA1 korespondujących objektów, ponieważ plik zawiera teraz zmieniony sznur znaków.  To znaczy róniweż, że musiałabyś zmienić każdy klucz objektu 'tree', które ją referują oraz w wyniku tego wszystkie klucze 'commits' zawierające obejkty 'tree' dodatkowo do pochodnych tych 'commits'. Oznacza to również, że klusz oficjalnego HEAD różni się od klucza HEAD manipulowanego rapozytorium. Wystrarczy teraz prześledzić ścieżkę różniących się kluczy SHA1, odnajeźć okaleczony plik, jak i 'commit' w którym po raz pierwszy wystąpił.
131 Krótko mówiąc, doputy reprezentujące ostatni commit 20 bajtów są zabezpieczone, przefałszowanie repozytorium Gita nie jest możliwe.
133 A co ze sławnymi możliwościami Gita? 
134 'Branching'?  'Merging'?  'Tags'?  To szczegół. Aktualny HEAD przetrzymywany jest w pliku +.git/HEAD+, która posiada klucz SHA1 ostatniego 'commit'. Klucz SHA1 zostaje aktualizowany podczas wykonania 'commit', tak samo jak i przy wielu innych poleceniach. 'branches' to prawie to samo, są plikami zapamiętanymi w +.git/refs/heads+. 'Tags' również, znajdziemy je w +.git/refs/tags+, są one jednak aktualizowane poprzez serię innych poleceń.