first quick and dirty translation from german translation using omegat
[gitmagic.git] / szl / history.txt
blob2f00b356be6b318a92f0a39d44d2de850a7550c8
1 == Lekcja historii ==
3 Jedną z charakterystycznych cech rozproszonej natury Git jest to, że jego kronika historii może być łatwo edytowana.  Ale jeśli masz zamiar manipulować przeszłością, bądź ostrożny: zmieniaj tylko tą część historii, którą wyłącznie jedynie ty sam posiadasz. Tak samo jak Narody ciągle dyskutują, który jakie popełnił okrucieństwa, popadniesz w kłopoty przy synchronizacji, jeśli ktoś inny posiada klon z różniącą się historią i jeśli te odgałęzienia mają się wymieniać.
5 Niektórzy programiści zarzekają się w kwestii nienaruszalności historii - ze wszystkimi jej błędami i niedociągnięciami. Inni uważają, ze odgałęzienia powinny dobrze się prezentować nim zostaną przedstawione publicznie. Git jest wyrozumiały dla obydwóch stron. Tak samo jak 'clone', 'branch' czy 'merge', możliwość zmian kroniki historii to tylko kolejna mocna strona Gita. Stosowanie lub nie, tej możliwości zależy wyłącznie od ciebie.
7 === Muszę się skorygować ===
9 Właśnie wykonałeś 'commit', ale chętnie chciałbyś podać inny opis? Wpisujesz:
11  $ git commit --amend 
13 by zmienić ostatni opis. Zauważasz jednak, że zapomniałeś dodać jakiegoś pliku? Wykonaj *git add*, by go dodać a następnie poprzednią instrukcje.
15 Chcesz wprowadzić jeszcze inne zmiany do ostatniego 'commit'? Wykonaj je i wpisz:
17 $ git commit --amend -a 
19 === ...  i jeszcze coś ===
21 Załóżmy, że poprzedni problem będzie 10 razy gorszy. Po dłuższej sesji zrobiłeś całą masę 'commits'. Nie jesteś jednak szczęśliwy z takiego zorganizowania a niektóre z 'commits' mogłyby być inaczej sformułowane. Wpisujesz:
23  $ git rebase -i HEAD~10 
25 i ostatnie 10 'commits' pojawią się w preferowanym przez ciebie edytorze. Przykładowy wyciąg:
27     pick 5c6eb73 Added repo.or.cz link
28     pick a311a64 Reordered analogies in "Work How You Want"
29     pick 100834f Added push target to Makefile
31 Starsze 'commits' poprzedzają młodsze, inaczej niż w poleceniu `log`
32 Tutaj 5c6eb73 jest najstarszym 'commit', a 100834f najnowszym. By to zmienić:
34 - Usuń 'commits' poprzez skasowanie linii. Podobnie jak polecenie 'revert', będzie to jednak wyglądało jakby wybrane 'commit' nigdy nie istniały.
35 - Przeorganizuj 'commits' przesuwając linie. 
36 - Zamień `pick` na: 
37    * `edit`  by zaznaczyć 'commit' do 'amend'. 
38    * `reword`, by zmienić opisy logu. 
39    * `squash` by połączyć 'commit' z poprzednim ('merge'). 
40    * `fixup` by połączyć 'commit' z poprzednim ('merge') i usunąć zapisy z logu.
42 Na przykład chcemy zastąpić drugi `pick` na `squash`:
44 Zapamiętaj i zakończ. Jeśli zaznaczyłeś jakiś 'commit' poprzez 'edit', wpisz:
46  $ git commit --amend 
48     pick 5c6eb73 Added repo.or.cz link
49     squash a311a64 Reordered analogies in "Work How You Want"
50     pick 100834f Added push target to Makefile
52 After we save and quit, Git merges a311a64 into 5c6eb73. Thus *squash* merges
53 into the next commit up: think ``squash up''.
55 Git then combines their log messages and presents them for editing. The
56 command *fixup* skips this step; the squashed log message is simply discarded.
58 If you marked a commit with *edit*, Git returns you to the past, to the oldest
59 such commit. You can amend the old commit as described in the previous section,
60 and even create new commits that belong here. Once you're pleased with the
61 ``retcon'', go forward in time by running:
63  $ git rebase --continue 
65 Git replays commits until the next *edit*, or to the present if none remain.
67 You can also abandon the rebase with:
69  $ git rebase --abort
71 A więc, stosuj polecenie 'commit' wcześnie i często: możesz później posprzątać za pomocą 'rebase'.
73 === Lokalne zmiany na koniec ===
75 Pracujesz nad aktywnym projektem. Z biegiem czasu nagromadziło się wiele 'commits' i wtedy chcesz zsynchronizować za pomocą 'merge' z oficjalną gałęzią. Ten cykl powtarza się kilka razy zanim jesteś gotowy na 'push' do centralnego drzewa.
77 Teraz jednak historia w twoim lokalnym klonie jest chaotycznym pomieszaniem twoich zmian i zmian z oficjalnego drzewa. Chciałbyś raczej widzieć twoje zmiany uporządkowane chronologicznie w jednej sekcji i za oficjalnymi zmianami. 
79 To zadanie dla *git rebase*, jak opisano powyżej. W wielu przypadkach możesz skorzystać z przełącznika *--onto* by zapobiec interakcji.
81 Przeczytaj też *git help rebase* dla zapoznania sie z obszernymi przykładami tej zadziwiającej funkcji. Możesz również podzielić 'commits'. Możesz nawet przeorganizować 'branches' w repozytorium.
83 Bądź ostrożny korzystając z 'rebase', to bardzo mocne polecenie. Zanim dokonasz skomplikowanych 'rebase', zrób backup za pomocą *git clone*
85 === Przepisanie historii ===
87 Czasami potrzebny ci rodzaj systemu kontroli porównywalnego do wyretuszowania osób z oficjalnego zdjęcia, by w stalinowski sposób wymazać je z historii. Wyobraź sobie, że chcesz opublikować projekt, jednak zawiera on pewny plik, który z jakiegoś ważnego powodu musi pozostać utajniony. Być może zapisałem numer karty kredytowej w danej tekstowej i nieumyślnie dodałem do projektu? Skasowanie tej danej nie ma sensu, ponieważ poprzez starsze 'commits' można nadal ją przywołać. Musimy ten plik usunąć ze wszystkich 'commits':
89  $ git filter-branch --tree-filter 'rm bardzo/tajny/plik' HEAD
91 Sprawdź *git help filter-branch*, gdzie przykład ten został wytłumaczony i przytoczona została jeszcze szybsza metoda. Ogólnie poprzez *filter-branch* da się dokonać zmian w dużych zakresach historii poprzez tylko jedno polecenie.
93 Po tej operacji katalog +.git/refs/original+ opisuje stan przed jej wykonaniem. Sprawdź czy 'filter-branch' zrobił to, co od niego oczekiwałeś, następnie skasuj ten katalog zanim wykonasz następne polecenia 'filter-branch'.
95 Wreszcie zamień wszystkie klony twojego projektu na zaktualizowaną wersję, jeśli masz zamiar prowadzić z nimi wymianę. 
97 === Tworzenie historii ===
99 [[makinghistory]] 
100 Masz zamiar przenieść projekt do Gita? Jeśli twój projekt był dotychczas zarządzany jednym z bardziej znanych systemów, to istnieje duże prawdopodobieństwo, że ktoś napisał już odpowiedni skrypt, który umożliwi ci eksportowanie do Gita całej historii.
102 W innym razie przyjrzyj się funkcji *git fast-import*, która wczytuje tekst w specjalnym formacie by następnie odtworzyć całą historię od początku. Często taki skrypt pisany jest pośpiesznie i służy do jednorazowego wykorzystania, aby tylko w jednym przebiegu udała się migracja projektu.
104 Utwórz na przykład z następującej listy tymczasowy plik, na przykład jako: `/tmp/history`: 
105 ----------------------------------
106 commit refs/heads/master
107 committer Alice <alice@example.com> Thu, 01 Jan 1970 00:00:00 +0000
108 data <<EOT
109 Initial commit.
112 M 100644 inline hello.c
113 data <<EOT
114 #include <stdio.h>
116 int main() {
117   printf("Hello, world!\n");
118   return 0;
123 commit refs/heads/master
124 committer Bob <bob@example.com> Tue, 14 Mar 2000 01:59:26 -0800
125 data <<EOT
126 Replace printf() with write().
129 M 100644 inline hello.c
130 data <<EOT
131 #include <unistd.h>
133 int main() {
134   write(1, "Hello, world!\n", 14);
135   return 0;
139 ----------------------------------
141 Następnie utwórz repozytorium git z tymczasowego pliku poprzez wpisanie:
143  $ mkdir project; cd project; git init 
144  $ git fast-import --date-format=rfc2822 < /tmp/history 
146 Aktualną wersję projektu możesz przywołać ('checkout') poprzez:
148  $ git checkout master
150 Polecenie *git fast-export* konwertuje każde repozytorium do formatu *git fast-import*, możesz przestudiować komunikaty tego polecenia, jeśli masz zamiar napisać programy eksportujące a oprócz tego, by przekazywać repozytoria jako czytelne dla ludzi zwykłe pliki tekstowe. To polecenie potrafi przekazywać repozytoria za pomocą zwykłego pliku tekstowego.
152 === Gdzie wszystko się zepsuło? ===
154 Właśnie znalazłeś w swoim programie funkcję, która już nie chce działać, a jesteś pewna, że czyniła to jeszcze kilka miesięcy temu. Ach! Skąd wziął się ten błąd? A gdybym tylko lepiej przetestowała ją wcześniej, zanim weszła do wersji produkcyjnej.
156 Na to jest już za późno. Jakby nie było, pod warunkiem, że często używałeś 'commit', Git może ci zdradzić gdzie szukać problemu.
158  $ git bisect start
159  $ git bisect bad HEAD
160  $ git bisect good 1b6d
162 Git przywoła stan, który leży dokładnie pośrodku. Przetestuj funkcję, a jeśli ciągle jeszcze nie działa:
164  $ git bisect bad 
166 Jeśli nie, zamień "bad" na "good". Git przeniesie cię znowu do stanu dokładnie pomiędzy znanymi wersjami "good" i "bad", redukując w ten sposób możliwości. Po kilku iteracjach doprowadzą cię te poszukiwania do 'commit', który jest odpowiedzialny za kłopoty. Po skończeniu dochodzenia przejdź do oryginalnego stanu:
168  $ git bisect reset 
170 Zamiast sprawdzania zmian ręcznie, możesz zautomatyzować poszukiwania za pomocą skryptu:
172  $ git bisect run mój_skrypt
174 Git korzysta tutaj z wartości zwróconej przez skrypt, by ocenić czy zmiana jest dobra ('good'), czy zła ('bad'): Skrypt powinien zwracać 0 dla 'good', 128, jeśli zmiana powinna być pominięta, i coś pomiędzy 1 - 127 dla 'bad'. Jeśli wartość zwrócona jest ujemna, program 'bisect' przerywa pracę.
176 Możesz robić jeszcze dużo innych rzeczy: w pomocy znajdziesz opis w jaki sposób wizualizować działania 'bisect', sprawdzić czy powtórzyć log bisect, wyeliminować nieistotne zmiany dla zwiększenia prędkości poszukiwań.
178 === Kto ponosi odpowiedzialność? ===
180 Jak i wiele innych systemów kontroli wersji również i Git posiada polecenie 'blame':
182  $ git blame bug.c 
184 które komentuje każdą linię podanego pliku, by pokazać kto ją ostatnio zmieniał i kiedy. W przeciwieństwie do wielu innych systemów, funkcja ta działa offline, czytając tylko z lokalnego dysku.
186 === Osobiste doświadczenia ===
188 W scentralizowanym systemie kontroli wersji praca nad kroniką historii jest skomplikowanym zadaniem i zarezerwowanym głównie dla administratorów. Polecenia 'clone', 'branch' czy 'merge' nie są możliwe bez podłączenia do sieci. Również takie podstawowe funkcje, jak przeszukanie historii czy 'commit' jakiejś zmiany. W niektórych systemach użytkownik potrzebuje działającej sieci nawet by zobaczyć  dokonane przez siebie zmiany, albo by w ogóle otworzyć plik do edycji.
190 Scentralizowane systemy wykluczają pracę offline i wymagają drogiej infrastruktury sieciowej, w szczególności gdy wzrasta liczba programistów. Najgorsze jednak, iż z czasem wszystkie operacje stają się wolniejsze, z reguły do osiągnięcia punktu, gdzie użytkownicy unikają zaawansowanych poleceń, aż staną się one absolutnie konieczne. W ekstremalnych przypadkach dotyczy to również poleceń podstawowych. Jeśli użytkownicy są zmuszeni do wykonywania powolnych poleceń, produktywność spada, ponieważ ciągle przerywany zostaje tok pracy.
192 Dowiedziałem się o tym fenomenie z pierwszej ręki. Git był pierwszym systemem kontroli wersji którego używałem. Szybko dorosłem do tej aplikacji i przyjąłem wiele funkcji za oczywiste.  Wychodziłem też z założenia, że inne systemy są podobne: wybór systemu kontroli wersji nie powinien zbyt bardzo odbiegać od wyboru edytora tekstu, czy przeglądarki internetowej.
194 Byłem zszokowany, gdy musiałem później korzystać ze scentralizowanego systemu. Niesolidne połączenie internetowe ma niezbyt duży wpływ na Gita, praca staje się jednak prawie nie możliwa, gdy wymagana jest niezawodność porównywalny z lokalnym dyskiem. Poza tym sam łapałem się na tym, że unikałem pewnych poleceń i związanym z nimi czasem oczekiwania, w sumie wszystko to wpływało mocno na wypracowany przeze mnie system pracy.
196 Gdy musiałem wykonywać powolne polecenia, z powodu ciągłego przerywanie toku myślenia, powodowałem nieporównywalne szkody dla całego przebiegu pracy. Podczas oczekiwania na zakończenie komunikacji pomiędzy serwerami dla przeczekania zaczynałem robić coś innego, na przykład czytałem maile albo pisałem dokumentację. Gdy wracałem do poprzedniego zajęcia, po zakończeniu komunikacji, dawno straciłem wątek i traciłem czas, by znów przypomnieć sobie co właściwie miałem zamiar zrobić. Ludzie nie potrafią dobrze dostosować się do częstej zmiany kontekstu.
198 Był też taki ciekawy efekt http://pl.wikipedia.org/wiki/Tragedia_wspólnego_pastwiska[tragedii wspólnego pastwiska]: przypominający przeciążenia w sieci - pojedyncze indywidua pochłaniają więcej pojemności sieci niż to konieczne, by uchronić się przed mogącymi ewentualnie wystąpić w przyszłości niedoborami. Suma tych starań pogarsza tylko przeciążenia, co motywuje jednostki do zużywania jeszcze większych zasobów, by ochronić się przed jeszcze dłuższymi czasami oczekiwania.