From: damianmichna Date: Sat, 6 Jul 2013 12:33:36 +0000 (+0200) Subject: Alle Dateien in pl geprüft X-Git-Url: https://repo.or.cz/w/gitmagic.git/commitdiff_plain/ad4de943b2c322284e6453f56c855ed09a6a3a47 Alle Dateien in pl geprüft --- diff --git a/pl/drawbacks.txt b/pl/drawbacks.txt index 5785cf0..2c65d41 100644 --- a/pl/drawbacks.txt +++ b/pl/drawbacks.txt @@ -1,12 +1,12 @@ == Załącznik A: Niedociągnięcia Gita == -O kilku problemach mogących wystąpić z GIT nie wspomniałem do tej pory. Niektóre z nich można łatwo rozwiązać korzystając ze skryptów i 'hooks', inne wymagają reorganizacji i ponownego zdefiniowania całego projektu, a na rozwiązanie kilku innych uniedogodnień możesz tylko uzbroić się w cierpliwość i czekać na ich rozwiązanie. Albo jeszcze lepiej, samemu się nimi zająć i spróbować pomóc. +O kilku problemach mogących wystąpić z Gitem nie wspomniałem do tej pory. Niektóre z nich można łatwo rozwiązać korzystając ze skryptów i 'hooks', inne wymagają reorganizacji i ponownego zdefiniowania całego projektu, a na rozwiązanie kilku innych uniedogodnień możesz tylko uzbroić się w cierpliwość i czekać na ich usunięcie. Albo jeszcze lepiej, samemu się nimi zająć i spróbować pomóc. === Słabości SHA1 === -Z biegiem czasu kryptografowie odkrywają coraz więcej słabości systemu SHA1. Już dzisiaj byłoby możliwe dla przedsiębiorstw dysponujących odpowiednimi zasobami finansowymi znaleźć kolizje w hashach Za kilka lat możliwe, że całkiem normalny domowy PC będzie dysponował odpowiednim zasobem mocy obliczeniowej, by skorumpować niepostrzeżenie repozytorium Gita. +Z biegiem czasu kryptografowie odkrywają coraz więcej słabości systemu SHA1. Już dzisiaj byłoby możliwe dla przedsięwzięć dysponujących odpowiednimi zasobami finansowymi znaleźć kolizje w hashach. Za kilka lat, całkiem możliwe, że normalny domowy PC będzie dysponował odpowiednim zasobem mocy obliczeniowej, by skorumpować niepostrzeżenie repozytorium Gita. -Miejmy nadzieję, że Git przestawi się na lepszą funkcje hashującą, zanim badania nad SHA1 zupełnie zrobią go bezużytecznym. +Miejmy nadzieję, że Git przestawi się na lepszą funkcje hashującą, zanim badania nad SHA1 zrobią go bezużytecznym. === Microsoft Windows === @@ -24,29 +24,29 @@ Jednym z możliwych rozwiązań mogłoby być podzielenie twojego projektu na ki === Kto nad czym pracuje? === -Niektóre systemy kontroli wersji zmuszają cię, by w jakiś sposób oznaczyć pliki nad którymi pracujesz. Mimo że jest to bardzo uciążliwe, gdyż wymaga ciągłej komunikacji z serwerem centralnym, posiada to też swoje zalety: +Niektóre systemy kontroli wersji zmuszają cię, by w jakiś sposób oznaczyć pliki nad którymi pracujesz. Mimo że jest to bardzo uciążliwe, gdyż wymaga ciągłej komunikacji z serwerem centralnym, posiada to też swoje zalety: 1. Różnice zostają szybko znalezione, ponieważ wystarczy skontrolować wyłącznie oznaczone pliki. 2. Każdy może szybko sprawdzić, kto aktualnie nad czym pracuje, sprawdzając na serwerze po prostu kto zaznaczył jakie dane do edycji. -Używając odpowiednich skryptów uda ci się to również przy pomocy Gita. Wymaga to jednak współdziałania programistów, ponieważ muszą również korzystać z tych skryptów podczas pracy nad plikiem. +Używając odpowiednich skryptów uda ci się to również przy pomocy Gita. Wymaga to jednak współdziałania programistów, ponieważ muszą również korzystać z tych skryptów podczas pracy nad projektem. === Historia pliku === -Ponieważ Git loguje zmiany tylko dla całości projektu jako takiego, rekonstrukcja przebiegu zmian pojedynczego pliku jest bardziej pracochłonna, niż w innych systemach, które kontrolują pojedyncze pliki. +Ponieważ Git loguje zmiany tylko dla całości projektu jako takiego, rekonstrukcja przebiegu zmian pojedynczego pliku jest bardziej pracochłonna, niż w innych systemach kontrolujących pojedyncze . -Te wady są w większości przypadków marginalne i nie są brane pod uwagę, ponieważ inne operacje są bardzo wydajne. Na przykład polecenie `git checkout` jest szybsze niż `cp -a`, zmiany w zakresie całego projektu daje się lepiej komprymować niż zbiór zmian na bazie pojedynczych plików. +Te wady są w większości przypadków uznawane za marginalne i nie są brane pod uwagę, ponieważ inne operacje są bardzo wydajne. Na przykład polecenie `git checkout` jest szybsze niż `cp -a`, zmiany w zakresie całego projektu daje się lepiej komprymować niż zbiór zmian na bazie pojedynczych plików. === Pierwszy klon === Wykonanie klonu jest kosztowniejsze niż w innych systemach kontroli wersji jeśli istnieje długa historia. -Początkowy koszt spłaca się jednak na dłuższą metę ponieważ większość przyszłych operacji przeprowadzane będzie szybko i offline. Niemniej jednak istnieją sytuacje, w których lepiej utworzyć powierzchowny klon korzystając z opcji `--depth`. Trwa to o wiele krócej, taki klon taki posiada też tylko ograniczoną funkcjonalność. +Początkowy koszt spłaca się jednak na dłuższą metę ponieważ większość przyszłych operacji przeprowadzane będzie szybko i offline. Niemniej jednak istnieją sytuacje, w których lepiej utworzyć powierzchowny klon korzystając z opcji `--depth`. Trwa to o wiele krócej, taki klon jednak posiada też tylko ograniczoną funkcjonalność. === Niestałe projekty === -Git został napisany z myślą optymalizacji prędkości działania przy dokonywaniu wielkich zmian. Ludzie robią jednak pomniejsze zmiany z wersji na wersję. Jakaś poprawka tutaj, jakaś nowa funkcja gdzie indziej, poprawienie komentarzy itd. Ale jeśli twoje dane znacznie się od siebie różnią pomiędzy następującymi po sobie wersjami, to chcąc nie chcąc przy każdym 'commit' projekt zwiększy się o twoje zmiany. +Git został napisany z myślą optymalizacji prędkości działania przy dokonywaniu wielkich zmian. Ludzie robią jednak pomniejsze zmiany z wersji na wersję. Jakaś poprawka tutaj, jakaś nowa funkcja gdzie indziej, poprawienie komentarzy, itd. Ale jeśli twoje dane znacznie się od siebie różnią pomiędzy następującymi po sobie wersjami, to chcąc nie chcąc przy każdym 'commit' projekt zwiększy się o te zmiany. Nie wymyślono jednak do tej pory niczego w żadnym systemie kontroli wersji, by móc temu zapobiec, tutaj jednak użytkownik Gita cierpi najbardziej, ponieważ w normalnym wypadku klonuje cały przebieg projektu. @@ -54,7 +54,7 @@ Powinno się w takim wypadku szukać powodów wystąpienia największych zmian. Może czasami bardziej wskazana byłaby baza danych, czy jakiś system archiwizacji zamiast systemu kontroli wersji. Na przykład nie jest dobrym sposobem zastosowanie systemu kontroli wersji do zarządzania zdjęciami wykonywanymi periodycznie przez kamerę internetową. -Jeśli dane ulegają ciągłym zmianom i naprawdę muszą być objęte kontrolą wersji, jedną z możliwości jest zastosowanie Git w scentralizowanej formie. Każdy może dokonywać pobieżnych klonów, które mało co lub wcale nie mają nic do czynienia z przebiegiem projektu. Oczywiście w takim wypadku wiele funkcji Gita nie będzie dostępnych a zmiany muszą być przekazywane w formie 'patch'. Prawdopodobnie będzie to dość dobrze działać, mimo iż nie jest do końca jasne komu potrzebna jest znajomość przebiegu tak ogromnej ilości niestabilnych danych. +Jeśli dane ulegają ciągłym zmianom i naprawdę muszą być objęte kontrolą wersji, jedną z możliwości jest zastosowanie Gita w scentralizowanej formie. Każdy może dokonywać pobieżnych klonów, które mało co lub wcale nie mają nic do czynienia z przebiegiem projektu. Oczywiście w takim wypadku wiele funkcji Gita nie będzie dostępnych a zmiany muszą być przekazywane w formie 'patch'. Prawdopodobnie będzie to dość dobrze działać, mimo iż nie jest do końca jasne komu potrzebna jest znajomość przebiegu tak ogromnej ilości niestabilnych danych. Innym przykładem może być projekt, który zależny jest od firmware przyjmującej kształt wielkiej danej w formie binarnej. Historia pliku firmware nie interesuje użytkownika, a zmiany nie pozwalają się wygodnie komprymować, wielkość repozytorium wzrasta niepotrzebnie o nowe wersje binarnego pliku firmware. @@ -62,9 +62,9 @@ W takim wypadku należałoby trzymać w repozytorium wyłącznie kod źródłowy === Licznik globalny === -Wiele systemów kontroli wersji udostępnia licznik, który jest zwiększany z każdym "commit". Git natomiast odwołuje się przy zmianach do klucza SHA1, który w wielu przypadkach jest lepszym rozwiązaniem. +Wiele systemów kontroli wersji udostępnia licznik, który jest zwiększany z każdym "commit". Git natomiast odwołuje się przy zmianach do sum kontrolnych SHA1, co w wielu przypadkach jest lepszym rozwiązaniem. -Niektórzy jednak przyzwyczaili się do tego licznika. Na szczęście, łatwo jest pisać skrypty, zwiększające stan licznika przy każdej aktualizacji centralnego repozytorium Gita. Może jako forma taga, który powiązany jest z kluczem SHA1 ostatniego 'commit'. +Niektórzy jednak przyzwyczaili się do tego licznika. Na szczęście, łatwo jest napisać skrypt zwiększający stan licznika przy każdej aktualizacji centralnego repozytorium Gita. Może w formie taga, który powiązany jest z sumą kontrolną ostatniego 'commit'. Każdy klon mógłby posiadać taki licznik, jednak byłby on prawdopodobnie bezużyteczny, ponieważ tylko licznik centralnego repozytoriom ma znaczenie. @@ -78,13 +78,13 @@ To raczej obecna implementacja Gita, a mniej jego konstrukcja, jest odpowiedzial Stereotypowy informatyk liczy od 0 zamiast 1. Niestety, w kwestii 'commits' Git nie podąża za tą konwencją. Wiele komend marudzi przed wykonaniem pierwszego 'commit'. Dodatkowo, różnego rodzaju krańcowe przypadki muszą być traktowane specjalnie, jak 'rebase' dla 'branch' o różniącym się pierwszym 'commit'. -Git zyskałby na zdefiniowaniu tzw. 'zero - commit', ponieważ zaraz po zainicjowaniu repozytorium, 'HEAD' otrzymałby 20 bajtowy klucz SHA1. Ten specjalny 'commit' reprezentowałby puste drzewo, bez rodziców, być może pradziad wszystkich repozytoriów. +Git zyskałby na zdefiniowaniu tzw. 'zero-commit', ponieważ zaraz po zainicjowaniu repozytorium, 'HEAD' otrzymałby 20 bajtowy hash SHA1. Ten specjalny 'commit' reprezentowałby puste drzewo, bez rodziców, być może pradziad wszystkich repozytoriów. Jeśli na przykład użytkownik wykonałby polecenie *git log*, zostałby poinformowany, że nie istnieje jeszcze żaden 'commit', gdzie na dzień dzisiejszy taka komenda wywoła błąd. Analogicznie dzieje się też z innymi poleceniami. Każdy inicjujący 'commit' byłby pochodną tego zerowego 'commit'. -Niestety występuje jeszcze kilka innych problemów. Jeśli chcemy scalić kilka 'branches' o różniących sie inicjalnych 'commits' i przeprowadzić 'rebase', musimy ręcznie ingerować. +Niestety występuje jeszcze kilka innych problemów. Jeśli chcemy scalić kilka 'branches' o różniących sie inicjalnych 'commits' i przeprowadzić 'rebase', musimy ingerować ręcznie. === Charakterystyka zastosowania === diff --git a/pl/grandmaster.txt b/pl/grandmaster.txt index 2bc9cd2..2854423 100644 --- a/pl/grandmaster.txt +++ b/pl/grandmaster.txt @@ -1,10 +1,10 @@ == Git dla zaawansowanych == -W międzyczasie powinnaś umieć odnaleźć się na stronach *git help* i rozumieć większość zagadnień. Mimo to może okazać się dość mozolne odnalezienie odpowiedniej komendy dla rozwiązania pewnych zadań. Może uda mi się zaoszczędzić ci trochę czasu: poniżej znajdziesz kilka recept, które były mi przydatne w przeszłości. +W międzyczasie powinnaś umieć odnaleźć się na stronach *git help* i rozumieć większość zagadnień. Mimo to może okazać się dość mozolne odnalezienie odpowiedniej komendy dla rozwiązania pewnego zadania. Może uda mi się zaoszczędzić ci trochę czasu: poniżej znajdziesz kilka przepisów, które były mi przydatne w przeszłości. === Publikowanie kodu źródłowego === -Git zarządza w moich projektach dokładnie tymi danymi, które chcę archiwizować i dać do dyspozycji innym użytkownikom. Aby utworzyć archiwum tar kodu źródłowego, używam polecenia +Git zarządza w moich projektach dokładnie tymi danymi, które chcę archiwizować i dać do dyspozycji innym użytkownikom. Aby utworzyć archiwum tar kodu źródłowego, używam polecenia: $ git archive --format=tar --prefix=proj-1.2.3/ HEAD @@ -39,17 +39,17 @@ Jeśli jesteś już zadowolony z wyniku, wpisz: by dokonać wybranych zmian. Uważaj tylko, by nie skorzystać z opcji *-a*, ponieważ wtedy git dokona 'commit' zawierający wszystkie zmiany. -A co, jeśli pracowałaś nad wieloma danymi w wielu różnych miejscach? Sprawdzenie każdej danej z osobna jest frustrujące i męczące zarówno. W takim wypadku skorzystaj z *git add -i*, obsługa tego polecenia może nie jest zbyt łatwa, za to jednak bardzo elastyczna. Kilkoma naciśnięciami klawiszy możesz wiele zmienionych plików dodać ('stage') albo usunąć z 'commit' ('unstage'), jak również sprawdzić, czy dodać zmiany dla poszczególnych plików. Alternaywnie możesz skorzystać z *git commit \--interactive*, polecenie to wykona automatycznie 'commit' gdy skończysz. +A co, jeśli pracowałaś nad wieloma danymi w wielu różnych miejscach? Sprawdzenie każdej danej z osobna jest zarówno rustrujące jak i męczące. W takim wypadku skorzystaj z *git add -i*, obsługa tego polecenia może nie jest zbyt łatwa, za to jednak bardzo elastyczna. Kilkoma naciśnięciami klawiszy możesz wiele zmienionych plików dodać ('stage') albo usunąć z 'commit' ('unstage'), jak również sprawdzić, czy dodać zmiany dla poszczególnych plików. Alternaywnie możesz skorzystać z *git commit \--interactive*, polecenie to wykona automatycznie 'commit' gdy skończysz. === Index: rusztowanie Gita === -Do tej pory staraliśmy się omijać sławny 'index', jednak przyszedł czas się nim zająć, aby móc wyjaśnić wszystko to co poznaliśmy do tej pory. Index jest tymczasowym rusztowaniem Git rzadko wymienia dane bezpośrednio między twoim projektem a swoją historią wersji. Raczej zapisuje on dane najpierw w indexie, dopiero po tym kopiuje dane z indexu na ich właściwe miejsce przeznaczenia. +Do tej pory staraliśmy się omijać sławny 'indeks', jednak przyszedł czas się nim zająć, aby móc wyjaśnić wszystko to co poznaliśmy do tej pory. Index jest tymczasową przechowalnią. Git rzadko wymienia dane bezpośrednio między twoim projektem a swoją historią wersji. Raczej zapisuje on dane najpierw w indeksie, dopiero po tym kopiuje dane z indeksu na ich właściwe miejsce przeznaczenia. -Na przykład polecenie *commit -a* jest właściwie procesem dwustopniowym. Pierwszy krok to stworzenie obrazu bieżącego statusu każdego monitorowanego pliku do indeksu. Drugim krokiem jest trwałe zapamiętanie obrazu do indeksu. Wykonanie 'commit' bez opcji *-a* wykona jedynie drugi wspomniany krok i ma jedynie sens, jeśli poprzednio wykonano komendę, która dokonała odpowiednich zmian w indexie, na przykład *git add*. +Na przykład polecenie *commit -a* jest właściwie procesem dwustopniowym. Pierwszy krok to stworzenie obrazu bieżącego statusu każdego monitorowanego pliku do indeksu. Drugim krokiem jest trwałe zapamiętanie obrazu do indeksu. Wykonanie 'commit' bez opcji *-a* wykona jedynie drugi wspomniany krok i ma jedynie sens, jeśli poprzednio wykonano komendę, która dokonała odpowiednich zmian w indeksie, na przykład *git add*. -Normalnie możemy ignorować indeks i udawać, że czytamy i zapisujemy bezpośrednio z historii. W tym wypadku chcemy posiadać jednak większą kontrolę, więc manipulujemy indeks. Tworzymy obraz niektórych, jednak nie wszystkich zmian w indeksie i zapamiętujemy trwale starannie dobrany obraz. +Normalnie możemy ignorować indeks i udawać, że czytamy i zapisujemy bezpośrednio z historii. W tym wypadku chcemy posiadać jednak większą kontrolę, więc manipulujemy indeks. Tworzymy obraz niektórych, jednak nie wszystkich zmian w indeksie i później zapamiętujemy trwale starannie dobrany obraz. -=== Nie trać głowy === +=== Nie trać głowy! === Identyfikator 'HEAD' zachowuje się jak kursor, który zwykle wskazuje na najmłodszy 'commit' i z każdym nowym 'commit' zostaje przesunięty do przodu. Niektóre komendy Gita pozwolą ci nim manipulować. Na przyklad: @@ -59,7 +59,7 @@ przesunie identyfikator 'HEAD' o 3 'commits' spowrotem. Spowoduje to, że wszyst Ale jak teraz wrócić znów do przyszłości? Poprzednie 'commits' nic nie wiedzą o jej istnieniu. -Jeśli posiadasz klucz SHA1 orginalnego 'HEAD', wtedy możesz wrócić komendą: +Jeśli posiadasz hash SHA1 orginalnego 'HEAD', wtedy możesz wrócić komendą: $ git reset 1b6d @@ -71,9 +71,9 @@ Wyobraź jednak sobie, że nigdy go nie notowałaś? Nie ma sprawy: Przy wykonyw Może się zdarzyć, że ORIG_HEAD nie wystarczy. Może właśnie spostrzegłaś, iż dokonałaś kapitalnego błędu i musisz wrócić się do bardzo starego 'commit' w zapomnianym 'branch'. -Standardowo Git zapamiętuje 'commit' przez przynajmniej 2 tygodnie, nawet jeśli poleciłaś zniszczyć 'branch' w którym istniał. Problemem staje się tutaj odnalezienie odpowieniego klucza SHA1. Możesz po kolei testować wszystkie klucze SHA1 w `.git/objects` i w ten sposób próbować odnaleźć szukany 'commit'. Istnieje jednak na to dużo prostszy sposób. +Standardowo Git zapamiętuje 'commit' przez przynajmniej 2 tygodnie, nawet jeśli poleciłaś zniszczyć 'branch' w którym istniał. Problemem staje się tutaj odnalezienie odpowieniej sumy kontrolnej SHA1. Możesz po kolei testować wszystkie hashe SHA1 w `.git/objects` i w ten sposób próbować odnaleźć szukany 'commit'. Istnieje jednak na to dużo prostszy sposób. -Git zapamiętuje każdy obliczony klucz SHA1 dla odpowiednich 'commit' w `.git/logs`. Podkatalog `refs` zawieza przebieg wszystkich aktywności we wszystkich 'branches', podczas gdy plik `HEAD` wszystkie klucze SHA1 które kiedykolwiek posiadał. Ostatnie możemy zastosować do odnalezienia kluczy SHA1 tych 'commits' które znajdowały się w nieuważnie usuniętym 'branch'. +Git zapamiętuje każdy obliczony hash SHA1 dla odpowiednich 'commit' w `.git/logs`. Podkatalog `refs` zawieza przebieg wszystkich aktywności we wszystkich 'branches', podczas gdy plik `HEAD` wszystkie klucze SHA1 które kiedykolwiek posiadał. Ostatnie możemy zastosować do odnalezienia sum kontrolnych SHA1 tych 'commits' które znajdowały się w nieuważnie usuniętym 'branch'. Polecenie 'reflog' daje nam do dyspozycji przyjazny interfejs do tych właśnie logów. Wypróbuj polecenie: @@ -103,9 +103,9 @@ wtedy 'commits' będą tylko wtedy usuwane, gdy ręcznie wykonasz polecenie *git === Budować na bazie Gita === -W prawdziwym unixowym świecie sama konstrukcja Gita pozwala na wykorzystanie go, jako komponent niskiego poziomu, przez inne aplikacje, jak na przykład interfejsy graficzne i aplikacje internetowe, alternatywne narzędzia konsoli, narzędzia patchujące, narzędzia pomocne w importowaniu i konwertowaniu i tak dalej. Nawek same polecenia git są czasami malutkimi skryptami, jak krasnoludki na ramieniu olbrzyma. Przykładając trochę ręki możesz adoptować Git do twoich własnych potrzeb. +W prawdziwym unixowym świecie sama konstrukcja Gita pozwala na wykorzystanie go jako funkcji niskiego poziomu przez inne aplikacje, jak na przykład interfejsy graficzne i aplikacje internetowe, alternatywne narzędzia konsoli, narzędzia patchujące, narzędzia pomocne w importowaniu i konwertowaniu i tak dalej. Nawek same polecenia Git są czasami malutkimi skryptami, jak krasnoludki na ramieniu olbrzyma. Przykładając trochę ręki możesz adoptować Git do twoich własnych potrzeb. -Prostą sztuczką może być korzystanie z zintegrowanej w git funkcji aliasu, by skrócić najczęściej stosowane polecenia: +Prostą sztuczką może być korzystanie z zintegrowanej w Git funkcji aliasu, by skrócić najczęściej stosowane polecenia: $ git config --global alias.co checkout $ git config --global --get-regexp alias # wyświetli aktualne aliasy @@ -120,13 +120,13 @@ pokaże nazwę aktualnego 'branch'. W praktyce chciałbyś raczej usunąć "refs $ git symbolic-ref HEAD 2> /dev/null | cut -b 12- -Podkatakog +contrib+ jest wielkim znaleziskiem narzędzi zbudowanych dla git. Z czasem niektóre z nich mogą uzyskać status oficjalnych poleceń. W dystrybucji Debian i Ubuntu znajdziemy ten katalog pod +/usr/share/doc/git-core/contrib+. +Podkatakog +contrib+ jest wielkim znaleziskiem narzędzi zbudowanych dla Gita. Z czasem niektóre z nich mogą uzyskać status oficjalnych poleceń. W dystrybucjach Debiana i Ubuntu znajdziemy ten katalog pod +/usr/share/doc/git-core/contrib+. -Ulubionym przedstawicielem jest +workdir/git-new-workdir+. Poprzez sprytne przelinkowania skrypt ten tworzy nowy katalog roboczy, który dzieli swoją historię wersji z orginalnym repozytorium: +Ulubionym przedstawicielem jest +workdir/git-new-workdir+. Poprzez sprytne przelinkowania skrypt ten tworzy nowy katalog roboczy, który dzieli swoją historię wersji z oryginalnym repozytorium: $ git-new-workdir istniejacy/repo nowy/katalog -Ten nowy katalog i znajdujące się w nim pliki można sobie wyobrazić jako klon, z tą różnicą, że ze względu na wspólną niepodzieloną historie obje wersje pozostaną zsynchronizowane. Synchronizacja za pomocą 'merge', 'push', czy 'pull' nie będzie konieczna. +Ten nowy katalog i znajdujące się w nim pliki można sobie wyobrazić jako klon, z tą różnicą, że ze względu na wspólną niepodzieloną historie obje wersje pozostaną zsynchronizowane. Synchronizacja za pomocą 'merge', 'push', czy 'pull' nie będzie konieczna. === Śmiałe wyczyny === @@ -150,9 +150,9 @@ Również nie uda się próba przesunięcia 'branch' poleceniem 'move', jeśliby $ git branch -M źródło cel # zamiast -m -Inaczej niż w przypadku 'checkout' i 'reset', te oba polecenia przesuną zniszczenie danych. Zmiany te zostaną zapisane w podkatalogu .git i mogą znów zostać przywrócone, jeśli znajdziemy odpowiedni kluch SHA1 w `.git/logs` (zobacz "Łowcy głów" powyżej). Standardowo dane te pozostają jeszcze przez 2 tygodnie. +Inaczej niż w przypadku 'checkout' i 'reset', te oba polecenia przesuną zniszczenie danych. Zmiany te zostaną zapisane w podkatalogu .git i mogą znów zostać przywrócone, jeśli znajdziemy odpowiedni hash SHA1 w `.git/logs` (zobacz "Łowcy głów" powyżej). Standardowo dane te pozostają jeszcze przez 2 tygodnie. -*clean*: Różnorakie polecenia Git nie chcą się zadziałać, ponieważ podejżewają konflikty z niewersjonowanymi danymi. Jeśli jesteś pewny, że wszystkie niezwersjonowane pliki i katalogi są zbędne, skasujesz je bezlitośnie poleceniem: +*clean*: Różnorakie polecenia Git nie chcą zadziałać, ponieważ podejżewają konflikty z niewersjonowanymi danymi. Jeśli jesteś pewny, że wszystkie niezwersjonowane pliki i katalogi są zbędne, skasujesz je bezlitośnie poleceniem: $ git clean -f -d @@ -176,4 +176,4 @@ Na początku *pre-commit* tego 'hook' umieściłbym dla ochrony przed rozdrobnie exit 1 fi -Wiele operacji Gita pozwala na używanie 'hooks'; zobacz też: *git help hooks*. We wcześniejszcm rozdziale "Git poprzez http" przytoczyliśmy przykład 'hook' dla *post-update*, który wykonywany jest zawsze, jeśli znacznik 'HEAD' zostaje przesunięty. Ten przykładowy skrypt 'post-update' aktualizuje dane, które potrzebne są do komunikacji poprzez 'Git-agnostic transports', jak na przykład HTTP. +Wiele operacji Gita pozwala na używanie 'hooks'; zobacz też: *git help hooks*. We wcześniejszym rozdziale "Git poprzez http" przytoczyliśmy przykład 'hook' dla *post-update*, który wykonywany jest zawsze, jeśli znacznik 'HEAD' zostaje przesunięty. Ten przykładowy skrypt 'post-update' aktualizuje dane, które potrzebne są do komunikacji poprzez 'Git-agnostic transports', jak na przykład HTTP. diff --git a/pl/history.txt b/pl/history.txt index f5fe423..bdbe2fd 100644 --- a/pl/history.txt +++ b/pl/history.txt @@ -1,8 +1,8 @@ == Lekcja historii == -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ć. +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ć. -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. +Niektórzy programiści zarzekają się w kwestii nienaruszalności historii - ze wszystkimi jej błędami i niedociągnięciami. Inni uważają, że odgałęzienia powinny dobrze się prezentować nim zostaną przedstawione publicznie. Git jest wyrozumiały dla obydwu 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. === Muszę się skorygować === @@ -16,13 +16,13 @@ Chcesz wprowadzić jeszcze inne zmiany do ostatniego 'commit'? Wykonaj je i wpis $ git commit --amend -a -=== ... i jeszcze coś === +=== ... i jeszcze coś === -Załóżmy, że poprzedni problem będzie 10 razy gorszy. Po dłuższej sesji zrobiłaś całą masę 'commits'. Nie jesteś jednak szczęśliwy z takiego zorganizowania a niektóre z 'commits' mogłyby być inaczej sformułowane. Wpisujesz: +Załóżmy, że poprzedni problem będzie 10 razy gorszy. Po dłuższej sesji zrobiłaś całą masę 'commits'. Nie jesteś jednak szczęśliwy z takiego zorganizowania, a niektóre z 'commits' mogłyby być inaczej sformułowane. Wpisujesz: $ git rebase -i HEAD~10 -i ostatnie 10 'commits' pojawią się w preferowanym przez ciebie edytorze. Przykładowy wyciąg: +a ostatnie 10 'commits' pojawią się w preferowanym przez ciebie edytorze. Przykładowy wyciąg: pick 5c6eb73 Added repo.or.cz link pick a311a64 Reordered analogies in "Work How You Want" @@ -41,7 +41,7 @@ Tutaj 5c6eb73 jest najstarszym 'commit', a 100834f najnowszym. By to zmienić: Na przykład chcemy zastąpić drugi `pick` na `squash`: -Zapamiętaj i zakończ. Jeśli zaznaczyłaś jakiś 'commit' poprzez 'edit', wpisz: +Zapamiętaj i zakończ. Jeśli zaznaczyłaś jakiś 'commit' do 'edit', wpisz: $ git commit --amend @@ -49,26 +49,23 @@ Zapamiętaj i zakończ. Jeśli zaznaczyłaś jakiś 'commit' poprzez 'edit', wpi squash a311a64 Reordered analogies in "Work How You Want" pick 100834f Added push target to Makefile -After we save and quit, Git merges a311a64 into 5c6eb73. Thus *squash* merges +Po zapamiętaniu i wyjściu Git połączy a311a64 z 5c6eb73. +Thus *squash* merges into the next commit up: think ``squash up''. -Git then combines their log messages and presents them for editing. The -command *fixup* skips this step; the squashed log message is simply discarded. +Git połączy wiadomości logów i zaprezentuje je do edycji. Polecenie *fixup* pominie ten krok, wciśnięte logi zostaną pominięte. -If you marked a commit with *edit*, Git returns you to the past, to the oldest -such commit. You can amend the old commit as described in the previous section, -and even create new commits that belong here. Once you're pleased with the -``retcon'', go forward in time by running: +Jeśli zaznaczyłeś 'commit' opcją *edit*, Git przeniesie cię do najstarszego takiego 'commit'. Możesz użyć 'amend', jak opisane w poprzednim rozdziale, i utworzyć nowy 'commit' mający się tu znaleźć. Gdy już będziesz zadowolony z ``retcon'', przenieś się na przód w czasie: $ git rebase --continue -Git replays commits until the next *edit*, or to the present if none remain. +Git powtarza 'commits' aż do następnego *edit* albo na przyszłość, jeśli żadne nie stoją na prożu. -You can also abandon the rebase with: +Możesz równierz zrezygnować z 'rebase': $ git rebase --abort -A więc, stosuj polecenie 'commit' wcześnie i często: możesz później posprzątać za pomocą 'rebase'. +A więc, stosuj polecenie 'commit' wcześnie i często: możesz później zawsze posprzątać za pomocą 'rebase'. === Lokalne zmiany na koniec === @@ -138,12 +135,12 @@ EOT ---------------------------------- -Następnie utwórz repozytorium git z tymczasowego pliku poprzez wpisanie: +Następnie utwórz repozytorium Git z tymczasowego pliku poprzez wpisanie: $ mkdir project; cd project; git init $ git fast-import --date-format=rfc2822 < /tmp/history -Aktualną wersję projektu możesz przywołać ('checkout') poprzez: +Aktualną wersję projektu możesz przywołać poprzez: $ git checkout master @@ -185,11 +182,11 @@ które komentuje każdą linię podanego pliku, by pokazać kto ją ostatnio zmi === Osobiste doświadczenia === -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. +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. 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. -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. +Dowiedziałem się o tym fenomenie na sobie samym. 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. 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. diff --git a/pl/multiplayer.txt b/pl/multiplayer.txt index 0be0ecd..3bab68e 100644 --- a/pl/multiplayer.txt +++ b/pl/multiplayer.txt @@ -1,12 +1,12 @@ == Multiplayer Git == -Na początku zastosowałem git przy prywatnym projekcie, gdzie byłem jedynym developerem. Z poleceń w związku z rozproszoną naturą git, potrzebowałem jedynie poleceń *pull* i *clone*, dzięki czemu mogłem trzymać ten sam projekt w kilku miejscach. +Na początku zastosowałem Git w prywatnym projekcie, gdzie byłem jedynym programistą. Z poleceń, w związku z rozproszoną naturą Gita, potrzebowałem jedynie komende *pull* i *clone*, dzięki czemu mogłem trzymać ten sam projekt w kilku miejscach. -Później chciałem opublikować mój kod za pomocą git i dołączyć zmiany kolegów Musiałem nauczyć się zarządzać projektami, nad którymi zaangażowani byli programiści z całego świata. Na szczęście jest to silną stroną git i chyba jego racją bytu. +Później chciałem opublikować mój kod za pomocą Gita i dołączyć zmiany kolegów. Musiałem nauczyć się zarządzać projektami, nad którymi zaangażowani byli programiści z całego świata. Na szczęście jest to silną stroną Gita i chyba jego racją bytu. === Kim jestem? === -Każdy 'commit' otrzymuje nazwę i adres e-mail autora, które zostaną pokazane w *git log*. Standardowo git korzysta z ustawień systemowych do wypełnienia tych pól. Aby wprowadzić te dane bezpośrednio, podaj: +Każdy 'commit' otrzymuje nazwę i adres e-mail autora, które zostaną pokazane w *git log*. Standardowo Git korzysta z ustawień systemowych do wypełnienia tych pól. Aby wprowadzić te dane bezpośrednio, podaj: $ git config --global user.name "Jan Kowalski" $ git config --global user.email jan.kowalski@example.com @@ -15,7 +15,7 @@ Jeśli opóścisz przełącznik '--global' zmiany zostaną zastosowane wyłączn === Git przez SSH, HTTP === -Załóżmy, posiadasz dostęp 'SSH' do serwera stron internetowych, gdzie jednak Git nie został zainstalowany. Nawet, jeśli jest to mniej efektywne jak własny protokół 'GIT', Git potrafi komunikować się przez 'HTTP'. +Załóżmy, posiadasz dostęp SSH do serwera stron internetowych, gdzie jednak Git nie został zainstalowany. Nawet, jeśli jest to mniej efektywne jak rodzimy protokół 'GIT', Git potrafi komunikować się również przez HTTP. Zładuj Git, skompiluj i zainstaluj pod własnym kontem oraz utwórz repozytorium w twoim katalogu strony internetowej. @@ -26,13 +26,13 @@ Zładuj Git, skompiluj i zainstaluj pod własnym kontem oraz utwórz repozytoriu Przy starszych wersjach Gita samo polecenie 'cp' nie wystarczy, wtedy musisz jeszcze: - chmod a+x hooks/post-update + $ chmod a+x hooks/post-update Od teraz możesz publikować aktualizacje z każdego klonu poprzez SSH. $ git push web.server:/sciezka/do/proj.git master -i każdy może teraz sklonować twój projekt przez: +i każdy może teraz sklonować twój projekt przez HTTP: $ git clone http://web.server/proj.git @@ -44,8 +44,7 @@ Nadawca tworzy 'bundle': $ git bundle create plik HEAD -i transportuje 'bundle' +plik+ do innych zaangażowanych: przez e-mail, pendrive, *xxd* hexdump i skaner OCR, kod morsea, przez telefon, znaki dymne itd. Odbiorca wyciąga 'commits' z 'bundle' poprzez podanie: - +i transportuje 'bundle' +plik+ do innych zaangażowanych: przez e-mail, pendrive, *xxd* hexdump i skaner OCR, kod morsea, przez telefon, znaki dymne, itd. Odbiorca wyciąga 'commits' z 'bundle' poprzez podanie: $ git pull plik @@ -53,7 +52,6 @@ Odbiorca może to zrobić z pustym repozytorium. Mimo swojej wielkości +plik+ z W dużych projektach unikniesz śmieci danych, jeśli tylko zrobisz 'bundle' zmian brakujących w innych repozytoriach. Na przykład załóżmy, że 'commit' ``1b6d...'' jest najaktualniejszym, które posiadają obie partie: - $ git bundle create plik HEAD ^1b6d Jeśli robi się to regularnie, łatwo można zapomnieć, który 'commit' został wysłany ostatnio. Strony pomocy zalecają stosowanie tagów, by rozwiązać ten problem. To znaczy, po wysłaniu 'bundle', podaj: @@ -72,7 +70,7 @@ Przypomnij sobie pierwszy rozdział: $ git diff 1b6d > mój.patch -produkuje 'patch', który można dołączyć do maila dla dalszej dyskusji. W repozytorium git natomiast podajesz: +produkuje 'patch', który można dołączyć do e-maila dla dalszej dyskusji. W repozytorium Git natomiast podajesz: $ git apply < mój.patch @@ -92,9 +90,9 @@ Po stronie odbiorcy zapamiętaj e-mail jako daną i podaj: Patch zostanie wprowadzony i utworzy commit, włącznie z informacjami jak na przykład informacje o autorze. -Jeśli stosujesz webmail musisz ewentualnie poszukać opcji pokazania treści w formie niesformatowanego textu , zanim zapamiętasz patch do pliku. +Jeśli stosujesz webmail musisz ewentualnie poszukać opcji pokazania treści w formie niesformatowanego textu, zanim zapamiętasz patch do pliku. -Występują minimalne różnice między aplikacjami e-mailowymi bazującymi na mbox, ale jeśli korzystasz z takiej, należysz do grupy ludzi która za pewne umie się z nimi obchodzić bez czytania instrukcji! +Występują minimalne różnice między aplikacjami e-mailowymi bazującymi na mbox, ale jeśli korzystasz z takiej, należysz do grupy ludzi, która za pewne umie się z nimi obchodzić bez czytania instrukcji! === Przepraszamy, przeprowadziliśmy się === @@ -102,15 +100,15 @@ Po sklonowaniu repozytorium, polecenia *git push* albo *git pull* będą automat $ git config --list -Opcja +remote.origin.url+ kontroluje źródłowe URL; ``origin'' to alias, nadany źródłowemu repozytorium. Tak jak i przy konwencji z ``master'' 'Branch' , możemy ten alias zmienić albo skasować, zwykle jednak nie ma powodów by to robić. +Opcja +remote.origin.url+ kontroluje źródłowe URL; ``origin'' to alias, nadany źródłowemu repozytorium. Tak jak i przy konwencji z 'master branch', możemy ten alias zmienić albo skasować, zwykle jednak nie ma powodów by to robić. Jeśli oryginalne repozytorium zostanie przesunięte, możemy zaktualizować link poprzez: $ git config remote.origin.url git://nowy_link/proj.git -Opcja +branch.master.merge+ definiuje standardowy remote-'Branch' dla *git pull*. Podczas początkowego klonowania, zostanie ustawiony na aktualny branch źródłowego repozytorium, że nawet i po tym jak 'HEAD' źródłowego repozytorium przejdzie do innego branch, późniejszy 'pull' pozostanie wierny oryginalnemu branch. +Opcja +branch.master.merge+ definiuje standardowy 'remote-branch' dla *git pull*. Podczas początkowego klonowania, zostanie ustawiony na aktualny branch źródłowego repozytorium, że nawet i po tym jak 'HEAD' źródłowego repozytorium przejdzie do innego branch, późniejszy 'pull' pozostanie wierny oryginalnemu branch. -Ta opcja jest ważna jedynie dla repozytorium, z którego dokonało się pierwsze klonowanie, co zapisane jest w opcji +branch.master.remote+. Przy 'pull' z innego repozytorium musimy podać z którego branch chcemy korzystać. +Ta opcja jest ważna jedynie dla repozytorium, z którego dokonało się pierwszego klonowania, co zapisane jest w opcji +branch.master.remote+. Przy 'pull' z innego repozytorium musimy podać z którego branch chcemy korzystać. $ git pull git://example.com/inny.git master @@ -128,41 +126,41 @@ Powinieneś zobaczyć coś jak: origin/HEAD origin/master origin/experimental -Lista ta ukazuje branches i HEAD odległego repozytorium, które mogą być również stosowane w zwykłych poleceniach Git. Przyjmijmy, na przykład, że wykonałaś wiele commits i chciałbyś uzyskać porównanie do ostatnio ściągniętej wersji. Możesz przeszukać logi za odpowiednim kluczem SHA1, ale dużo prościej jest podać: +Lista ta ukazuje branches i HEAD odległego repozytorium, które mogą być również stosowane w zwykłych poleceniach Git. Przyjmijmy, na przykład, że wykonałaś wiele commits i chciałbyś uzyskać porównanie do ostatnio ściągniętej wersji. Możesz przeszukać logi za odpowiednim hashem SHA1, ale dużo prościej jest podać: $ git diff origin/HEAD -Możesz też sprawdzić co działo się w 'Branch' ``experimental'' +Możesz też sprawdzić co działo się w 'branch' ``experimental'': $ git log origin/experimental === Więcej serwerów === -Przyjmijmy, dwóch innych programistów pracuje nad twoim projektem i chcielibyśmy mieć ich na oku. Możemy obserwować więcej niż jedno reposytorium jednocześnie: +Przyjmijmy, dwóch innych programistów pracuje nad twoim projektem i chciałabyś mieć ich na oku. Możemy obserwować więcej niż jedno repozytorium jednocześnie: $ git remote add inny git://example.com/jakies_repo.git $ git pull inny jakis_branch -Teraz przyłączyliśmy jeden branch z dwóch repozytoriów i uzyskaliśmy łatwy dostęp do wszystkich branch z wszystkich repozytoriów. +Teraz przyłączyliśmy jeden 'branch' z dwóch repozytoriów i uzyskaliśmy łatwy dostęp do wszystkich 'branch' z wszystkich repozytoriów. $ git diff origin/experimental^ inny/jakiś_branch~5 -Co jednak zrobić, gdy chcemy porównać zmiany w nich bez wpływu na naszą pracę? Innymi słowami, chcemy zbadać ich branches bez importowania ich zmian do naszego katalogu roboczego. Zamiast 'pull' skorzystaj z: +Co jednak zrobić, gdy chcemy porównać zmiany w nich bez wpływu na naszą pracę? Innymi słowami, chcemy zbadać ich 'branches' bez importowania ich zmian do naszego katalogu roboczego. Zamiast 'pull' skorzystaj z: - $ git fetch # Fetch z origin, jako standard. + $ git fetch # Fetch z origin, standard. $ git fetch inne # Fetch od drugiego programisty. Polecenie to załaduje jedynie historię Mimo, że nasz katalog pozostał bez zmian, możemy teraz referować z każdego repozytorium poprzez polecenia Gita, ponieważ posiadamy lokalną kopię. Przypomnij sobie, że 'pull' za kulisami to to samo co 'fetch' z następującym za nim *merge*. W normalnym wypadku wykonalibyśmy *pull*, bo chcielibyśmy przywołać również ostatnie 'commmits'. Ta przywołana sytuacja jest wyjątkiem wartym wspomnienia. -Sprawdź *git help remote* by zobaczyć, jak usuwa się repozytoria, ignoruje pewne branches i więcej- +Sprawdź *git help remote* by zobaczyć, jak usuwa się repozytoria, ignoruje pewne branches i więcej. === Moje ustawienia === -W moich projektach preferuję, gdy pomagający mi programiści przygotują własne repozytoria, z których mogę wykonać 'pull'. Większość hosterów Gita pozwala na utworzenie jednym kliknięciem twojego własnego forka innego projektu. +W moich projektach preferuję, gdy pomagający mi programiści przygotują własne repozytoria z których mogę wykonać 'pull'. Większość hosterów Gita pozwala na utworzenie jednym kliknięciem twojego własnego forka innego projektu. -Gdy przywołałem moją gałęź korzystam z poleceń Gita dla nawigacji i kontroli zmian, które najłepiej gdy są dobrze zorganizowane i udokumentowane. Wykonuję 'merge' moich własnych zmian i przeprowadzam ewentualnie dalsze zmiany. Gdy już jestem zadowolony, 'push' do zentralnego repozytorium.- +Gdy przywołałem moją gałęź korzystam z poleceń Gita dla nawigacji i kontroli zmian, które najlepiej, gdy są dobrze zorganizowane i udokumentowane. Wykonuję 'merge' moich własnych zmian i przeprowadzam ewentualnie dalsze zmiany. Gdy już jestem zadowolony, 'push' do zentralnego repozytorium. Mimo, iż dość rzadko otrzymuję posty, jestem zdania, że ta metoda się opłaca. Zobacz http://torvalds-family.blogspot.com/2009/06/happiness-is-warm-scm.html[Post na Blogu Linusa Torvalds (po angielsku)]. diff --git a/pl/secrets.txt b/pl/secrets.txt index 3c4d30d..451738a 100644 --- a/pl/secrets.txt +++ b/pl/secrets.txt @@ -4,9 +4,9 @@ Rzućmy spojrzenie pod maskę silnika i wytłumaczymy w jaki sposób Git realizu === Niewidzialność === -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 w ogóle nie istniała. To znaczy - do czasu aż będzie ci potrzebna. A oto chodzi, byś był zadowolony z tego, że Git cały czas czuwa nad twoją pracą +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 w ogóle nie istniała. Chciałem powiedzieć, do czasu aż będzie ci potrzebna. A oto chodzi, byś był zadowolony z tego, że Git cały czas czuwa nad twoją pracą. -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ć zabezpieczone 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. +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ć zabezpieczone 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. 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. @@ -16,7 +16,7 @@ Z kryptografią przez większość ludzi łączona jest poufność informacji, j 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. -Sam klucz 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 wykorzystuje je Git dla zapewnienia produktywności i integralności danych. +Sama suma konreolna SHA1 też jest łańcuchem znaków w formie bajtów. Możemy generować hashe SHA1 z łańcuchów samych zawierających inne hashe 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 wykorzystuje je Git dla zapewnienia produktywności i integralności danych. 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. @@ -28,7 +28,7 @@ Git poszukuje heurystycznie zmian nazw w następujących po sobie wersjach kopii === Indeksowanie === -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. +Dla każdego kontrolowanego pliku, Git zapamiętuje informacje o jego wielkości, czasie utworzenia i czasie ostatniej edycji w pliku znanym nam jako indeks. 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. 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. @@ -40,7 +40,7 @@ Ten http://lkml.org/lkml/2005/4/6/121['Linux Kernel Mailing List' post] opisuje === Obiektowa baza danych === -Każda wersja twoich danych jest przechowywana w obiektowej bazie danych, która znajduje się 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 jednak elegancka i jest źródłem siły Gita. +Każda wersja twoich danych jest przechowywana w obiektowej bazie danych, która znajduje się 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 jednak elegancka i jest źródłem siły Gita. Każdy plik w `.git/objects` jest obiektem. Istnieją trzy rodzaje obiektów, które nas interesują: 'blob', 'tree' i 'commit'. @@ -57,7 +57,7 @@ Na początek magiczna sztuczka. Wymyśl jakąś nazwę pliku, jakąkolwiek. W pu Zobaczysz coś takiego: +.git/objects/aa/823728ea7d592acc69b36875a482cdf3fd5c8d+. -Skąd mogłem to wiedzieć, mimo iż nie znałem nazwy pliku? Ponieważ wartość klucza SHA1 dla: +Skąd mogłem to wiedzieć, mimo iż nie znałem nazwy pliku? Ponieważ suma kontrolna SHA1 dla: "blob" SP "6" NUL "sweet" LF @@ -65,7 +65,7 @@ wynosi właśnie: aa823728ea7d592acc69b36875a482cdf3fd5c8d. Przy czym SP to spa $ printf "blob 6\000sweet\n" | sha1sum -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 obiektu '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 obiektu i jego wielkość w bajtach, pozwala to na uproszczenie zarządzania wewnętrznego. +Git pracuje asocjacyjnie (skojarzeniowo): dane nie są zapamiętywane na podstawie ich nazwy, tylko wartości ich własnego hasha SHA1 w pliku, który określamy mianem obiektu 'blob'. Sumę kontrolną 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 tylko rodzaj obiektu i jego wielkość w bajtach, pozwala to na uproszczenie zarządzania wewnętrznego. Przez to właśnie mogłem 'przepowiedzieć' wynik. Nazwa pliku nie ma znaczenia, jedynie jego zawartość służy do utworzenia obiektu 'blob'. @@ -90,7 +90,7 @@ Powinieneś ujrzeć teraz 3 obiekty. Tym razem nie jestem w stanie powiedzieć, $ git filter-branch --tree-filter 'mv TWOJA_NAZWA rose' $ find .git/objects -type f -Powinnaś zobaczyć teraz plik +.git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9+, ponieważ jest to klucz SHA1 jego zawartości. +Powinnaś zobaczyć teraz plik +.git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9+, ponieważ jest to suma kontrolna SHA1 jego zawartości. "tree" SP "32" NUL "100644 rose" NUL 0xaa823728ea7d592acc69b36875a482cdf3fd5c8d @@ -98,22 +98,22 @@ Sprawdź, czy plik na prawdę odpowiada powyższej zawartości przez polecenie: $ echo 05b217bb859794d08bb9e4f7f04cbda4b207fbe9 | git cat-file --batch -Za pomocą 'zpipe' łatwo sprawdzić klucz SHA1: +Za pomocą 'zpipe' łatwo sprawdzić hash SHA1: $ zpipe -d < .git/objects/05/b217bb859794d08bb9e4f7f04cbda4b207fbe9 | sha1sum Sprawdzanie za pomocą 'cat-file' jest troszeczkę kłopotliwe, bo jego 'output' zawiera więcej niż tylko nieskomprymowany obiekt pliku. -Nasz plik to tak zwany obiekt '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 obiektu 'blob' zawierającego zawartość `rose`. Inne możliwe rodzaje plików to programy, linki symboliczne i katalogi. W ostatnim przypadku klucz SHA1 wskazuje na obiekt 'tree'. +Nasz plik to tak zwany obiekt 'tree': lista wyrażeń, na którą składają się rodzaj pliku, jego nazwa i jego suma kontrolna SHA1. W naszym przykładzie typ pliku to 100644, co oznacza, że `rose` jest plikiem zwykłym, natomiast hash SHA1 odpowiada sumie kontrolnej SHA1 obiektu 'blob' zawierającego zawartość `rose`. Inne możliwe rodzaje plików to programy, linki symboliczne i katalogi. W ostatnim przypadku hash SHA1 wskazuje na obiekt 'tree'. -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. +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 karencji, chcemy się ich pozbyć od zaraz, aby lepiej prześledzić następne przykłady. $ rm -r .git/refs/original $ git reflog expire --expire=now --all $ git prune -W prawdziwych projektach powinnaś unikać takich komend, ponieważ zniszczą zabezpieczone dane. Jeśli chcesz posiadać czyste repozytorium, to najlepiej załóż nowy klon. Bądź też ostrożna przy bezpośredniej manipulacji +.git+: 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. +W prawdziwych projektach powinnaś unikać takich komend, ponieważ zniszczą zabezpieczone dane. Jeśli chcesz posiadać czyste repozytorium, to najlepiej załóż nowy klon. Bądź też ostrożna przy bezpośredniej manipulacji +.git+: 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. === 'Commits' === @@ -124,7 +124,7 @@ Wytłumaczyliśmy dwa z trzech obiektów. Ten trzeci to obiekt 'commit' Jego zaw $ find .git/objects -type f $ find .git/objects -type f -Powinieneś znaleźć +.git/objects/49/993fe130c4b3bf24857a15d7969c396b7bc187+, co odpowiada kluczowi SHA1 jego zawartości: +Powinieneś znaleźć +.git/objects/49/993fe130c4b3bf24857a15d7969c396b7bc187+, co odpowiada sumie kontrolnej SHA1 jego zawartości: "commit 158" NUL "tree 05b217bb859794d08bb9e4f7f04cbda4b207fbe9" LF "author Alice 1234567890 -0800" LF "committer Bob 1234567890 -0800" LF LF "Shakespeare" LF @@ -134,13 +134,13 @@ To jest pierwszy 'commit', przez to nie posiada matczynych 'commits'. Następuj === Nie do odróżnienia od magii === -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. +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, przyprawienie plikami 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 w objektową bazę danych, co jest optymalne dla kontroli wersji. -Przyjmijmy, gdy jakikolwiek plik w obiektowej bazie danych ulegnie zniszczeniu poprzez błąd nośnika, to jego SHA1 nie będzie zgadzać się z 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 obiekty 'tree', 'blob' i rodziców 'commit'. Obiektowa baza dynch jest odporna na nieoczekiwane przerwy, jak na przykład przerwanie dostawy prądu. +Przyjmijmy, gdy jakikolwiek plik w obiektowej bazie danych ulegnie zniszczeniu poprzez błąd nośnika, to jego SHA1 nie będzie zgadzać się z 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, to znaczy, 'commit' nie potrafi zapamiętać jedynie części zmian: hash SHA1 'commit' możemy obliczyć i zapamiętać dopiero po tym gdy zapamiętane zostały wszystkie obiekty 'tree', 'blob' i rodziców 'commit'. Obiektowa baza dynch jest odporna na nieoczekiwane przerwy, jak na przykład przerwanie dostawy prądu. -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łby zmienić klucze SHA1 korespondujących obiektów, ponieważ plik zawiera teraz zmieniony sznur znaków. To znaczy również, że musiałabyś zmienić każdy klucz obiektu 'tree', które ją referują oraz w wyniku tego wszystkie klucze 'commits' zawierające obiekty 'tree' dodatkowo do pochodnych tych 'commits'. Oznacza to również, że klucz oficjalnego HEAD różni się od klucza HEAD manipulowanego repozytorium. Wystarczy teraz prześledzić ścieżkę różniących się kluczy SHA1, odnaleźć okaleczony plik, jak i 'commit' w którym po raz pierwszy wystąpił. +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łby zmienić sumy kontrolne SHA1 korespondujących obiektów, ponieważ plik zawiera teraz zmieniony sznur znaków. To znaczy również, że musiałby zmienić każdy hash obiektu 'tree', które ją referują oraz w wyniku tego wszystkie sumy kontrolne 'commits' zawierające obiekty 'tree' dodatkowo do pochodnych tych 'commits'. Oznacza to również, że suma kontrolna oficjalnego HEAD różni się od sumy kontrolnej HEAD manipulowanego repozytorium. Wystarczy teraz prześledzić ścieżkę różniących się hashy SHA1, odnaleźć okaleczony plik, jak i 'commit' w którym po raz pierwszy wystąpił. Krótko mówiąc, dopuki reprezentujące ostatni commit 20 bajtów są zabezpieczone, sfałszowanie repozytorium Gita nie jest możliwe. A co ze sławnymi możliwościami Gita? -'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ń. +'Branching'? 'Merging'? 'Tags'? To szczegół. Aktualny HEAD przetrzymywany jest w pliku +.git/HEAD+, która posiada hash SHA1 ostatniego 'commit'. Hash 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ń.