From 8c4cc4ad3d4be79fda6cb3109956d33bf984ca94 Mon Sep 17 00:00:00 2001 From: Dimitar Bonev Date: Thu, 28 Feb 2013 00:33:41 +0200 Subject: [PATCH 001/862] highlight the existence of git 'tree' object type to distinguish it (e.g. from file system tree) --- en/03-git-branching/01-chapter3.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/03-git-branching/01-chapter3.markdown b/en/03-git-branching/01-chapter3.markdown index 6dc212b55..a1ed3993f 100644 --- a/en/03-git-branching/01-chapter3.markdown +++ b/en/03-git-branching/01-chapter3.markdown @@ -15,7 +15,7 @@ To visualize this, let’s assume that you have a directory containing three fil $ git add README test.rb LICENSE $ git commit -m 'initial commit of my project' -When you create the commit by running `git commit`, Git checksums each subdirectory (in this case, just the root project directory) and stores those tree objects in the Git repository. Git then creates a commit object that has the metadata and a pointer to the root project tree so it can re-create that snapshot when needed. +Running `git commit` checksums all project directories and stores them as `tree` objects in the Git repository. Git then creates a `commit` object that has the metadata and a pointer to the root project `tree` object so it can re-create that snapshot when needed. Your Git repository now contains five objects: one blob for the contents of each of your three files, one tree that lists the contents of the directory and specifies which file names are stored as which blobs, and one commit with the pointer to that root tree and all the commit metadata. Conceptually, the data in your Git repository looks something like Figure 3-1. From 8a103a8e06460ba227e30b62672d6ef90178ef3f Mon Sep 17 00:00:00 2001 From: Tomasz Jakub Skrynnyk Date: Wed, 11 Sep 2013 22:19:17 +0200 Subject: [PATCH 002/862] [pl] Spelling/typo fixes. --- pl/03-git-branching/01-chapter3.markdown | 10 +++---- pl/04-git-server/01-chapter4.markdown | 26 +++++++++---------- pl/06-git-tools/01-chapter6.markdown | 2 +- pl/07-customizing-git/01-chapter7.markdown | 18 ++++++------- pl/08-git-and-other-scms/01-chapter8.markdown | 6 ++--- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/pl/03-git-branching/01-chapter3.markdown b/pl/03-git-branching/01-chapter3.markdown index 003851d46..d0538f3aa 100644 --- a/pl/03-git-branching/01-chapter3.markdown +++ b/pl/03-git-branching/01-chapter3.markdown @@ -268,7 +268,7 @@ Jeśli chcesz do rozwiązania tych problemów użyć narzędzia graficznego, mo {remote}: modified Hit return to start merge resolution tool (opendiff): -Jeśli chcesz użyć narzędzia innego niż domyślne (Git w tym przypadku wybrał dla mnie `opendiff`, ponieważ pracuję na Maku), możesz zobaczyć wszystkie wspierane narzędzia wymienione na samej górze, zaraz za „merge tool candidates”. Wpisz nazwę narzędzia, którego wolałbyś użyć. W Rozdziale 7 dowiemy się, jak zmienić domyślną wartość dla Twojego środowiska pracy. +Jeśli chcesz użyć narzędzia innego niż domyślne (Git w tym przypadku wybrał dla mnie `opendiff`, ponieważ pracuję na Maku), możesz zobaczyć wszystkie wspierane narzędzia wymienione na samej górze, zaraz za „merge tool candidates”. Wpisz nazwę narzędzia, którego wolałbyś użyć. W Rozdziale 7 dowiemy się, jak zmienić domyślną wartość dla twojego środowiska pracy. Po opuszczeniu narzędzia do scalania, Git zapyta, czy wszystko przebiegło pomyślnie. Jeśli odpowiesz skryptowi, że tak właśnie było, plik zostanie umieszczony w poczekalni, by konflikt oznaczyć jako rozwiązany. @@ -328,7 +328,7 @@ Aby zobaczyć wszystkie gałęzie zawierające zmiany, których jeszcze nie scal $ git branch --no-merged testing -Pokazuje to Twoją drugą gałąź. Ponieważ zawiera ona zmiany, które nie zostały jeszcze scalona, próba usunięcia jej poleceniem `git branch -d` nie powiedzie się: +Pokazuje to Twoją drugą gałąź. Ponieważ zawiera ona zmiany, które nie zostały jeszcze scalone, próba usunięcia jej poleceniem `git branch -d` nie powiedzie się: $ git branch -d testing error: The branch 'testing' is not an ancestor of your current HEAD. @@ -356,7 +356,7 @@ Ogólnie łatwiej jest myśleć o nich jak o silosach na zmiany, gdzie grupy zmi Insert 18333fig0319.png Figure 3-19. Może być ci łatwiej myśleć o swoich gałęziach jak o silosach. -Możesz powielić ten schemat na kilka poziomów stabilności. Niektóre większe projekty posiadają dodatkowo gałąź `proposed` albo `pu` („proposed updates” — proponowane zmiany), scalającą gałęzie, które nie są jeszcze gotowe trafić do gałęzi `next` czy `master`. Zamysł jest taki, że Twoje gałęzie reprezentują różne poziomy stabilności; kiedy osiągają wyższy stopień stabilności, są scalane do gałęzi powyżej. +Możesz powielić ten schemat na kilka poziomów stabilności. Niektóre większe projekty posiadają dodatkowo gałąź `proposed` albo `pu` („proposed updates” — proponowane zmiany), scalającą gałęzie, które nie są jeszcze gotowe trafić do gałęzi `next` czy `master`. Zamysł jest taki, że twoje gałęzie reprezentują różne poziomy stabilności; kiedy osiągają wyższy stopień stabilności, są scalane do gałęzi powyżej. Podobnie jak poprzednio, posiadanie takich długodystansowych gałęzi nie jest konieczne, ale często bardzo pomocne, zwłaszcza jeśli pracujesz przy dużych, złożonych projektach. ### Gałęzie tematyczne ### @@ -410,7 +410,7 @@ Figure 3-26. Dostajesz lokalny odnośnik do gałęzi master w repozytorium teamo ### Wypychanie zmian ### -Jeśli chcesz podzielić się swoją gałęzią ze światem, musisz wypchnąć zmiany na zdalny serwer, na którym posiadasz prawa zapisu. Twoje lokalne gałęzie nie są automatycznie synchronizowane z serwerem, na którym zapisujesz - musisz jawnie określić gałęzie, których zmianami chcesz się podzielić. W ten sposób możesz używać prywatnych gałęzi do pracy, której nie chcesz dzielić, i wypychać jedynie gałęzie tematyczne, w ramach których współpracujesz. +Jeśli chcesz podzielić się swoją gałęzią ze światem, musisz wypchnąć zmiany na zdalny serwer, na którym posiadasz prawa zapisu. twoje lokalne gałęzie nie są automatycznie synchronizowane z serwerem, na którym zapisujesz - musisz jawnie określić gałęzie, których zmianami chcesz się podzielić. W ten sposób możesz używać prywatnych gałęzi do pracy, której nie chcesz dzielić, i wypychać jedynie gałęzie tematyczne, w ramach których współpracujesz. Jeśli posiadasz gałąź o nazwie `serverfix`, w której chcesz współpracować z innymi, możesz wypchnąć swoje zmiany w taki sam sposób jak wypychałeś je w przypadku pierwszej gałęzi. Uruchom `git push (nazwa zdalnego repozytorium) (nazwa gałęzi)`: @@ -470,7 +470,7 @@ Załóżmy, że skończyłeś pracę ze zdalną gałęzią - powiedzmy, że ty i To git@github.com:schacon/simplegit.git - [deleted] serverfix -Bum. Nie ma już na serwerze tej gałęzi. Jeśli chcesz, zaznacz sobie tą stronę ponieważ będziesz potrzebował tego polecenia, a najprawdopodobniej zapomnisz jego składni. Polecenie to można spróbować zapamiętać przypominając sobie składnię `git push [nazwa zdalnego repozytorium] [gałąź lokalna]:[gałąź zdalna]`, którą omówiliśmy odrobinę wcześniej. Pozbywając się części [gałąź lokalna], mówisz mniej więcej "Weź nic z mojej strony i zrób z tego [gałąź zdalną]". +Bum. Nie ma już na serwerze tej gałęzi. Jeśli chcesz, zaznacz sobie tę stronę, ponieważ będziesz potrzebował tego polecenia, a najprawdopodobniej zapomnisz jego składni. Polecenie to można spróbować zapamiętać przypominając sobie składnię `git push [nazwa zdalnego repozytorium] [gałąź lokalna]:[gałąź zdalna]`, którą omówiliśmy odrobinę wcześniej. Pozbywając się części [gałąź lokalna], mówisz mniej więcej "Weź nic z mojej strony i zrób z tego [gałąź zdalną]". ## Zmiana bazy ## diff --git a/pl/04-git-server/01-chapter4.markdown b/pl/04-git-server/01-chapter4.markdown index 632a3521f..0c2d4227c 100644 --- a/pl/04-git-server/01-chapter4.markdown +++ b/pl/04-git-server/01-chapter4.markdown @@ -10,7 +10,7 @@ Zdalne repozytorium to nic innego jak samo repozytorium bez kopii roboczej (ang. ## Protokoły ## -Git potrafi korzystać z czterech podstawowych protokołów sieciowych do przesyłu danych: lokalnego, Secure Shell (SSH), Git, oraz HTTP. Poniżej opiszemy czym się charakteryzują i w jakich sytuacjach wartko korzystać (lub wręcz przeciwnie) z jednego z nich. +Git potrafi korzystać z czterech podstawowych protokołów sieciowych do przesyłu danych: lokalnego, Secure Shell (SSH), Git, oraz HTTP. Poniżej opiszemy czym się charakteryzują i w jakich sytuacjach warto korzystać (lub wręcz przeciwnie) z jednego z nich. Istotne jest, że z wyjątkiem protokołu HTTP, wszystkie pozostałe wymagają by na serwerze został zainstalowany Git. @@ -119,7 +119,7 @@ Aby sklonować repozytorium jako nowe, czyste repozytorium, należy uruchomić p $ git clone --bare my_project my_project.git Initialized empty Git repository in /opt/projects/my_project.git/ -Informacje wyświetlane przez to polecenia mogą być mylące. Ponieważ `clone` to tak naprawdę `git init` + `git fetch`, można zobaczyć informacje wyświetlane przez część związaną z `git init`, która powoduje utworzenie pustego katalogu. Ma miejsce rzeczywiste kopiowanie obiektów, ale nie powoduje to wyświetlenia jakiejkolwiek informacji. Teraz powinieneś mieć kopię katalogu Git w katalogu `my_project.git`. +Informacje wyświetlane przez to polecenie mogą być mylące. Ponieważ `clone` to tak naprawdę `git init` + `git fetch`, można zobaczyć informacje wyświetlane przez część związaną z `git init`, która powoduje utworzenie pustego katalogu. Ma miejsce rzeczywiste kopiowanie obiektów, ale nie powoduje to wyświetlenia jakiejkolwiek informacji. Teraz powinieneś mieć kopię katalogu Git w katalogu `my_project.git`. Ogólnie rzecz biorąc odpowiada to następującemu poleceniu: @@ -147,7 +147,7 @@ Widać zatem, że bardzo prosto jest wziąć repozytorium Git, utworzyć jego cz Warto zaznaczyć, że to właściwie wszystko czego potrzeba, aby utworzyć działający serwer Git, do którego dostęp ma kilka osób - wystarczy utworzyć dla nich konta SSH i wstawić czyste repozytorium gdzieś, gdzie osoby te mają dostęp i uprawnienia do zapisu i odczytu. Więcej nie trzeba - można działać. -W następnych sekcjach zobaczysz jak przeprowadzić bardziej zaawansowaną konfigurację. Sprawdzimy jak uniknąć konieczności tworzenia kont użytkowników dla każdej osoby, jak dodać publiczny dostęp tylko do odczytu, jak skonfigurować interfejs WWW, jak wykorzystać narzędzie Gitosis i inne. Miej jednak na uwadzę, że do pracy nad prywatnym projektem w kilka osób, _wszystko_, czego potrzeba to serwer z dostępem SSH i czyste repozytorium. +W następnych sekcjach zobaczysz jak przeprowadzić bardziej zaawansowaną konfigurację. Sprawdzimy jak uniknąć konieczności tworzenia kont użytkowników dla każdej osoby, jak dodać publiczny dostęp tylko do odczytu, jak skonfigurować interfejs WWW, jak wykorzystać narzędzie Gitosis i inne. Miej jednak na uwadze, że do pracy nad prywatnym projektem w kilka osób, _wszystko_, czego potrzeba to serwer z dostępem SSH i czyste repozytorium. ### Prosta konfiguracja ### @@ -233,7 +233,7 @@ Od tego momentu możesz ustawić puste repozytorium poprzez komendę 'git init' $ cd project.git $ git --bare init -Teraz John, Josie lub Jessica ma możliwość wykonania komendy push (wysłania) pierwszej wersji projektu do repozytorium poprzez dodanie go (projektu) jako zdalny (remote) oraz wysłanie całej gałęzi projektu. Aby tego dokonać należy połączyć sie poprzez shell z maszyną i utworzyć nowe repozytorium za każdym razem kiedy chcemy dodać projekt. Użyjmy `gitserver` jako nazwę serwera, na którym ustawisz użytkownika `git` oraz repozytorium. Jeżeli odpalasz je lokalnie i ustawiasz DNS jako `gitserver` do połączenia z tym serwerem, wtedy będziesz mógł użyć poniższych komend: +Teraz John, Josie lub Jessica ma możliwość wykonania komendy push (wysłania) pierwszej wersji projektu do repozytorium poprzez dodanie go (projektu) jako zdalny (remote) oraz wysłanie całej gałęzi projektu. Aby tego dokonać należy połączyć się poprzez shell z maszyną i utworzyć nowe repozytorium za każdym razem kiedy chcemy dodać projekt. Użyjmy `gitserver` jako nazwę serwera, na którym ustawisz użytkownika `git` oraz repozytorium. Jeżeli odpalasz je lokalnie i ustawiasz DNS jako `gitserver` do połączenia z tym serwerem, wtedy będziesz mógł użyć poniższych komend: # on Johns computer $ cd myproject @@ -290,7 +290,7 @@ Co robi to podpięcie `post-update`? Generalnie wygląda ono tak: #!/bin/sh exec git-update-server-info -To oznacza ze kiedy wysyłasz do serwera przez SSH, Git uruchomi tę komendę, aby uaktualnić pliki potrzebne do ściągania przez HTTP. +To oznacza, że kiedy wysyłasz do serwera przez SSH, Git uruchomi tę komendę, aby uaktualnić pliki potrzebne do ściągania przez HTTP. Następnie do ustawień swojego serwera Apache musisz dodać pozycję VirtualHost z głównym dokumentem jako główny katalog twoich projektów Git. Tutaj zakładamy, ze masz ustawiony wildcard DNS do wysyłania `*.gitserver` do jakiegokolwiek pudła, którego używasz do uruchamiania tego wszystkiego: @@ -657,7 +657,7 @@ Wiele wymiany kodu w świecie gita zdarza się jako żądania pobrania zmian "pl Takie podejście spowodowałoby takie samo zamieszanie z gałęziami jak w scentralizowanych systemach VCS, dodatkowo ustawianie uprawnień jest harówką dla administratora. -Gitolite pozwala nam na zdefiniowanie prefiksów "osobistych" lub "scratch" przestrzeni nazw dla każdego developera (na przykład `refs/personal//*`); zobacz sekcje "osobiste gałęzie" w `doc/3-faq-tips-etc.mkd`. +Gitolite pozwala nam na zdefiniowanie prefiksów "osobistych" lub "scratch" przestrzeni nazw dla każdego developera (na przykład `refs/personal//*`); zobacz sekcję "osobiste gałęzie" w `doc/3-faq-tips-etc.mkd`. ### Repozytoria "Wildcard" ### @@ -737,7 +737,7 @@ Jeśli zdecydujesz się nie używać Gitosis, ale chcesz ustawić Git demona, mu $ cd /path/to/project.git $ touch git-daemon-export-ok -Obecność tego pliku mówi Git'owi, że można serwować ten projekt bez autoryzacji. +Obecność tego pliku mówi Gitowi, że można serwować ten projekt bez autoryzacji. Gitosis może także kontrolować, który projekt GitWeb ma pokazywać. Najpierw, musisz dodać coś takiego do pliku `/etc/gitweb.conf`: @@ -788,7 +788,7 @@ Jeśli jest to możliwe to jest to dobry moment aby dodać swój publiczny klucz Kliknięcie "I agree, sign me up" powoduje przeniesienie do nowego panelu użytkownika (patrz rysunek 4-4). Insert 18333fig0404.png -Figure 4-4. Panel użytkowinia GitHub. +Figure 4-4. Panel użytkownika GitHub. Następnie możesz utworzyć nowe repozytorium. @@ -866,13 +866,13 @@ Po tym jak wyślesz swój projekt lub zaimportujesz z Subversion, będziesz mia Insert 18333fig0413.png Figure 4-13. Strona główna projektu GitHub. -Kiedy ludzie będą odwiedzali Twój projekt, zobaczą tą stronę. Zawiera ona kilka kart. Karta zatwierdzeń pokazuje zatwierdzenia w odwrotnej kolejności, tak samo jak w przypadku polecenia `git log`. Karta połączeń pokazuje wszystkich którzy zrobili rozwidlenie Twojego projektu i uzupełniają go. Karta ściągnięć pozwala Tobie załadować pliki binarne do projektu oraz linki do paczek z kodami i spakowane wersje wszystkich zaznaczonych punktów w projekcie. Karta Wiki pozwala na dodawanie dokumentacji oraz informacji do projektu. Karta Grafów pokazuje w graficzny sposób statystyki użytkowania projektu. Głowna karta z plikami źródłowymi, które lądują w projekcie pokazuje listę katalogów w projekcie i automatycznie renderuje plik README poniżej jeśli taki znajduje się w głównym katalogu projektu. Ta karta pokazuje również okno z zatwierdzeniami. +Kiedy ludzie będą odwiedzali Twój projekt, zobaczą tę stronę. Zawiera ona kilka kart. Karta zatwierdzeń pokazuje zatwierdzenia w odwrotnej kolejności, tak samo jak w przypadku polecenia `git log`. Karta połączeń pokazuje wszystkich którzy zrobili rozwidlenie Twojego projektu i uzupełniają go. Karta ściągnięć pozwala ci załadować pliki binarne do projektu oraz linki do paczek z kodami i spakowane wersje wszystkich zaznaczonych punktów w projekcie. Karta Wiki pozwala na dodawanie dokumentacji oraz informacji do projektu. Karta Grafów pokazuje w graficzny sposób statystyki użytkowania projektu. Głowna karta z plikami źródłowymi, które lądują w projekcie pokazuje listę katalogów w projekcie i automatycznie renderuje plik README poniżej jeśli taki znajduje się w głównym katalogu projektu. Ta karta pokazuje również okno z zatwierdzeniami. ### Rozwidlanie projektu ### Jeśli chcesz przyczynić się do rozwoju istniejącego projektu, w którym nie masz możliwości wysyłania, GitHub zachęca do rozwidlania projektu. Kiedy znajdziesz się na stronie która wydaje się interesująca i chcesz pogrzebać w niej trochę, możesz nacisnąć przycisk "fork" w nagłówku projektu aby GitHub skopiował projekt do Twojego użytkownika tak abyś mógł do niego wprowadzać zmiany. -W tego typu projektach nie musimy martwić się o dodawanie współpracowników aby nadać im prawo do wysyłania. Ludzie moga rozwidlić projekt i swobodnie wysyłać do niego, a głowny opiekun projektu może pobrać te zmiany dodając gałąź jako zdalną i połączyć go z głównym projektem. +W tego typu projektach nie musimy martwić się o dodawanie współpracowników aby nadać im prawo do wysyłania. Ludzie mogą rozwidlić projekt i swobodnie wysyłać do niego, a główny opiekun projektu może pobrać te zmiany dodając gałąź jako zdalną i połączyć go z głównym projektem. Aby rozwidlić projekt, odwiedź stronę projektu (w tym przykładzie, mojombo/chronic) i naciśnij przycisk "fork" w nagłówku (zobacz Rysunek 4-14). @@ -886,12 +886,12 @@ Figure 4-15. Twoje rozwidlenie projektu. ### Podsumowanie GitHub ### -To już wszystko o GitHub, ale ważne jest aby zaznaczyć jak szybko można to wszystko zrobić. Możesz stworzyć konto, dodać nowy projekt i wysłać go w kilka minut. Jeśli Twój projekt jest typu open source, dodatkowo zyskujesz ogromną społeczność programistów, którzy mają teraz wgląd do Twojego projektu i mogą pomóc jego rozwoju tworząc rozwidlenie. W ostateczności, może to być sposób na zaznajomienie się i szybkie wypróbowanie Git'a. +To już wszystko o GitHub, ale ważne jest aby zaznaczyć jak szybko można to wszystko zrobić. Możesz stworzyć konto, dodać nowy projekt i wysłać go w kilka minut. Jeśli Twój projekt jest typu open source, dodatkowo zyskujesz ogromną społeczność programistów, którzy mają teraz wgląd do twojego projektu i mogą pomóc w jego rozwoju tworząc rozwidlenie. W ostateczności, może to być sposób na zaznajomienie się i szybkie wypróbowanie Gita. ## Podsumowanie ## -Istnieje kilka sposobów na stworzenie repozytorium Git'a, w celu kooperacji z innymi lub dzielenia się swoją pracą. +Istnieje kilka sposobów na stworzenie repozytorium Gita, w celu kooperacji z innymi lub dzielenia się swoją pracą. -Postawienie własnego serwera daje Ci sporą kontrolę i umożliwia działanie serwera za własnym firewall'em, ale taki serwer na ogół wymaga sporo czasu na stworzenie i utrzymanie. Jeśli umieścisz swoje dane na gotowym hostingu, to jest to łatwe do skonfigurowania i utrzymania, ale musisz być w stanie utrzymać swój kod na cudzych serwerach, a niektóre organizacje na to nie pozwalają. +Postawienie własnego serwera daje Ci sporą kontrolę i umożliwia działanie serwera za własnym firewallem, ale taki serwer na ogół wymaga sporo czasu na stworzenie i utrzymanie. Jeśli umieścisz swoje dane na gotowym hostingu, to jest to łatwe do skonfigurowania i utrzymania, ale musisz być w stanie utrzymać swój kod na cudzych serwerach, a niektóre organizacje na to nie pozwalają. Określenie, które rozwiązanie lub połączenie rozwiązań jest odpowiednie dla Ciebie i Twojej organizacji powinno być dość proste. diff --git a/pl/06-git-tools/01-chapter6.markdown b/pl/06-git-tools/01-chapter6.markdown index 8357fc007..5225365a1 100644 --- a/pl/06-git-tools/01-chapter6.markdown +++ b/pl/06-git-tools/01-chapter6.markdown @@ -1096,7 +1096,7 @@ Git zobaczył, że 12 zmian było wprowadzonych między commitem który uznałe Bisecting: 3 revisions left to test after this [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing -Teraz jest na innym commicie, w połowie drogi między tym który właśnie przetestowałeś, a tym oznaczonym jako zły. Uruchamiasz swój test ponownie i widisz, że obecna wersja zawiera błąd, więc wskazujesz to Gitowi za pomocą `git bisect bad`: +Teraz jest na innym commicie, w połowie drogi między tym który właśnie przetestowałeś, a tym oznaczonym jako zły. Uruchamiasz swój test ponownie i widzisz, że obecna wersja zawiera błąd, więc wskazujesz to Gitowi za pomocą `git bisect bad`: diff --git a/pl/07-customizing-git/01-chapter7.markdown b/pl/07-customizing-git/01-chapter7.markdown index c8c89bb8c..c23b185a8 100644 --- a/pl/07-customizing-git/01-chapter7.markdown +++ b/pl/07-customizing-git/01-chapter7.markdown @@ -30,7 +30,7 @@ Następnym miejscem w które Git zajrzy jest plik `~/.gitconfig`, wskazujący na -Na końcu, Git szuka ustawień w pliku konfiguracyjnym znajdującym się z katalogu Git (`.git/config`) w każdym repozytorium którego obecnie uzywasz. Ustawienia te są specyficzne dla tego konkretnego repozytorium. Każdy z poziomów nadpisuje ustawienia poprzedniegi poziomy, więc na przykład ustawienia w `.git/config` napisują te z `/etc/gitconfig`. Możesz również ustawiać wartości ręcznie poprzez edycję i wprowadzenie danych w poprawnym formacie, ale generalnie dużo ławiej jest użyć komendy `git config`. +Na końcu, Git szuka ustawień w pliku konfiguracyjnym znajdującym się z katalogu Git (`.git/config`) w każdym repozytorium którego obecnie używasz. Ustawienia te są specyficzne dla tego konkretnego repozytorium. Każdy z poziomów nadpisuje ustawienia poprzedniego poziomu, więc na przykład ustawienia w `.git/config` nadpisują te z `/etc/gitconfig`. Możesz również ustawiać wartości ręcznie poprzez edycję i wprowadzenie danych w poprawnym formacie, ale generalnie dużo łatwiej jest użyć komendy `git config`. @@ -38,7 +38,7 @@ Na końcu, Git szuka ustawień w pliku konfiguracyjnym znajdującym się z katal -Opcje konfiguracyjne rozpoznawane przez Gita dzielą się na dwie kategorie: opcje klienta i serwera. Większość opcji dotyczy konfiguracji klienta - ustawień Twoich własnych preferencji. Chociaż jest dostępnych mnóstwo opcji, opiszę tylko kilka te z nich, którę są albo często używane lub mogą w znaczący sposób wpłynąć na Twoją pracę. Duża ilość opcji jest użyteczna tylko w specyficznych sytuacjach, których nie opiszę tutaj. Jeżeli chcesz zobaczyć listę wszystkich opcji konfiguracyjnych które Twoja wersja Gita rozpoznaje, uruchom +Opcje konfiguracyjne rozpoznawane przez Gita dzielą się na dwie kategorie: opcje klienta i serwera. Większość opcji dotyczy konfiguracji klienta - ustawień Twoich własnych preferencji. Chociaż jest dostępnych mnóstwo opcji, opiszę tylko kilka te z nich, które są albo często używane lub mogą w znaczący sposób wpłynąć na Twoją pracę. Duża ilość opcji jest użyteczna tylko w specyficznych sytuacjach, których nie opiszę tutaj. Jeżeli chcesz zobaczyć listę wszystkich opcji konfiguracyjnych które Twoja wersja Gita rozpoznaje, uruchom @@ -100,13 +100,13 @@ Potem, Twój edytor będzie ustawiał coś takiego jako domyślną treść komen ~ ".git/COMMIT_EDITMSG" 14L, 297C -Jeżeli masz specjalną politykę tworzenia treści komentarzy, to ustawienie takiego szablonu i skonfigurowanie Gita aby go używał zwiekszy szanse na to, że będzie ona regularnie przestrzegana. +Jeżeli masz specjalną politykę tworzenia treści komentarzy, to ustawienie takiego szablonu i skonfigurowanie Gita aby go używał zwiększy szanse na to, że będzie ona regularnie przestrzegana. #### core.pager #### -Wartość core.pager określa jaki program do stronnicowania jest używany przez Gita podczas pokazywania wyników komend `log` i `diff`. Możesz ustawić je na `more` lub inny ulubiony (domyślnie jest to `less`), lub możesz zupełnie je wyłączyć przez ustawienie pustej wartości: +Wartość core.pager określa jaki program do stronicowania jest używany przez Gita podczas pokazywania wyników komend `log` i `diff`. Możesz ustawić je na `more` lub inny ulubiony (domyślnie jest to `less`), lub możesz zupełnie je wyłączyć przez ustawienie pustej wartości: @@ -170,7 +170,7 @@ Gdy ta wartość jest ustawiona, Git będzie pokazywał w kolorze wyniki swojego -Bardzo rzadko będziesz potrzebował `color.ui = always`. Najczęściej, jeżeli będziesz chciał kolory w wynik działania Gita, użyjesz opcji `--color` do komendy Gita, aby wymisić na nim użycie kolorów. Ustawienie `color.ui = true` jest najczęściej tym, które będziesz chciał użyć. +Bardzo rzadko będziesz potrzebował `color.ui = always`. Najczęściej, jeżeli będziesz chciał kolory w wynik działania Gita, użyjesz opcji `--color` do komendy Gita, aby wymusić na nim użycie kolorów. Ustawienie `color.ui = true` jest najczęściej tym, które będziesz chciał użyć. @@ -203,11 +203,11 @@ Zobacz podręcznik systemowy do komendy `git config`, aby poznać wszystkie usta -Chociaż Git posiada wbudowaną obsługę narzedzia diff, którego dotychczas używałeś, możesz ustawić inny zewnętrzny program zamiast niego. Możesz również ustawić graficzny program pozwalający na łączenie zmian i rozwiązywanie konfliktów, bez konieczności robienia tego ręcznie. Zaprezentuję na przykładzie Perforce Visual Merge Tool (P4Merge) w jaki sposób ustawić do obsługi łączenia i pokazywania różnic zewnętrzny program, ponieważ ma on prosty graficzny interfejs i jest darmowy. +Chociaż Git posiada wbudowaną obsługę narzędzia diff, którego dotychczas używałeś, możesz ustawić inny zewnętrzny program zamiast niego. Możesz również ustawić graficzny program pozwalający na łączenie zmian i rozwiązywanie konfliktów, bez konieczności robienia tego ręcznie. Zaprezentuję na przykładzie Perforce Visual Merge Tool (P4Merge) w jaki sposób ustawić do obsługi łączenia i pokazywania różnic zewnętrzny program, ponieważ ma on prosty graficzny interfejs i jest darmowy. -Jeżeli chcesz tego również spróbować, P4Merge działa na wszystkich głównych platformach, więc prawdopodobnie będziesz mogł to zrobić. Będę używał nazw ścieżek w przykładach które działają na systemach Mac i Linux; dla systemu Windows bedziesz musiał zmienić `/usr/local/bin` na odpowiednią ścieżkę w Twoim środowisku. +Jeżeli chcesz tego również spróbować, P4Merge działa na wszystkich głównych platformach, więc prawdopodobnie będziesz mógł to zrobić. Będę używał nazw ścieżek w przykładach które działają na systemach Mac i Linux; dla systemu Windows będziesz musiał zmienić `/usr/local/bin` na odpowiednią ścieżkę w Twoim środowisku. @@ -217,7 +217,7 @@ Możesz pobrać P4Merge stąd: http://www.perforce.com/perforce/downloads/component.html -Na początek, ustawimy zewnętrzny skrypt do uruchamiania komend. Użyję ścieżki z systemu Mac wskazującej na program; w innych systemach, będzie ona musiała wskazywać na miejscej w którym program `p4merge` został zainstalowany. Stwórz skrypt o nazwie `extMerge`, który bedzie przyjmował wszystkie podane parametry i uruchamiał program: +Na początek, ustawimy zewnętrzny skrypt do uruchamiania komend. Użyję ścieżki z systemu Mac wskazującej na program; w innych systemach, będzie ona musiała wskazywać na miejsce w którym program `p4merge` został zainstalowany. Stwórz skrypt o nazwie `extMerge`, który będzie przyjmował wszystkie podane parametry i uruchamiał program: @@ -226,7 +226,7 @@ Na początek, ustawimy zewnętrzny skrypt do uruchamiania komend. Użyję ście /Applications/p4merge.app/Contents/MacOS/p4merge $* -Skrypt do obsługi diff sprawdza czy zostało podanych 7 argumentów i przekazuje dwa z nicg do skryptu obsłiugującego merge. Domyślnie, Git przekazuje te argumenty do programu obsługującego pokazywanie różnic: +Skrypt do obsługi diff sprawdza czy zostało podanych 7 argumentów i przekazuje dwa z nich do skryptu obsługującego merge. Domyślnie, Git przekazuje te argumenty do programu obsługującego pokazywanie różnic: diff --git a/pl/08-git-and-other-scms/01-chapter8.markdown b/pl/08-git-and-other-scms/01-chapter8.markdown index 46fb4a52f..c7c5762a8 100644 --- a/pl/08-git-and-other-scms/01-chapter8.markdown +++ b/pl/08-git-and-other-scms/01-chapter8.markdown @@ -208,7 +208,7 @@ Widać również, że suma SHA która oryginalnie rozpoczynała się od `97031e5 -Jeżeli współpracujesz z innymi programistami, a jeden z Was w pewnym momencie wypchnie jakieś zmiany, drugi może napotkać konflikt podczas próby wypchnęcia swoich zmian. Ta zmiana będzie odrzucona, do czasu włączenia tamtych. W `git svn`, wygląda to tak: +Jeżeli współpracujesz z innymi programistami, a jeden z Was w pewnym momencie wypchnie jakieś zmiany, drugi może napotkać konflikt podczas próby wypchnięcia swoich zmian. Ta zmiana będzie odrzucona, do czasu włączenia tamtych. W `git svn`, wygląda to tak: @@ -283,7 +283,7 @@ Uruchamianie `git svn rebase` co jakiś czas, pozwoli Ci upewnić się, że masz -Jak już przyzwyczaisz się do pracy z Gitem, z pewnością będziesz tworzył gałęzie tematyczne, pracował na nich, a następnie włączał je. Jeżeli wypychasz zmiany do serwera Subversion za pomocą komendy `git svn`, możesz chcieć wykonać "rebase" na wszystkich swoich zmianach włączając je do jednej gałęzi, zamiast łączyć gałezie razem. Powodem takiego sposobu działania jest to, że Subversion ma liniową historię i nie obsługuje łączenia zmian w taki sposób jak Git, więc `git svn` będzie podążał tylko za pierwszym rodzicem podczas konwertowania migawki do commitu Subversion. +Jak już przyzwyczaisz się do pracy z Gitem, z pewnością będziesz tworzył gałęzie tematyczne, pracował na nich, a następnie włączał je. Jeżeli wypychasz zmiany do serwera Subversion za pomocą komendy `git svn`, możesz chcieć wykonać "rebase" na wszystkich swoich zmianach włączając je do jednej gałęzi, zamiast łączyć gałęzie razem. Powodem takiego sposobu działania jest to, że Subversion ma liniową historię i nie obsługuje łączenia zmian w taki sposób jak Git, więc `git svn` będzie podążał tylko za pierwszym rodzicem podczas konwertowania migawki do commitu Subversion. @@ -488,7 +488,7 @@ Narzędzia dostarczane przez `git svn` są przydatne, jeżeli musisz używać se * Keep a linear Git history that doesn’t contain merge commits made by `git merge`. Rebase any work you do outside of your mainline branch back onto it; don’t merge it in. * Don’t set up and collaborate on a separate Git server. Possibly have one to speed up clones for new developers, but don’t push anything to it that doesn’t have a `git-svn-id` entry. You may even want to add a `pre-receive` hook that checks each commit message for a `git-svn-id` and rejects pushes that contain commits without it. --> -Jeżeli będziesz postępował zgodnie z tymi wskazówkami, praca z repozytoriami Subersion będzie bardziej znośna. Jednak, jeżeli możliwe jest przeniesienie się na prawdziwy serwer Gita, powinieneś to zrobić, a cały zespół jeszcze więcej na tym skorzysta. +Jeżeli będziesz postępował zgodnie z tymi wskazówkami, praca z repozytoriami Subversion będzie bardziej znośna. Jednak, jeżeli możliwe jest przeniesienie się na prawdziwy serwer Gita, powinieneś to zrobić, a cały zespół jeszcze więcej na tym skorzysta. From 74a739511c6c4afe426361f7f4c01fbb776d9974 Mon Sep 17 00:00:00 2001 From: harupong Date: Tue, 17 Sep 2013 10:30:11 +0900 Subject: [PATCH 003/862] [ja] Fix incorrect example in "diffing binary files" section --- ja/07-customizing-git/01-chapter7.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ja/07-customizing-git/01-chapter7.markdown b/ja/07-customizing-git/01-chapter7.markdown index 2df4feb59..860824fbe 100644 --- a/ja/07-customizing-git/01-chapter7.markdown +++ b/ja/07-customizing-git/01-chapter7.markdown @@ -348,8 +348,8 @@ Gitでは、バイナリファイルの差分を効果的に扱うためにGit Since its birth in 2005, Git has evolved and matured to be easy to use and yet retain these initial qualities. It’s incredibly fast, it’s very efficient with large projects, and it has an incredible branching - -system for non-linear development (See Chapter 3). - +system for non-linear development. + -system for non-linear development. + +system for non-linear development (See Chapter 3). Gitは、追加した"(See Chapter 3)"という文字列を首尾よく、かつ、簡潔に知らせてくれました。正確で、申し分のない動作です! From bcadb05ae922cb3cbbcb6f7683ed0f77069936fa Mon Sep 17 00:00:00 2001 From: AngleMortSociety Date: Tue, 17 Sep 2013 17:23:25 +0200 Subject: [PATCH 004/862] Word correction (comm => comment) --- fr/06-git-tools/01-chapter6.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fr/06-git-tools/01-chapter6.markdown b/fr/06-git-tools/01-chapter6.markdown index 1f362431e..ba662065c 100644 --- a/fr/06-git-tools/01-chapter6.markdown +++ b/fr/06-git-tools/01-chapter6.markdown @@ -1278,7 +1278,7 @@ La fusion de la pieuvre peut gérer plusieurs branches mais elle est plus pruden Cependant, il existe d'autres stratégies que vous pouvez tout aussi bien choisir. L'une d'elles est la fusion de sous-arborescence que vous pouvez utiliser pour gérer la problématique du sous-projet. -Nous allons donc voir comme gérer l'inclusion de `rack` comme dans la section précédente, mais en utilisant cette fois-ci les fusions de sous-arborescence. +Nous allons donc voir comment gérer l'inclusion de `rack` comme dans la section précédente, mais en utilisant cette fois-ci les fusions de sous-arborescence. La fusion de sous-arborescence suppose que vous ayez deux projets et que l'un s'identifie à un sous-répertoire de l'autre. Lorsque vous spécifiez une fusion de sous-arborescence, Git est assez intelligent pour deviner lequel est un sous-répertoire de l'autre et fusionne en conséquence — c'est assez bluffant. From a6841eb3f6d685c569e8d0572aea3a1853b54642 Mon Sep 17 00:00:00 2001 From: Igor Murzov Date: Tue, 11 Jun 2013 01:59:06 +0400 Subject: [PATCH 005/862] [ru] chapter 7: Extend/improve "Diffing Binary Files" section --- ru/07-customizing-git/01-chapter7.markdown | 35 +++++++++++----------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/ru/07-customizing-git/01-chapter7.markdown b/ru/07-customizing-git/01-chapter7.markdown index 6fc378d11..3b501e569 100644 --- a/ru/07-customizing-git/01-chapter7.markdown +++ b/ru/07-customizing-git/01-chapter7.markdown @@ -307,11 +307,15 @@ Git будет выявлять эти проблемы при запуске к #### Получение дельты для бинарных файлов #### -В Git'е функциональность атрибутов может быть использована для эффективного получения дельт для бинарных файлов. Чтобы сделать это, нужно объяснить Git'у, как сконвертировать ваши бинарные данные в текстовый формат, для которого можно выполнить сравнение с помощью обычного diff. +Функциональность атрибутов Git'а может быть использована для эффективного получения дельт бинарных файлов. Сделать это можно, объяснив Git'у, как сконвертировать ваши бинарные данные в текстовый формат, для которого можно выполнить сравнение с помощью обычного diff. Осталось только понять, как получить текстовое представление для *бинарных* данных. Идеальный вариант — найти подходящую утилиту для конвертирования нужного формата в текстовый вид. Но, к сожалению, получить хорошее текстовое представление можно только для весьма ограниченного набора бинарных форматов. Для большинства же бинарных форматов, например, для графических или аудио данных, получить читаемый текстовый вид не представляется возможным. Но если мы не можем получить текстовое представление содержимого, мы зачастую можем получить читаемое описание содержимого или метаданные. Метаданные не дают полное представление о содержимом файле, но, во всяком случае, это лучше чем ничего. + +Далее мы рассмотрим оба подхода на примерах популярных бинарных форматов. + +Замечание: Существуют разные виды бинарных файлов с текстовым содержимым, для которых вам, может быть, не удастся найти подходящий конвёртер. В данном случае вы можете попробовать вытащить текст с помощью утилиты `strings`. Некоторые из таких файлов могут использовать кодировку UTF-16 или могут быть написаны не в латинице, в таких файлах `strings` не найдёт ничего хорошего. Полезность `strings` может сильно варьироваться. Тем не менее, `strings` доступен на большинстве Mac- и Linux-систем, так что он может быть хорошим первым вариантом для того, чтобы сделать подобное со многими бинарными форматами. ##### Документы MS Word ##### -Так как эта довольно клёвая функция не особо широко известна, мы рассмотрим несколько примеров её использования. Для начала мы используем этот подход, чтобы решить одну из самых раздражающих проблем, известных человечеству: версионный контроль документов Word. Всем известно, что Word — это самый ужасающий из всех существующих редакторов, но, как ни странно, все им пользуются. Если вы хотите поместить документы Word под версионный контроль, вы можете запихнуть их в Git-репозиторий и время от времени делать коммиты. Но что в этом хорошего? Если вы запустите `git diff` как обычно, то увидите только что-то наподобие этого: +Для начала мы используем описанный подход, чтобы решить одну из самых раздражающих проблем, известных человечеству: версионный контроль документов Word. Всем известно, что Word — это самый ужасающий из всех существующих редакторов, но, как ни странно, все им пользуются. Если вы хотите поместить документы Word под версионный контроль, вы можете запихнуть их в Git-репозиторий и время от времени делать коммиты. Но что в этом хорошего? Если вы запустите `git diff` как обычно, то увидите только что-то наподобие этого: $ git diff diff --git a/chapter1.doc b/chapter1.doc @@ -322,18 +326,16 @@ Git будет выявлять эти проблемы при запуске к *.doc diff=word -Она говорит Git'у, что все файлы, соответствующие указанному шаблону (.doc) должны использовать фильтр "word" при попытке посмотреть дельту с изменениями. Что такое фильтр "word"? Нам нужно его изготовить. Сейчас мы настроим Git на использование программы `strings` для конвертирования документов Word в читаемые текстовые файлы, которые Git затем правильно сравнит: +Она говорит Git'у, что все файлы, соответствующие указанному шаблону (.doc) должны использовать фильтр "word" при попытке посмотреть дельту с изменениями. Что такое фильтр "word"? Нам нужно его изготовить. Сейчас мы настроим Git на использование программы `catdoc`, специально написанной для того, чтобы вытаскивать текстовую информацию из бинарных документов MS Word (скачать её можно по адресу `http://www.45.free.net/~vitus/software/catdoc/`), для конвертирования документов Word в читаемые текстовые файлы, которые Git затем правильно сравнит: - $ git config diff.word.textconv strings + $ git config diff.word.textconv catdoc Этой командой в свой `.git/config` вы добавите следующую секцию: [diff "word"] - textconv = strings - -Замечание: Существуют разные виды `.doc` файлов. Некоторые из них могут использовать кодировку UTF-16 или могут быть написаны не в латинице, в таких файлах `strings` не найдёт ничего хорошего. Полезность `strings` может сильно варьироваться. + textconv = catdoc -Теперь Git знает, что если ему надо найти дельту между двумя снимками состояния, и какие-то их файлы заканчиваются на `.doc`, он должен прогнать эти файлы через фильтр "word", который определён как программа `strings`. Так вы фактически сделаете текстовые версии своих Word-файлов перед тем, как получить для них дельту. +Теперь Git знает, что если ему надо найти дельту между двумя снимками состояния, и какие-то их файлы заканчиваются на `.doc`, он должен прогнать эти файлы через фильтр "word", который определён как программа `catdoc`. Так вы фактически сделаете текстовые версии своих Word-файлов перед тем, как получить для них дельту. Рассмотрим пример. Я поместил главу 1 настоящей книги в Git, добавил немного текста в один параграф и сохранил документ. Затем я выполнил `git diff`, чтобы увидеть, что изменилось: @@ -342,15 +344,14 @@ Git будет выявлять эти проблемы при запуске к index c1c8a0a..b93c9e4 100644 --- a/chapter1.doc +++ b/chapter1.doc - @@ -8,7 +8,8 @@ re going to cover Version Control Systems (VCS) and Git basics - re going to cover how to get it and set it up for the first time if you don - t already have it on your system. - In Chapter Two we will go over basic Git usage - how to use Git for the 80% - -s going on, modify stuff and contribute changes. If the book spontaneously - +s going on, modify stuff and contribute changes. If the book spontaneously - +Let's see if this works. + @@ -128,7 +128,7 @@ and data size) + Since its birth in 2005, Git has evolved and matured to be easy to use + and yet retain these initial qualities. It’s incredibly fast, it’s + very efficient with large projects, and it has an incredible branching + -system for non-linear development. + +system for non-linear development (See Chapter 3). -Git коротко и ясно дал мне знать, что я добавил строку "Let’s see if this works", так оно и есть. Работает не идеально, так как добавляет немного лишнего в конце, но определённо работает. Если вы сможете найти или написать хорошо работающую программу для конвертации документов Word в обычный текст, то такое решение, скорее всего, будет невероятно эффективно. Тем не менее, `strings` доступен на большинстве Mac- и Linux-систем, так что он может быть хорошим первым вариантом для того, чтобы сделать подобное со многими бинарными форматами. +Git коротко и ясно дал мне знать, что я добавил строку "(See Chapter 3)", так оно и есть. Работает идеально. ##### Текстовые файлы в формате OpenDocument ##### @@ -366,7 +367,7 @@ Git коротко и ясно дал мне знать, что я добави binary = true textconv = /usr/local/bin/odt-to-txt -Файлы в формате OpenDocument на самом деле являются запакованными zip'ом каталогами с множеством файлов (содержимое в XML-формате, таблицы стилей, изображения и т.д.). Мы напишем сценарий для извлечения содержимого и вывода его в виде обычного текста. Создайте файл `/usr/local/bin/odt-to-txt` (можете создать его в любом другом каталоге) со следующим содержимым: +Файлы в формате OpenDocument на самом деле являются запакованными zip'ом каталогами с множеством файлов (содержимое в XML-формате, таблицы стилей, изображения и т.д.). Мы напишем свой сценарий для извлечения содержимого и вывода его в виде обычного текста. Создайте файл `/usr/local/bin/odt-to-txt` (можете создать его в любом другом каталоге) со следующим содержимым: #! /usr/bin/env perl # Сценарий для конвертации OpenDocument Text (.odt) в обычный текст. From 2be2edae39951dceda41d48693c937a93c3d5734 Mon Sep 17 00:00:00 2001 From: Igor Murzov Date: Sun, 8 Sep 2013 01:08:48 +0400 Subject: [PATCH 006/862] [ru] chapter 7: Translate figures. --- ru/figures-dia/fig0702.dia | 851 +++++++++++++++++++++++++++++++++++++ ru/figures-dia/fig0703.dia | 851 +++++++++++++++++++++++++++++++++++++ 2 files changed, 1702 insertions(+) create mode 100644 ru/figures-dia/fig0702.dia create mode 100644 ru/figures-dia/fig0703.dia diff --git a/ru/figures-dia/fig0702.dia b/ru/figures-dia/fig0702.dia new file mode 100644 index 000000000..a287eb2bf --- /dev/null +++ b/ru/figures-dia/fig0702.dia @@ -0,0 +1,851 @@ + + + + + + + + + + + + + #A4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #fileA.txt# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #fileB.txt# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #fileC.rb# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #fileC.rb# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #fileA.txt'# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #fileB.txt'# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #smudge# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #clean# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Фильтры для *.txt# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Рабочий каталог# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Индекс# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git checkout# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ru/figures-dia/fig0703.dia b/ru/figures-dia/fig0703.dia new file mode 100644 index 000000000..7535d3ef7 --- /dev/null +++ b/ru/figures-dia/fig0703.dia @@ -0,0 +1,851 @@ + + + + + + + + + + + + + #A4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #fileA.txt# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #fileB.txt# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #fileC.rb# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #fileC.rb# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #fileA.txt'# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #fileB.txt'# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #smudge# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #clean# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Фильтры для *.txt# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Рабочий каталог# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Индекс# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git add# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From ac59c20b6db3cc63a66c0ade7cba1ddad2b6472e Mon Sep 17 00:00:00 2001 From: Igor Murzov Date: Sun, 15 Sep 2013 03:09:03 +0400 Subject: [PATCH 007/862] [ru] chapter 3: Translate some figures. --- ru/figures-dia/fig0322.dia | 1182 ++++++++++++++++++++ ru/figures-dia/fig0323.dia | 1457 +++++++++++++++++++++++++ ru/figures-dia/fig0324.dia | 1698 +++++++++++++++++++++++++++++ ru/figures-dia/fig0325.dia | 2101 +++++++++++++++++++++++++++++++++++ ru/figures-dia/fig0326.dia | 2111 ++++++++++++++++++++++++++++++++++++ ru/figures-dia/fig0336.dia | 786 ++++++++++++++ ru/figures-dia/fig0337.dia | 1546 ++++++++++++++++++++++++++ ru/figures-dia/fig0338.dia | 1755 ++++++++++++++++++++++++++++++ ru/figures-dia/fig0339.dia | 1882 ++++++++++++++++++++++++++++++++ 9 files changed, 14518 insertions(+) create mode 100644 ru/figures-dia/fig0322.dia create mode 100644 ru/figures-dia/fig0323.dia create mode 100644 ru/figures-dia/fig0324.dia create mode 100644 ru/figures-dia/fig0325.dia create mode 100644 ru/figures-dia/fig0326.dia create mode 100644 ru/figures-dia/fig0336.dia create mode 100644 ru/figures-dia/fig0337.dia create mode 100644 ru/figures-dia/fig0338.dia create mode 100644 ru/figures-dia/fig0339.dia diff --git a/ru/figures-dia/fig0322.dia b/ru/figures-dia/fig0322.dia new file mode 100644 index 000000000..7d796d442 --- /dev/null +++ b/ru/figures-dia/fig0322.dia @@ -0,0 +1,1182 @@ + + + + + + + + + + + + + #A4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #0b743# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #a6b4c# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #f42c5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #0b743# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #a6b4c# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #f42c5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #origin/master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git clone schacon@git.ourcompany.com:project.git# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git.ourcompany.com# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Локальный компьютер# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Удалённая ветка# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Локальная ветка# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ru/figures-dia/fig0323.dia b/ru/figures-dia/fig0323.dia new file mode 100644 index 000000000..2534b9d48 --- /dev/null +++ b/ru/figures-dia/fig0323.dia @@ -0,0 +1,1457 @@ + + + + + + + + + + + + + #A4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git.ourcompany.com# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Локальный компьютер# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #31b8c# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #190a3# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #origin/master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #0b743# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #a6b4c# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #f42c5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #0b743# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #a6b4c# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #f42c5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #a38de# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #893cf# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Отправил кто-то другой# + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ru/figures-dia/fig0324.dia b/ru/figures-dia/fig0324.dia new file mode 100644 index 000000000..3f6f6452c --- /dev/null +++ b/ru/figures-dia/fig0324.dia @@ -0,0 +1,1698 @@ + + + + + + + + + + + + + #A4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #origin/master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git fetch origin# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git.ourcompany.com# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Локальный компьютер# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #0b743# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #a6b4c# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #f42c5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #31b8e# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #190a3# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #0b743# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #a6b4c# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #f42c5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #31b8e# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #190a3# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #a38de# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #893cf# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ru/figures-dia/fig0325.dia b/ru/figures-dia/fig0325.dia new file mode 100644 index 000000000..abec97190 --- /dev/null +++ b/ru/figures-dia/fig0325.dia @@ -0,0 +1,2101 @@ + + + + + + + + + + + + + #A4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git.ourcompany.com# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Локальный компьютер# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #origin/master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git remote add# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #0b743# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #a6b4c# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #f42c5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #31b8e# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #190a3# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #190a3# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #f42c5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #31b8e# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #f42c5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #31b8e# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git.team1.ourcompany.com# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #origin# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #teamone# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #a38de# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #893cf# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #teamone# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #teamone# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #teamone# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git://git.team1.ourcompany.com# + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ru/figures-dia/fig0326.dia b/ru/figures-dia/fig0326.dia new file mode 100644 index 000000000..db235dc83 --- /dev/null +++ b/ru/figures-dia/fig0326.dia @@ -0,0 +1,2111 @@ + + + + + + + + + + + + + #A4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git.ourcompany.com# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Локальный компьютер# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #origin/master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #0b743# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #a6b4c# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #f42c5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #31b8e# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #190a3# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #190a3# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #f42c5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #31b8e# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #f42c5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #31b8e# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git.team1.ourcompany.com# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #origin# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #teamone# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #a38de# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #893cf# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git fetch teamone# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git fetch teamone# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #teamone/master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ru/figures-dia/fig0336.dia b/ru/figures-dia/fig0336.dia new file mode 100644 index 000000000..41db8c085 --- /dev/null +++ b/ru/figures-dia/fig0336.dia @@ -0,0 +1,786 @@ + + + + + + + + + + + + + #A4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C1# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C1# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C2# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C3# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #teamone/master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git.team1.ourcompany.com# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Локальный компьютер# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ru/figures-dia/fig0337.dia b/ru/figures-dia/fig0337.dia new file mode 100644 index 000000000..385c5f1e3 --- /dev/null +++ b/ru/figures-dia/fig0337.dia @@ -0,0 +1,1546 @@ + + + + + + + + + + + + + #A4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git.team1.ourcompany.com# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Локальный компьютер# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C1# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C6# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C1# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C6# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C2# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C3# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C7# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #teamone/master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ru/figures-dia/fig0338.dia b/ru/figures-dia/fig0338.dia new file mode 100644 index 000000000..7f52b2c20 --- /dev/null +++ b/ru/figures-dia/fig0338.dia @@ -0,0 +1,1755 @@ + + + + + + + + + + + + + #A4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git.team1.ourcompany.com# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Локальный компьютер# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #teamone/master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C1# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C6# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C4'# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C1# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C6# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C2# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C3# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C7# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C4'# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ru/figures-dia/fig0339.dia b/ru/figures-dia/fig0339.dia new file mode 100644 index 000000000..7a9285e76 --- /dev/null +++ b/ru/figures-dia/fig0339.dia @@ -0,0 +1,1882 @@ + + + + + + + + + + + + + #A4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #git.team1.ourcompany.com# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #Локальный компьютер# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #teamone/master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #master# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C1# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C6# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C4'# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C5# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C1# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C4# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C6# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C2# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C3# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C7# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C4'# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #C8# + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 41772b6601108f4941c7c9271956bd0c9a8ccdb2 Mon Sep 17 00:00:00 2001 From: AngleMortSociety Date: Thu, 19 Sep 2013 19:37:14 +0200 Subject: [PATCH 008/862] [fr] Fix some mistakes. --- fr/07-customizing-git/01-chapter7.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fr/07-customizing-git/01-chapter7.markdown b/fr/07-customizing-git/01-chapter7.markdown index 88e55a428..e7248a28a 100644 --- a/fr/07-customizing-git/01-chapter7.markdown +++ b/fr/07-customizing-git/01-chapter7.markdown @@ -142,7 +142,7 @@ Ce réglage a été ajouté dans Git 1.5.5. Si vous avez une version antérieure, vous devrez spécifier les règles de colorisation individuellement. `color.ui = always` est rarement utile. -Dans les plupart des cas, si vous tenez vraiment à coloriser vos sorties redirigées, vous pourrez passer le drapeau `--color` à la commande Git pour la forcer à utiliser les codes de couleur. +Dans la plupart des cas, si vous tenez vraiment à coloriser vos sorties redirigées, vous pourrez passer le drapeau `--color` à la commande Git pour la forcer à utiliser les codes de couleur. Le réglage `color.ui = true` est donc le plus utilisé. #### `color.*` #### @@ -163,7 +163,7 @@ Par exemple, pour régler les couleurs de méta-informations du diff avec une é La couleur peut prendre les valeurs suivantes : *normal*, *black*, *red*, *green*, *yellow*, *blue*, *magenta*, *cyan* ou *white*. Si vous souhaitez ajouter un attribut de casse, les valeurs disponibles sont *bold* (gras), *dim* (léger), *ul* (*underlined*, souligné), *blink* (clignotant) et *reverse* (inversé). -Référez-vous à la page de manuel de `git config` pour tous les sous-réglages disponibles. +Référez-vous à la page du manuel de `git config` pour tous les sous-réglages disponibles. ### Outils externes de fusion et de différence ### @@ -294,7 +294,7 @@ Les deux autres qui sont désactivées par défaut mais peuvent être activées Vous pouvez indiquer à Git quelle correction vous voulez activer en fixant `core.whitespace` avec les valeurs que vous voulez ou non, séparées par des virgules. Vous pouvez désactiver des réglages en les éliminant de la chaîne de paramétrage ou en les préfixant avec un `-`. -Par exemple, si vous souhaiter activer tout sauf `cr-at-eol`, vous pouvez lancer ceci : +Par exemple, si vous souhaitez activer tout sauf `cr-at-eol`, vous pouvez lancer ceci : $ git config --global core.whitespace \ trailing-space,space-before-tab,indent-with-non-tab @@ -749,7 +749,7 @@ Vous ne pouvez plus arrêter le processus de validation avec ce script. #### Autres crochets côté client #### -Le crochet `pre-rebase` est invoqueé avant que vous ne rebasiez et peut interrompre le processus s'il sort avec un code d'erreur non nul. +Le crochet `pre-rebase` est invoqué avant que vous ne rebasiez et peut interrompre le processus s'il sort avec un code d'erreur non nul. Vous pouvez utiliser ce crochet pour empêcher de rebaser tout *commit* qui a déjà été poussé. C'est ce que fait le crochet d'exemple `pre-rebase` que Git installe, même s'il considère que la branche cible de publication s'appelle `next`. Il est très probable que vous ayez à changer ce nom pour celui que vous utilisez réellement en branche publique stable. @@ -760,7 +760,7 @@ Cela peut signifier y déplacer des gros fichiers binaires que vous ne souhaitez Enfin, le crochet `post-merge` s'exécute à la suite d'une commande `merge` réussie. Vous pouvez l'utiliser pour restaurer certaines données non gérées par Git dans le copie de travail telles que les informations de permission. -Ce crochet permet de même de valider la présence de fichiers externes au contrôle de Git que vous souhaitez voir recopiés lorsque la copie de travail change. +Ce crochet permet même de valider la présence de fichiers externes au contrôle de Git que vous souhaitez voir recopiés lorsque la copie de travail change. ### Crochets côté serveur ### From 2394fa4a88971c82be9a24548c323846403e6668 Mon Sep 17 00:00:00 2001 From: Hiroaki ENDOH Date: Sat, 21 Sep 2013 12:20:47 +0900 Subject: [PATCH 009/862] [ja] Fix typo Chapter 1.3 Nearly Every Operation Is Local MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修正前) もし、飛行機もしくは "列車にに" 乗って 修正後) もし、飛行機もしくは "列車に" 乗って --- ja/01-introduction/01-chapter1.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ja/01-introduction/01-chapter1.markdown b/ja/01-introduction/01-chapter1.markdown index 4388e9de4..692487aee 100644 --- a/ja/01-introduction/01-chapter1.markdown +++ b/ja/01-introduction/01-chapter1.markdown @@ -79,7 +79,7 @@ Gitのほとんどの操作は、ローカル・ファイルと操作する資 例えば、プロジェクトの履歴を閲覧するために、Gitはサーバーに履歴を取得しに行って表示する必要がありません。直接にローカル・データベースからそれを読むだけです。これは、プロジェクトの履歴をほとんど即座に知るということです。もし、あるファイルの現在のバージョンと、そのファイルの1ヶ月前の間に導入された変更点を知りたいのであれば、Gitは、遠隔のサーバーに差分を計算するように問い合わせたり、ローカルで差分を計算するために遠隔サーバーからファイルの古いバージョンを持ってくる代わりに、1か月前のファイルを調べてローカルで差分の計算を行なえます。 -これはまた、オフラインであるか、VPNから切り離されていたとしても、出来ない事は非常に少ないことを意味します。もし、飛行機もしくは列車にに乗ってちょっとした仕事をしたいとしても、アップロードするためにネットワーク接続し始めるまで、楽しくコミットできます。もし、帰宅してVPNクライアントを適切に作動させられないとしても、さらに作業ができます。多くの他のシステムでは、それらを行なう事は、不可能であるか苦痛です。例えばPerforceにおいては、サーバーに接続できないときは、多くの事が行なえません。SubversionとCVSにおいては、ファイルの編集はできますが、データベースに変更をコミットできません(なぜならば、データベースがオフラインだからです)。このことは巨大な問題に思えないでしょうが、実に大きな違いを生じうることに驚くでしょう。 +これはまた、オフラインであるか、VPNから切り離されていたとしても、出来ない事は非常に少ないことを意味します。もし、飛行機もしくは列車に乗ってちょっとした仕事をしたいとしても、アップロードするためにネットワーク接続し始めるまで、楽しくコミットできます。もし、帰宅してVPNクライアントを適切に作動させられないとしても、さらに作業ができます。多くの他のシステムでは、それらを行なう事は、不可能であるか苦痛です。例えばPerforceにおいては、サーバーに接続できないときは、多くの事が行なえません。SubversionとCVSにおいては、ファイルの編集はできますが、データベースに変更をコミットできません(なぜならば、データベースがオフラインだからです)。このことは巨大な問題に思えないでしょうが、実に大きな違いを生じうることに驚くでしょう。 ### Gitは完全性を持つ ### From c4df8034cf8e6e73fb981c0cdc419366df03d810 Mon Sep 17 00:00:00 2001 From: AngleMortSociety Date: Tue, 24 Sep 2013 17:01:07 +0200 Subject: [PATCH 010/862] [fr] Fix some mistakes with a text. --- fr/08-git-and-other-scms/01-chapter8.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/fr/08-git-and-other-scms/01-chapter8.markdown b/fr/08-git-and-other-scms/01-chapter8.markdown index 26c5ca0e5..19e6caffb 100644 --- a/fr/08-git-and-other-scms/01-chapter8.markdown +++ b/fr/08-git-and-other-scms/01-chapter8.markdown @@ -374,7 +374,7 @@ Le résultat ressemble à ceci : Ici aussi, tous les *commits* locaux dans Git ou ceux poussé sur Subversion dans l'intervalle n'apparaissent pas. -#### L'information sur la serveur SVN #### +#### L'information sur le serveur SVN #### Vous pouvez aussi obtenir le même genre d'information que celle fournie par `svn info` en lançant `git svn info` : @@ -479,7 +479,7 @@ les *commits* ressemblent à ceci : fixed install - go to trunk -Non seulement le champ auteur a meilleure mine, mais de plus le champ `git-svn-id` a disparu. +Non seulement le champ auteur a meilleure mine, mais de plus, le champ `git-svn-id` a disparu. Il est encore nécessaire de faire un peu de ménage `post-import`. Déjà, vous devriez nettoyer les références bizarres que `git svn` crée. Premièrement, déplacez les étiquettes pour qu'elles soient de vraies étiquettes plutôt que des branches distantes étranges, ensuite déplacez le reste des branches pour qu'elles deviennent locales. @@ -500,7 +500,7 @@ Ensuite, déplacez le reste des références sous `refs/remotes` en branches loc À présent, toutes les vieilles branches sont des vraies branches Git et toutes les vieilles étiquettes sont de vraies étiquettes Git. La dernière activité consiste à ajouter votre nouveau serveur Git comme serveur distant et à y pousser votre projet transformé. -Pour pousser tout, y compris branches et étiquettes, lancez : +Pour pousser le tout, y compris branches et étiquettes, lancez : $ git push origin --tags @@ -516,7 +516,7 @@ Dans ce dernier cas, pour le lancer, il vous faut récupérer le code source de $ git clone git://git.kernel.org/pub/scm/git/git.git $ cd git/contrib/fast-import -Dans ce répertoire `fast-import`, vous devriez trouver une script exécutable Python appelé `git-p4`. +Dans ce répertoire `fast-import`, vous devriez trouver un script exécutable Python appelé `git-p4`. Python et l'outil `p4` doivent être installés sur votre machine pour que cet import fonctionne. Par exemple, nous importerons le projet Jam depuis le Perforce Public Depot. Pour installer votre client, vous devez exporter la variable d'environnement `P4PORT` qui pointe sur le dépôt Perforce : @@ -556,7 +556,7 @@ Si vous vous rendez dans le répertoire `/opt/p4import` et lancez la commande ` Vous pouvez visualiser l'identifiant `git-p4` de chaque *commit*. Il n'y a pas de problème à garder cet identifiant ici, au cas où vous auriez besoin de référencer dans l'avenir le numéro de modification Perforce. Cependant, si vous souhaitez supprimer l'identifiant, c'est le bon moment, avant de commencer à travailler avec le nouveau dépôt. -Vous pouvez utiliser `git filter-branch` pour faire une retrait en masse des chaînes d'identifiant : +Vous pouvez utiliser `git filter-branch` pour faire un retrait en masse des chaînes d'identifiant : $ git filter-branch --msg-filter ' sed -e "/^\[git-p4:/d" From 5de5f51fbfd2a0926cfa7626dae1fea7263759cd Mon Sep 17 00:00:00 2001 From: tendium Date: Wed, 25 Sep 2013 03:33:08 +0200 Subject: [PATCH 011/862] Better wording Refomulated for better understanding --- ru/03-git-branching/01-chapter3.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/03-git-branching/01-chapter3.markdown b/ru/03-git-branching/01-chapter3.markdown index d73bb4674..34bc4aea8 100644 --- a/ru/03-git-branching/01-chapter3.markdown +++ b/ru/03-git-branching/01-chapter3.markdown @@ -567,7 +567,7 @@ Insert 18333fig0335.png Если вы будете следовать этому указанию, всё будет хорошо. Если нет — люди возненавидят вас, вас будут презирать ваши друзья и семья. -Когда вы что-то перемещаете, вы отменяете существующие коммиты и создаёте новые, которые являются похожими на старые, но в чём-то другими. Если вы выкладываете свои коммиты куда-нибудь, и другие забирают их себе и в дальнейшем основывают на них свою работу, а затем вы переделываете эти коммиты командой `git rebase` и выкладываете их снова, ваши коллеги будут вынуждены заново выполнять слияние для своих наработок. Всё запутается, когда вы в очередной раз попытаетесь включить их работу в свою. +Когда вы что-то перемещаете, вы отменяете существующие коммиты и создаёте новые, которые похожи на старые, но являются другими. Если вы выкладываете (push) свои коммиты куда-нибудь, и другие забирают (pull) их себе и в дальнейшем основывают на них свою работу, а затем вы переделываете эти коммиты командой `git rebase` и выкладываете их снова, ваши коллеги будут вынуждены заново выполнять слияние для своих наработок. В итоге вы получите беспорядок, когда в очередной раз попытаетесь включить их работу в свою. Давайте рассмотрим пример того, как перемещение публично доступных наработок может вызвать проблемы. Представьте себе, что вы склонировали себе репозиторий с центрального сервера и поработали в нём. И ваша история коммитов выглядит как на рисунке 3-36. From 18ef2f47453978f4a3bc335db79c295801447381 Mon Sep 17 00:00:00 2001 From: AngleMortSociety Date: Thu, 26 Sep 2013 17:29:55 +0200 Subject: [PATCH 012/862] [fr] Fix some mistakes with a text. --- fr/09-git-internals/01-chapter9.markdown | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fr/09-git-internals/01-chapter9.markdown b/fr/09-git-internals/01-chapter9.markdown index 975730f80..ccf9eb886 100644 --- a/fr/09-git-internals/01-chapter9.markdown +++ b/fr/09-git-internals/01-chapter9.markdown @@ -19,7 +19,7 @@ Ensuite, vous apprendrez les mécanismes de transport/transmission/communication ## Plomberie et porcelaine ## Ce livre couvre l'utilisation de Git avec une trentaine de verbes comme `checkout`, `branch`, `remote`... -Mais, puisque Git était initialement une boîte à outils (*toolkit*) pour VCS, plutôt qu'un VCS complet et conviviale, il dispose de tout un ensemble d'actions pour les tâches bas niveau qui étaient conçues pour être liées dans le style UNIX ou appelées depuis des scripts. +Mais, puisque Git était initialement une boîte à outils (*toolkit*) pour VCS, plutôt qu'un VCS complet et convivial, il dispose de tout un ensemble d'actions pour les tâches bas niveau qui étaient conçues pour être liées dans le style UNIX ou appelées depuis des scripts. Ces commandes sont dites commandes de « plomberie » (*plumbing*) et les autres, plus conviviales sont appelées « porcelaines » (*porcelain*). Les huit premiers chapitres du livre concernent presque exclusivement les commandes porcelaine. @@ -349,7 +349,7 @@ Vous devez inclure la bibliothèque et exécuter `Zlib::Deflate.deflate()` sur l => "x\234K\312\311OR04c(\317H,Q\310,V(-\320QH\311O\266\a\000_\034\a\235" Finalement, vous enregistrerez le contenu compressé dans un objet sur le disque. -Vous déterminerez le chemin de l'objet que vous voulez enregistrer (les deux premiers caractères de l'empreinte SHA-1 formeront le nom du sous-répertoires et les 38 derniers formeront le nom du fichier dans ce répertoire). +Vous déterminerez le chemin de l'objet que vous voulez enregistrer (les deux premiers caractères de l'empreinte SHA-1 formeront le nom du sous-répertoire et les 38 derniers formeront le nom du fichier dans ce répertoire). En Ruby, on peut utiliser la fonction `FileUtils.mkdir_p()` pour créer un sous-répertoire s'il n'existe pas. Ensuite, ouvrez le fichier avec `File.open()` et enregistrez le contenu compressé en appelant la fonction `write()` sur la référence du fichier : @@ -725,7 +725,7 @@ S'il existe une équipe qualité (QA) qui publie une série de branches et que l fetch = +refs/heads/master:refs/remotes/origin/master fetch = +refs/heads/qa/*:refs/remotes/origin/qa/* -Si vous utilisez des processus complexes impliquant une équipe qualité, des développeurs et des intégrateurs qui publient des branches et qui collaborent sur des branches distantes, vous pouvez facilement utiliser des espaces des noms de cette façon. +Si vous utilisez des processus complexes impliquant une équipe qualité, des développeurs et des intégrateurs qui publient des branches et qui collaborent sur des branches distantes, vous pouvez facilement utiliser des espaces de noms, de cette façon. ### Publier une référence spécifique ### @@ -1084,12 +1084,12 @@ Si vous l'exécutez avec l'option `--full`, il vous montre tous les objets qui n dangling blob 7108f7ecb345ee9d0084193f147cdad4d2998293 Dans ce cas, vous pouvez voir votre *commit* manquant après « dangling commit ». -Vous pouvez le restaurez de la même manière que précédemment, en créant une branche qui référence cette empreinte SHA. +Vous pouvez le restaurer de la même manière que précédemment, en créant une branche qui référence cette empreinte SHA. ### Suppression d'objets ### Il y a beaucoup de choses dans Git qui sont géniales, mais une fonctionnalité qui peut poser problème est le fait que `git clone` télécharge l'historique entier du projet, incluant chaque version de chaque fichier. -C'est très bien lorsque le tout est du code source, parce Git est hautement optimisé pour compresser les données efficacement. +C'est très bien lorsque le tout est du code source, parce que Git est hautement optimisé pour compresser les données efficacement. Cependant, si quelqu'un à un moment donné de l'historique de votre projet a ajouté un énorme fichier, chaque clone sera forcé de télécharger cet énorme fichier, même s'il a été supprimé du projet dans le *commit* suivant. Puisqu'il est accessible depuis l'historique, il sera toujours là. @@ -1131,7 +1131,7 @@ Maintenant, faites un `gc` sur votre base de données, pour voir combien d'espac Writing objects: 100% (21/21), done. Total 21 (delta 3), reused 15 (delta 1) -Vous pouvez exécutez la commande `count-objects` pour voir rapidement combien d'espace disque vous utilisez : +Vous pouvez exécuter la commande `count-objects` pour voir rapidement combien d'espace disque vous utilisez : $ git count-objects -v count: 4 @@ -1142,7 +1142,7 @@ Vous pouvez exécutez la commande `count-objects` pour voir rapidement combien d prune-packable: 0 garbage: 0 -L'entrée `size-pack` est la taille de vos fichiers groupés en kilooctets, vous utilisez donc 2 Mio. +L'entrée `size-pack` est la taille de vos fichiers groupés en kilo-octet, vous utilisez donc 2 Mio. Avant votre dernier *commit*, vous utilisiez environ 2 Kio, clairement, supprimer le fichier avec le *commit* précédent ne l'a pas enlevé de votre historique. À chaque fois que quelqu'un clonera votre dépôt, il aura à cloner les 2 Mio pour récupérer votre tout petit projet, parce que vous avez accidentellement rajouté un gros fichier. Débarrassons-nous en. @@ -1160,7 +1160,7 @@ Vous pouvez également le faire suivre à la commande `tail` car vous ne vous in Le gros objet est à la fin : 2 Mio. Pour trouver quel fichier c'est, vous allez utiliser la commande `rev-list`, que vous avez utilisée brièvement dans le chapitre 7. -Si vous mettez l'option `--objects` à `rev-list`, elle listera tous les SHA des *commits* et des blobs avec le chemin du fichier associés. +Si vous mettez l'option `--objects` à `rev-list`, elle listera tous les SHA des *commits* et des blobs avec le chemin du fichier associé. Vous pouvez utilisez cette commande pour trouver le nom de votre blob : $ git rev-list --objects --all | grep 7a9eb2fb From cf27e5f743d28987ba051ac4b8d4ea97aa440f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Pe=C3=B1a?= Date: Tue, 1 Oct 2013 02:08:57 +0300 Subject: [PATCH 013/862] Fixing typo for "entesijos" [sic] According to the RAE the correct spelling is "entresijos" : cosa oculta. --- es/09-git-internals/01-chapter9.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es/09-git-internals/01-chapter9.markdown b/es/09-git-internals/01-chapter9.markdown index b0455af06..85c789327 100755 --- a/es/09-git-internals/01-chapter9.markdown +++ b/es/09-git-internals/01-chapter9.markdown @@ -1,4 +1,4 @@ -# Los entesijos internos de Git # +# Los entresijos internos de Git # Puedes que hayas llegado a este capítulo saltando desde alguno previo o puede que hayas llegado tras leer todo el resto del libro. --En uno u otro caso, aquí es donde aprenderás acerca del funcionamiento interno y la implementación de Git--. Me parece que esta información es realmente importante para entender cúan util y potente es Git. Pero algunas personas opinan que puede ser confuso e innecesariamente complejo para novatos. Por ello, lo he puesto al final del libro; de tal forma que puedas leerlo antes o después, en cualquier momento, a lo largo de tu proceso de aprendizaje. Lo dejo en tus manos. From 90c92ceb9ba2034ef9f9489f0fae46ec1e2b33f3 Mon Sep 17 00:00:00 2001 From: Jay Taggart Date: Thu, 3 Oct 2013 10:55:24 -0500 Subject: [PATCH 014/862] Fixed the command for git svn clone, removed erroneous hyphen --- en/08-git-and-other-scms/01-chapter8.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/08-git-and-other-scms/01-chapter8.markdown b/en/08-git-and-other-scms/01-chapter8.markdown index 908773998..37ac490e4 100644 --- a/en/08-git-and-other-scms/01-chapter8.markdown +++ b/en/08-git-and-other-scms/01-chapter8.markdown @@ -369,7 +369,7 @@ That gives you the log output in XML format — you can look for the authors, cr You can provide this file to `git svn` to help it map the author data more accurately. You can also tell `git svn` not to include the metadata that Subversion normally imports, by passing `--no-metadata` to the `clone` or `init` command. This makes your `import` command look like this: - $ git-svn clone http://my-project.googlecode.com/svn/ \ + $ git svn clone http://my-project.googlecode.com/svn/ \ --authors-file=users.txt --no-metadata -s my_project Now you should have a nicer Subversion import in your `my_project` directory. Instead of commits that look like this From 068e68d1182e576a8d5b6121e559e6fff676d824 Mon Sep 17 00:00:00 2001 From: Igor Murzov Date: Sat, 5 Oct 2013 00:44:58 +0400 Subject: [PATCH 015/862] [ru] chapter 8: Incorporate changes from 90c92ceb9 "Fixed the command for git svn clone, removed erroneous hyphen" --- ru/08-git-and-other-scms/01-chapter8.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/08-git-and-other-scms/01-chapter8.markdown b/ru/08-git-and-other-scms/01-chapter8.markdown index d839fedc0..dd6b71084 100644 --- a/ru/08-git-and-other-scms/01-chapter8.markdown +++ b/ru/08-git-and-other-scms/01-chapter8.markdown @@ -369,7 +369,7 @@ Git определяет ветку, в которую он отправит в Вы можете передать этот файл как параметр команде `git svn` для более точного преобразования данных об авторах. Кроме того, можно дать указание `git svn` не включать метаданные, обычно импортируемые Subversion, передав параметр `--no-metadata` команде `clone` или `init`. Таким образом, команда для импортирования будет выглядеть так: - $ git-svn clone http://my-project.googlecode.com/svn/ \ + $ git svn clone http://my-project.googlecode.com/svn/ \ --authors-file=users.txt --no-metadata -s my_project Теперь в вашем каталоге `my_project` будут находиться более приятно выглядящие данные после импортирования. Вместо коммитов, которые выглядят так: From fcec80365a191bf5a715cf89c595beefa3dfc37a Mon Sep 17 00:00:00 2001 From: Patrik Wehrli Date: Tue, 8 Oct 2013 09:07:32 +0200 Subject: [PATCH 016/862] [de] (08) minor spelling fix --- de/08-git-and-other-scms/01-chapter8.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/de/08-git-and-other-scms/01-chapter8.markdown b/de/08-git-and-other-scms/01-chapter8.markdown index dee1fbfdb..8f6fd6b41 100644 --- a/de/08-git-and-other-scms/01-chapter8.markdown +++ b/de/08-git-and-other-scms/01-chapter8.markdown @@ -29,7 +29,7 @@ Das Haupt-Kommando in Git für alle Kommandos der Subversion Bridge ist `git svn -Es ist wichtig, dass Du im Hinterkopf behältst, dass Du mit dem `git svn` Befehl mit Subversion interagierst, eine System, dass nicht ganz so fortschrittlich ist wie Git. Obwohl Du auch dort ganz einfach Branches erstellen und wieder zusammenführen kannst, ist es üblicherweise am einfachsten, wenn Du die History so geradlinig wie möglich gestaltest, indem Du ein rebase für Deine Arbeit durchfürst und es vermeidest, zum Beispiel mit einem entfernten Git-Repository zu interagieren. +Es ist wichtig, dass Du im Hinterkopf behältst, dass Du mit dem `git svn` Befehl mit Subversion interagierst, einem System, das nicht ganz so fortschrittlich ist wie Git. Obwohl Du auch dort ganz einfach Branches erstellen und wieder zusammenführen kannst, ist es üblicherweise am einfachsten, wenn Du die History so geradlinig wie möglich gestaltest, indem Du ein rebase für Deine Arbeit durchfürst und es vermeidest, zum Beispiel mit einem entfernten Git-Repository zu interagieren. From 199e37d5e6d206404749ac2b3381f4cfde9f8ae7 Mon Sep 17 00:00:00 2001 From: Jean-Noel Avila Date: Tue, 8 Oct 2013 10:00:55 +0200 Subject: [PATCH 017/862] Revert maruku to 0.6.1 maruku 0.7.0 has a bug where code blocks starting with a star are interpreted as lists. --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index a37722ab6..79f6c3029 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,5 @@ source 'https://rubygems.org' -gem 'maruku' +gem 'maruku', '0.6.1' gem 'redcarpet' gem 'rdiscount' From 17bb7f8175f534c6303d066e657a211b71cc6caf Mon Sep 17 00:00:00 2001 From: Krzysztof Gibas Date: Tue, 8 Oct 2013 13:41:21 +0200 Subject: [PATCH 018/862] [pl] next part of chapter 7 --- pl/07-customizing-git/01-chapter7.markdown | 61 +++++++++++++++------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/pl/07-customizing-git/01-chapter7.markdown b/pl/07-customizing-git/01-chapter7.markdown index c8c89bb8c..d648831e3 100644 --- a/pl/07-customizing-git/01-chapter7.markdown +++ b/pl/07-customizing-git/01-chapter7.markdown @@ -132,13 +132,13 @@ Teraz, możesz podpisywać tagi bez konieczności wskazywania za każdym razem k #### core.excludesfile #### -Możesz umieścić wzorce plików w pliku `.gitignore` w swoim projekcie, tak aby Git pomijał je i nie próbował dodawać ich do przechowalni, gdy uruchomisz `git add`, zgodnie z tym ja opisano w rozdziale 2. Jednakże, jeżeli chcesz aby inny plik poza projektem przechowywał te informacje, lub miał jakieś dodatkowe, możesz wskazać Gitowi gdzie ten plik się znajduje za pomocą ustawienia `core.excludesfile`. Po prostu ustaw w nim ścieżkę do pliku, który zawiera wpisu analogiczne do tych które byłyby w pliku `.gitignore`. +Możesz umieścić wzorce w pliku `.gitignore` w swoim projekcie, aby Git nie śledził ich i nie próbował dodawać do przechowalni po wykonaniu komendy `git add`, jak wspomniałem już w rozdziale 2. Możesz jednak przechowywać te informacje w innym pliku, znajdującym się poza drzewem projektu, możesz wskazać Gitowi loikalizację tego pliku za pomocą ustawienia `core.excludesfile`. Po prostu ustaw ją na ścieżkę wskazującą na plik, który ma zawartość podobną do tej, którą ma `.gitignore`. #### help.autocorrect #### -Opcja ta jest dostępna od wersji Gita 1.6.1 lub późniejszej. Jeżeli zrobisz błąd podczas wpisywania komendy Gita, pokaże Ci się coś podobnego do: +Ta opcja jest dostępna w wersjach Gita 1.6.1 i późniejszych. Jeżeli błędnie wpiszesz komendę w Git, zostanie Ci pokazany wynik podobny do: @@ -148,11 +148,14 @@ Opcja ta jest dostępna od wersji Gita 1.6.1 lub późniejszej. Jeżeli zrobisz Did you mean this? commit -Po ustawieniu `help.autocorrect` na 1, Git automatycznie uruchomi komendę, jeżeli będzie w stanie dopasować ją do dokładnie jednego wyniku. +Jeżeli ustawisz `help.autocorrect` na 1, Git automatycznie uruchomi komendę, jeżeli będzie mógł ją dopasować tylko do jednego wyniku. -### Colors in Git ### + +### Kolory w Git ### + + Git może również pokazywać wyniki swojego działania w kolorze, co ułatwi Ci ich odczytanie w szybszy i łatwiejszy sposób. Liczne opcje pozwalają na dostosowanie kolorowania do Twoich preferencji. @@ -226,7 +229,7 @@ Na początek, ustawimy zewnętrzny skrypt do uruchamiania komend. Użyję ście /Applications/p4merge.app/Contents/MacOS/p4merge $* -Skrypt do obsługi diff sprawdza czy zostało podanych 7 argumentów i przekazuje dwa z nicg do skryptu obsłiugującego merge. Domyślnie, Git przekazuje te argumenty do programu obsługującego pokazywanie różnic: +Skrypt do obsługi diff sprawdza czy zostało podanych 7 argumentów i przekazuje dwa z nich do skryptu obsługującego merge. Domyślnie, Git przekazuje te argumenty do programu obsługującego pokazywanie różnic: @@ -234,7 +237,7 @@ Skrypt do obsługi diff sprawdza czy zostało podanych 7 argumentów i przekazuj -Ponieważ potrzebujesz tylko argumentów `stary-plik` i `nowy-plik`, w skrypcie przekazujesz tylko te które potrzebujesz. +Ponieważ chcesz tylko argumentów `stary-plik` i `nowy-plik`, w skrypcie przekazujesz tylko te które potrzebujesz. @@ -242,14 +245,14 @@ Ponieważ potrzebujesz tylko argumentów `stary-plik` i `nowy-plik`, w skrypcie #!/bin/sh [ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5" -Musisz zwrócić uwagę, czy te narzędzia mają poprawne uprawnienia: +Musisz zwrócić uwagę, czy te skrypty mają poprawne uprawnienia: $ sudo chmod +x /usr/local/bin/extMerge $ sudo chmod +x /usr/local/bin/extDiff -Teraz możesz zmienić ustawienia, +Teraz możesz ustawić swój plik konfiguracyjny, aby korzystał z innych niż domyślne programów do łączenia i rozwiązywania konfliktów. Dostępnych jest kilka opcji konfiguracyjnych: `merge.tool` wskazująca jaką strategię TODO @@ -259,7 +262,9 @@ Teraz możesz zmienić ustawienia, $ git config --global mergetool.trustExitCode false $ git config --global diff.external extDiff -or you can edit your `~/.gitconfig` file to add these lines: +lub możesz wyedytować swój plik `~/.gitconfig` i dodać następujące linie: + + [merge] tool = extMerge @@ -269,34 +274,54 @@ or you can edit your `~/.gitconfig` file to add these lines: [diff] external = extDiff -After all this is set, if you run diff commands such as this: +Po wprowadzeniu tych ustawień, jeżeli uruchomisz komendę diff w ten sposób: + + $ git diff 32d1776b1^ 32d1776b1 -Instead of getting the diff output on the command line, Git fires up P4Merge, which looks something like Figure 7-1. +Zamiast wyniku pokazanego w wierszu poleceń, Git uruchomi P4Merge, pokazując wynik podobny do tego zamieszczonego na Rysunku 7-1. + + Insert 18333fig0701.png Figure 7-1. P4Merge. -If you try to merge two branches and subsequently have merge conflicts, you can run the command `git mergetool`; it starts P4Merge to let you resolve the conflicts through that GUI tool. +Jeżeli spróbujesz wykonać łączenie (ang. merge) na dwóch gałęziach, które zakończy się konfliktem, możesz uruchomić komendę `git mergetool`; zostanie uruchomiony skrypt P4Merge, pozwalający na rozwiązanie konfliktów poprzez interfejs graficzny GUI. + + + +Zaletą tej konfiguracji jest to, że możesz zmienić łatwo zmienić narzędzia służące do porównywania (diff), oraz łączenia (merge). Na przykład, aby skrypty `extDiff` i `extMerge` uruchamiały KDiff3, musisz tylko zmienić plik `extMerge`: -The nice thing about this wrapper setup is that you can change your diff and merge tools easily. For example, to change your `extDiff` and `extMerge` tools to run the KDiff3 tool instead, all you have to do is edit your `extMerge` file: + $ cat /usr/local/bin/extMerge #!/bin/sh /Applications/kdiff3.app/Contents/MacOS/kdiff3 $* -Now, Git will use the KDiff3 tool for diff viewing and merge conflict resolution. +teraz, Git będzie używał programu KDiff3 podczas pokazywania różnic oraz rozwiązywania konfliktów. -Git comes preset to use a number of other merge-resolution tools without your having to set up the cmd configuration. You can set your merge tool to kdiff3, opendiff, tkdiff, meld, xxdiff, emerge, vimdiff, or gvimdiff. If you’re not interested in using KDiff3 for diff but rather want to use it just for merge resolution, and the kdiff3 command is in your path, then you can run + + +Git jest wstępnie skonfigurowany do używania wielu innych narzędzi do łączenia i rozwiązywania konfliktów, bez konieczności wprowadzania konfiguracji odpowiednich komend. Możesz wybrać narzędzia takie jak kdiff3, opendiff, tkdiff, meld, xxdiff, emerge, vimdiff, oraz gvimdiff. Jeżeli nie chcesz używać KDiff3 do pokazywania różnic, ale chcesz aby dalej służył do rozwiązywania konfliktów, w przypadku gdy kdiff3 znajduje się w zmiennej środowiskowej PATH, możesz uruchomić + + $ git config --global merge.tool kdiff3 -If you run this instead of setting up the `extMerge` and `extDiff` files, Git will use KDiff3 for merge resolution and the normal Git diff tool for diffs. +Jeżeli uruchomić tą komendę, zamiast ustawienia plików `extMerge` i `extDiff`, Git będzie używał KDiff3 do rozwiązywania konfliktów i standardowego narzędzia Git diff do pokazywania różnic. + + + +### Formatowanie i białe znaki ### + + + +Problemy związane z formatowaniem i białymi znakami są jednym z bardziej uciążliwych i wyrafinowanych problemów, które wielu deweloperów może spotkać podczas współpracy, szczególnie jeżeli korzystają z różnych systemów operacyjnych. Bardzo łatwo można wprowadzić zmiany w łatach lub innych modyfikacjach, które -### Formatting and Whitespace ### +Git posiada kilka opcji konfiguracyjnych, które pomagają rozwiązać te problemy. -Formatting and whitespace issues are some of the more frustrating and subtle problems that many developers encounter when collaborating, especially cross-platform. It’s very easy for patches or other collaborated work to introduce subtle whitespace changes because editors silently introduce them or Windows programmers add carriage returns at the end of lines they touch in cross-platform projects. Git has a few configuration options to help with these issues. + #### core.autocrlf #### From 7d14ff208e9fe039b41a240e37c43df430bfc86c Mon Sep 17 00:00:00 2001 From: Kune Keiseiie Date: Wed, 9 Oct 2013 01:51:09 +0900 Subject: [PATCH 019/862] [th] Retranslate README file --- th/README | 56 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/th/README b/th/README index 1c843bad6..ff4219025 100644 --- a/th/README +++ b/th/README @@ -1,23 +1,47 @@ -เนื้อหาหนังสือ Pro Git -===================== +[![Build Status](https://secure.travis-ci.org/progit/progit.png?branch=master)](https://travis-ci.org/progit/progit) -นี่คือซอร์สโค้ดของเนื้อหาในหนังสือ Pro Git ซึ่งอยู่ภายใต้สิทธิบัตรแบบ -Creative Commons Attribution-Non Commercial-Share Alike 3.0 ผู้เขียนหวังว่า -คุณจะชอบเนื้อหาเหล่านี้ และหวังว่าหนังสือเล่มนี้จะช่วยให้คุณเรียนรู้ -เกี่ยวกับ Git ได้ไม่มากก็น้อย สุดท้ายนี้ผมหวังว่าคุณจะสนับสนุน Apress -และตัวผู้เขียนโดยการซื้อหนังสือแบบรูปเล่มที่ Amazon นะครับ: +# เนื้อหาภายในหนังสือ Pro Git + +ภายในนี้คือต้นฉบับของเนื้อหาภายใน Pro Git ทั้งหมด เนื้อหาในหนังสือ Pro Git ใช้สัญญาอนุญาตของครีเอทีฟคอมมอนส์เวอร์ชัน 3.0 ชนิด "อ้างอิงแหล่งที่มา ห้ามนำไปใช้เพื่อการค้า และให้อนุญาตต่อไปแบบเดียวกัน" +เราหวังว่าหนังสือเล่มนี้จะช่วยให้เรียนรู้การใช้ Git ได้สะดวกขึ้น คุณสามารถสนับสนุนเราและสำนักพิมพ์ Apress ได้โดยสั่งซื้อหนังสือเล่มนี้ผ่าน Amazon http://tinyurl.com/amazonprogit +หรือสามารถเข้าถึงที่: + +http://git-scm.com/book/ + +# การสร้าง Ebooks + +บนระบบปฏิบัติการ Fedora เวอร์ชัน 16 ขึ้นไป สามารถใช้คำสั่งด้านล่างนี้เพื่อสร้าง ebook ได้ + + $ yum install ruby calibre rubygems ruby-devel rubygem-ruby-debug rubygem-rdiscount + $ makeebooks en # will produce a mobi + +ในระบบปฏิบัติการ MacOS สามารถทำตามขั้นตอนดังนี้ + +1. ติดตั้ง ruby และ rubygems +2. `$ gem install rdiscount` +3. ดาวน์โหลดและติดตั้งโปรแกรม Calibre, command line tools และโปรแกรมสำหรับสร้างไฟล์ PDF: + * pandoc: http://johnmacfarlane.net/pandoc/installing.html + * xelatex: http://tug.org/mactex/ +4. `$ makeebooks th` # จะได้ไฟล์ที่มี extension `.mobi` + +# ข้อผิดพลาด + +หากพบข้อผิดพลาดภายในหนังสือหรือพบจุดที่ต้องแก้ไข กรุณาแจ้งปัญหาผ่านระบบ issue ของ GitHub โดยการ[สร้าง issue](https://github.com/progit/progit/issues/new) +หลังจากสร้าง issue แล้ว ผู้ดูแลจะเข้ามารับเรื่องและดำเนินการต่อไป + + +# การแปลหนังสือ -ข้อผิดพลาด -===================== -ถ้าคุณพบข้อผิดพลาดในเนื้อหาที่ต้องมีการแก้ไข กรุณาอีเมล์ผู้เขียนได้ที่ -schacon at gmail dot com ครับ +หากต้องการแปลเนื้อหาภายในหนังสือ คุณสามารถแปลเนื้อหาภายในโฟลเดอร์ย่อยที่ตรงกับภาษาที่แปล ชื่อของโฟลเดอร์ย่อยจะใช้รหัสภาษาแบบ [ISO 639](http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) +เมื่อแปลเสร็จเรียบร้อยแล้ว ขอให้ส่ง pull request กลับมายัง repository เดิม +# การส่ง pull request -สำหรับผู้แปล -===================== -ถ้าคุณต้องการแปลหนังสือเล่มนี้ กรุณาสร้างเนื้อหาแปลในไดเร็คทอรี่ย่อยที่เหมาะสม -(เช่น: 'it' สำหรับภาษาอิตาเลียน ฯลฯ) และส่ง pull request ไปที่ผู้เขียน (schacon) -นะครับ จากนั้นผู้เขียนจะนำเนื้อหาที่แปลแล้วขึ้นไปไว้ที่ progit.org +* ขอให้แน่ใจว่า encoding ของไฟล์เป็น UTF-8 +* โปรดแยกการ pull request หากคุณแก้ไขเนื้อหาที่เป็นภาษาหลักของหนังสือ และเนื้อหาที่แปลจากภาษาหลัก +* หากแปลเนื้อหาภายในหนังสือ ขอให้เขียน commit message โดยให้มีรหัสของภาษาตาม ISO 639 ที่ครอบด้วยวงเล็บแบบก้ามปู ตามด้วยสิ่งที่เปลี่ยนแปลง เช่น `[de] Update chapter 2` +* ตรวจสอบการ conflict ด้วยทุกครั้ง เนื่องจากเมื่อเกิด conflict ผู้ดูแลจะไม่รวมด้วยมือ +* ขอให้แน่ใจว่าสิ่งที่แก้ไขสามารถแปลงเป็น PDF, ebook และสามารถนำขึ้นเว็บไซต์ git-scm.com ได้โดยไม่มีปัญหาใด ๆ \ No newline at end of file From 50c976804c7e81a4a730a091edde2bcbeb142770 Mon Sep 17 00:00:00 2001 From: Reizinixc Date: Wed, 9 Oct 2013 02:16:24 +0900 Subject: [PATCH 020/862] Rename README to README.md Fix document not render in GitHub --- th/{README => README.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename th/{README => README.md} (99%) diff --git a/th/README b/th/README.md similarity index 99% rename from th/README rename to th/README.md index ff4219025..e32ffd548 100644 --- a/th/README +++ b/th/README.md @@ -44,4 +44,4 @@ http://git-scm.com/book/ * โปรดแยกการ pull request หากคุณแก้ไขเนื้อหาที่เป็นภาษาหลักของหนังสือ และเนื้อหาที่แปลจากภาษาหลัก * หากแปลเนื้อหาภายในหนังสือ ขอให้เขียน commit message โดยให้มีรหัสของภาษาตาม ISO 639 ที่ครอบด้วยวงเล็บแบบก้ามปู ตามด้วยสิ่งที่เปลี่ยนแปลง เช่น `[de] Update chapter 2` * ตรวจสอบการ conflict ด้วยทุกครั้ง เนื่องจากเมื่อเกิด conflict ผู้ดูแลจะไม่รวมด้วยมือ -* ขอให้แน่ใจว่าสิ่งที่แก้ไขสามารถแปลงเป็น PDF, ebook และสามารถนำขึ้นเว็บไซต์ git-scm.com ได้โดยไม่มีปัญหาใด ๆ \ No newline at end of file +* ขอให้แน่ใจว่าสิ่งที่แก้ไขสามารถแปลงเป็น PDF, ebook และสามารถนำขึ้นเว็บไซต์ git-scm.com ได้โดยไม่มีปัญหาใด ๆ From 4fe36ebd8bf98cc86ba274a0cda1850485474ba8 Mon Sep 17 00:00:00 2001 From: Johan 't Hart Date: Sat, 23 Mar 2013 23:43:24 +0100 Subject: [PATCH 021/862] nl: Fixed some typo's in chapter 8 --- nl/08-git-and-other-scms/01-chapter8.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nl/08-git-and-other-scms/01-chapter8.markdown b/nl/08-git-and-other-scms/01-chapter8.markdown index af24983ef..6600ab4f2 100644 --- a/nl/08-git-and-other-scms/01-chapter8.markdown +++ b/nl/08-git-and-other-scms/01-chapter8.markdown @@ -485,7 +485,7 @@ Je import is nu klaar om naar je nieuwe Git server gepushed te worden. Als het door jou gebruikte systeem niet Subversion of Perforce is, zou je online voor een importeerder moeten zoeken – er zijn importeerders van goede kwaliteit beschikbaar voor CVS, Clear Case, Visual Source Safe, en zelfs een map met archieven. Als geen van deze tools voor jou geschikt is, je hebt een zeldzamer tool, of je hebt om een andere reden een eigen import proces nodig, dan zou je `git fast-import` moeten gebruiken. Dit commando leest eenvoudige instructies van stdin om specifieke Git data te schrijven. Het is veel eenvoudiger om op deze manier Git objecten te maken, dan de rauwe Git commando's uit te voeren, of om te proberen de rauwe objecten te schrijven (zie hoofdstuk 9 voor meer informatie). Op deze manier kun je een import script schrijven dat de noodzakelijke data uit het systeem leest dat je aan het importeren bent en rechttoe rechtaan instructies op stdout afdrukt. Je kunt dit programma dan uitvoeren en de output door `git fast-import` sluizen. -Voor een snelle demonstratie zul je een eenvoudige importeerde schrijven. Stel dan je in current werkt, waarbij je je project eens in de zoveel tijd backup'ed door de map te kopiëren naar een backup map die gelabeld is met de tijd `back_YYYY_MM_DD`, en je wil dit in Git importeren. Je mappenstructuur ziet er zo uit: +Voor een snelle demonstratie zul je een eenvoudige importeerder schrijven. Stel dat je in current werkt, waarbij je je project eens in de zoveel tijd backup'ed door de map te kopiëren naar een backup map die gelabeld is met de tijd `back_YYYY_MM_DD`, en je wil dit in Git importeren. Je mappenstructuur ziet er zo uit: $ ls /opt/import_from back_2009_01_02 From 33a8a77765274ff45c6ce60c1a643eef5dcb5f47 Mon Sep 17 00:00:00 2001 From: Johan 't Hart Date: Sun, 24 Mar 2013 00:03:48 +0100 Subject: [PATCH 022/862] nl: Chapter 8: Made some sentences more fluent. --- nl/08-git-and-other-scms/01-chapter8.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nl/08-git-and-other-scms/01-chapter8.markdown b/nl/08-git-and-other-scms/01-chapter8.markdown index 6600ab4f2..80b861560 100644 --- a/nl/08-git-and-other-scms/01-chapter8.markdown +++ b/nl/08-git-and-other-scms/01-chapter8.markdown @@ -496,9 +496,9 @@ Voor een snelle demonstratie zul je een eenvoudige importeerder schrijven. Stel Om naar een Git map te importeren, moet je bekijken hoe Git zijn data opslaat. Je kunt je misschien herinneren dat Git in fundament een gelinkte lijst is met commit objecten die naar een snapshot van inhoud wijzen. Het enige dat je hoeft te doen, is `fast-import` vertellen wat de inhoud snapshots zijn, welke commit data er naar wijst en de volgorde waarin ze moeten staan. Je strategie bestaat uit het doorlopen van de snapshots en commits te creëren met de inhoud van iedere map, waarbij je iedere commit terug linkt met de vorige. -Zoals je dat gedaan hebt in de "Een Voorbeeld van Git Afgedwongen Beleid" sectie van Hoofdstuk 7, gaan we dit in Ruby schrijven, omdat het is waar ik over het algemeen mee werk en het neigt eenvoudig te lezen te zijn. Je kunt dit voorbeeld vrij eenvoudig schrijven in alles waar je bekend mee bent – het hoeft alleen de juiste informatie naar stdout te schrijven. En dat betekent dat als je op Windows werkt, je erg voorzichtig moet zijn om geen carriage returns te introduceren aan het einde van je regels – git fast-import is erg kieskeurig in de manier waarop hij slechts line feeds (LF) wil hebben en niet de cariage return line feeds (CRLF), die Windows gebruikt. +Zoals je dat gedaan hebt in de "Een Voorbeeld van Git Afgedwongen Beleid" sectie van Hoofdstuk 7, gaan we dit in Ruby schrijven, omdat ik daar over het algemeen mee werk en het is relatief eenvoudig te lezen. Je kunt dit voorbeeld vrij eenvoudig schrijven in alles waar je bekend mee bent – het hoeft alleen de juiste informatie naar stdout te schrijven. En dat betekent dat als je op Windows werkt, je erg voorzichtig moet zijn om geen carriage returns te introduceren aan het einde van je regels – git fast-import is erg kieskeurig in de manier waarop hij slechts line feeds (LF) wil hebben en niet de cariage return line feeds (CRLF), die Windows gebruikt. -Om te beginnen ga je naar de doelmap en identificeer je iedere submap, waarvan elk een snapshot is dat je als commit wil importeren. Je zult in iedere submap gaan en de noodzakelijke commando's printen om ze te exporteren. Je basis hoofdlus ziet er zo uit: +Om te beginnen ga je naar de doelmap en identificeer je iedere submap, waarvan elk een snapshot is dat je als commit wil importeren. Dan ga je in iedere submap en print de noodzakelijke commando's om ze te exporteren. Je basis hoofdlus ziet er zo uit: last_mark = nil @@ -528,7 +528,7 @@ Je zult dit doen door een lijst van mappen te creëren en de index waarde als me ($marks.index(dir) + 1).to_s end -Nu dat je een geheel getal hebt als voorstelling van je commit, moet je een datum hebben voor de commit metadata. Omdat de datum is uitgedrukt in de naam van de map, zul je het daar uit moeten halen. De volgende regel in de `print_export` bestand is +Nu dat je een geheel getal hebt als voorstelling van je commit, moet je een datum hebben voor de commit metadata. Omdat de datum is uitgedrukt in de naam van de map, zul je het daar uit moeten halen. De volgende regel in het `print_export` bestand is date = convert_dir_to_date(dir) From 7b620c3cadc33e8c08be631f8bb5e6dd1e3faf7d Mon Sep 17 00:00:00 2001 From: Brackmeister Date: Sat, 12 Oct 2013 01:04:12 +0200 Subject: [PATCH 023/862] Fixed a few obvious spelling, grammar, punctuation and capitalization errors in the branching chapter of the German translation. --- de/03-git-branching/01-chapter3.markdown | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/de/03-git-branching/01-chapter3.markdown b/de/03-git-branching/01-chapter3.markdown index 3b8f8cf6c..fece926d3 100644 --- a/de/03-git-branching/01-chapter3.markdown +++ b/de/03-git-branching/01-chapter3.markdown @@ -616,7 +616,7 @@ Abbildung 3-22. Ein 'git clone' gibt dir deinen eigenen `master`-Branch und `ori -Wenn du ein wenig an deinem lokalen `master`-Branch arbeitest und unterdessen jemand etwas zu `git.ourcompany.com` herauflädt, verändert er damit dessen `master`-Branch und eure Arbeitsverläufe entwickeln sich unterschiedlich. Indess bewegt sich dein `origin/master`-Zeiger nicht, solange du keinen Kontakt mit deinem `origin`-Server aufnimmst (siehe Abbildung 3-23). +Wenn du ein wenig an deinem lokalen `master`-Branch arbeitest und unterdessen jemand etwas zu `git.ourcompany.com` herauflädt, verändert er damit dessen `master`-Branch und eure Arbeitsverläufe entwickeln sich unterschiedlich. Indes bewegt sich dein `origin/master`-Zeiger nicht, solange du keinen Kontakt mit deinem `origin`-Server aufnimmst (siehe Abbildung 3-23). @@ -643,7 +643,7 @@ Abbildung 3-25. Einen weiteren Server als Quelle hinzufügen. -Nun kannst du einfach `git fetch teamone` ausführen um alles vom Server zu holen was du noch nicht hast. Da der Datenbestand auf dem Teamserver einen Teil der Informationen auf deinem `origin`-Server ist, holt Git keine Daten, erstellt allerdings einen Remote-Branch namens `teamone/master`, der auf den gleichen Commit wie `teamone`s `master`-Branch zeigt (siehe Abbildung 3-26). +Nun kannst du einfach `git fetch teamone` ausführen um alles vom Server zu holen was du noch nicht hast. Da der Datenbestand auf dem Teamserver ein Teil der Informationen auf deinem `origin`-Server ist, holt Git keine Daten, erstellt allerdings einen Remote-Branch namens `teamone/master`, der auf den gleichen Commit wie `teamone`s `master`-Branch zeigt (siehe Abbildung 3-26). @@ -706,7 +706,7 @@ Dies erstellt dir einen lokalen bearbeitbaren Branch mit der Grundlage des `orig -Das Auschecken eines lokalen Branches von einem Remote-Branch erzeugt automatisch einen sogenannten _Tracking-Branch_. Tracking Branches sind lokale Branches mit einer direkten Beziehung zu dem Remote-Zweig. Wenn du dich in einem Tracking-Branch befindest und `git push` eingibst, weiß Git automatisch zu welchem Server und Repository es Pushen soll. Ebenso führt `git pull` in einem dieser Branches dazu, dass alle entfernten Referenzen gefetched und automatisch in den Zweig gemerged werden. +Das Auschecken eines lokalen Branches von einem Remote-Branch erzeugt automatisch einen sogenannten _Tracking-Branch_. Tracking Branches sind lokale Branches mit einer direkten Beziehung zu dem Remote-Zweig. Wenn du dich in einem Tracking-Branch befindest und `git push` eingibst, weiß Git automatisch zu welchem Server und Repository es pushen soll. Ebenso führt `git pull` in einem dieser Branches dazu, dass alle entfernten Referenzen gefetched und automatisch in den Zweig gemerged werden. @@ -786,7 +786,7 @@ In unserem Beispiel würdest du folgendes ausführen: -Dies funktioniert, indem Git zu dem gemeinsamen/allgemeinen Vorfahren [gemeinsamer Vorfahr oder der Ursprung der beiden Branches?] der beiden Branches (des Zweiges auf dem du arbeitest und des Zweiges auf den du _rebasen_ möchtest) geht, die Differenzen jedes Commits des aktuellen Branches ermittelt und temporär in einer Datei ablegt. Danach wird der aktuelle Branch auf den Schnittpunkt der beiden Zweige zurückgesetzt und alle zwischengespeicherte Commits nacheinander auf Zielbranch angewendet. Die Abbildung 3-29 bildet diesen Prozess ab. +Dies funktioniert, indem Git zu dem gemeinsamen/allgemeinen Vorfahren [gemeinsamer Vorfahr oder der Ursprung der beiden Branches?] der beiden Branches (des Zweiges auf dem du arbeitest und des Zweiges auf den du _rebasen_ möchtest) geht, die Differenzen jedes Commits des aktuellen Branches ermittelt und temporär in einer Datei ablegt. Danach wird der aktuelle Branch auf den Schnittpunkt der beiden Zweige zurückgesetzt und alle zwischengespeicherte Commits nacheinander auf den Zielbranch angewendet. Die Abbildung 3-29 bildet diesen Prozess ab. @@ -804,7 +804,7 @@ Abbildung 3-30. Fast-forward des Master-Branches. -Nun ist der Schnappschuss, auf den C3 zeigt, exakt der gleiche, wie der auf den C5 in dem Merge-Beispiel gezeigt hat. Bei dieser Zusammenführung entsteht kein unterschiedliches Produkt, durch Rebasing ensteht allerdings ein sauberer Verlauf. Bei genauerer Betrachtung der Historie, entpuppt sich der Rebased-Branch als linearer Verlauf - es scheint als sei die ganze Arbeit in einer Serie entstanden, auch wenn sie in Wirklichkeit parallel stattfand. +Nun ist der Schnappschuss, auf den C3' zeigt, exakt der gleiche, wie der auf den C5 in dem Merge-Beispiel gezeigt hat. Bei dieser Zusammenführung entsteht kein unterschiedliches Produkt, durch Rebasing ensteht allerdings ein sauberer Verlauf. Bei genauerer Betrachtung der Historie entpuppt sich der Rebased-Branch als linearer Verlauf - es scheint als sei die ganze Arbeit in einer Serie entstanden, auch wenn sie in Wirklichkeit parallel stattfand. @@ -834,7 +834,7 @@ Stell dir vor du entscheidest dich deine clientseitigen Änderungen für einen R -Das bedeutet einfach “Checke den Client-Branch aus, finde die Patches heraus die auf dem gemeinsamen Vorfahr der `client`- und `server`-Branches basieren und wende sie erneut auf dem `master`-Branch an.” Das ist ein bisschen komplex aber das Ergebnis - wie in Abbildung 3-32 - ist richtig cool. +Das bedeutet einfach “Checke den Client-Branch aus, finde die Patches heraus die auf dem gemeinsamen Vorfahr der `client`- und `server`-Branches basieren und wende sie erneut auf dem `master`-Branch an.” Das ist ein bisschen komplex, aber das Ergebnis - wie in Abbildung 3-32 - ist richtig cool. @@ -900,7 +900,7 @@ Ahh, aber der ganze Spaß mit dem Rebasing kommt nicht ohne seine Schattenseiten -Wenn du diesem Ratschlag folgst ist alles in ordnung. Falls nicht werden die Leute dich hassen und du wirst von deinen Freunden und deiner Familie verachtet. +Wenn du diesem Ratschlag folgst ist alles in Ordnung. Falls nicht, werden die Leute dich hassen und du wirst von deinen Freunden und deiner Familie verachtet. @@ -908,7 +908,7 @@ Wenn du Zeug rebased, hebst du bestehende Commits auf und erstellst stattdessen -Lass uns mal ein Beispiel betrachten wie das Rebasen veröfentlichter Arbeit Probleme verursachen kann. Angenommen du klonst von einem zentralen Server und werkelst ein bisschen daran rum. Dein Commit-Verlauf sieht wie in Abbildung 3-36 aus. +Lass uns mal ein Beispiel betrachten wie das Rebasen veröffentlichter Arbeit Probleme verursachen kann. Angenommen du klonst von einem zentralen Server und werkelst ein bisschen daran rum. Dein Commit-Verlauf sieht wie in Abbildung 3-36 aus. @@ -944,11 +944,11 @@ Abbildung 3-39. Du mergst die gleiche Arbeit nochmals in einen neuen Merge-Commi -Irgendwann musst du seine Arbeit einmergen, damit du auch zukünftig mit dem anderen Entwickler zusammenarbeiten kannst. Danach wird dein Commit-Verlauf sowohl den C4 als auch den C4'-Commit enthalten, weche zwar verschiedene SHA-1-Hashes besitzen aber die gleichen Änderungen und die gleiche Commit-Beschreibung enthalten. Wenn du so einen Verluaf mit `git log` betrachtest, wirst immer zwei Commits des gleichen Autors, zur gleichen Zeit und mit der gleichen Commit-Nachricht sehen. Was ganz schön verwirrend ist. Wenn du diesen Verlauf außerdem auf den Server hochlädst, wirst du dort alle rebasierten Commits einführen, was auch noch andere verwirren kann. +Irgendwann musst du seine Arbeit einmergen, damit du auch zukünftig mit dem anderen Entwickler zusammenarbeiten kannst. Danach wird dein Commit-Verlauf sowohl den C4 als auch den C4'-Commit enthalten, weche zwar verschiedene SHA-1-Hashes besitzen aber die gleichen Änderungen und die gleiche Commit-Beschreibung enthalten. Wenn du so einen Verlauf mit `git log` betrachtest, wirst du immer zwei Commits des gleichen Autors, zur gleichen Zeit und mit der gleichen Commit-Nachricht sehen. Was ganz schön verwirrend ist. Wenn du diesen Verlauf außerdem auf den Server hochlädst, wirst du dort alle rebasierten Commits einführen, was auch noch andere verwirren kann. -Wenn du rebasing als Weg behandelst um aufzuräumen und mit Commits zu arbeiten, bevor du sie hochlädst und wenn du nur Commits rebased die noch nie publiziert wurden, dann fährst du goldrichtig. Wenn du Commits rebased die bereits veröffentlicht wurden und Leute vielleicht schon ihre Arbeit darauf aufgebaut haben, dann bist du vielleicht für frustrierenden Ärger verantwortlich. +Wenn du rebasing als Weg behandelst um aufzuräumen und mit Commits zu arbeiten, bevor du sie hochlädst und wenn du nur Commits rebased, die noch nie publiziert wurden, dann fährst du goldrichtig. Wenn du Commits rebased die bereits veröffentlicht wurden und Leute vielleicht schon ihre Arbeit darauf aufgebaut haben, dann bist du vielleicht für frustrierenden Ärger verantwortlich. ## Zusammenfassung ## From 273f602654bcd13c7ffd624d428f9138209ca96a Mon Sep 17 00:00:00 2001 From: tendium Date: Tue, 15 Oct 2013 15:02:13 +0200 Subject: [PATCH 024/862] =?UTF-8?q?Second=20version=20of=20the=20patch=20(?= =?UTF-8?q?=D0=B1=D0=B5=D1=81=D0=BF=D0=BE=D1=80=D1=8F=D0=B4=D0=BE=D0=BA=20?= =?UTF-8?q?=3D>=20=D0=BF=D1=83=D1=82=D0=B0=D0=BD=D0=B8=D1=86=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ru/03-git-branching/01-chapter3.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/03-git-branching/01-chapter3.markdown b/ru/03-git-branching/01-chapter3.markdown index 34bc4aea8..98b20872d 100644 --- a/ru/03-git-branching/01-chapter3.markdown +++ b/ru/03-git-branching/01-chapter3.markdown @@ -567,7 +567,7 @@ Insert 18333fig0335.png Если вы будете следовать этому указанию, всё будет хорошо. Если нет — люди возненавидят вас, вас будут презирать ваши друзья и семья. -Когда вы что-то перемещаете, вы отменяете существующие коммиты и создаёте новые, которые похожи на старые, но являются другими. Если вы выкладываете (push) свои коммиты куда-нибудь, и другие забирают (pull) их себе и в дальнейшем основывают на них свою работу, а затем вы переделываете эти коммиты командой `git rebase` и выкладываете их снова, ваши коллеги будут вынуждены заново выполнять слияние для своих наработок. В итоге вы получите беспорядок, когда в очередной раз попытаетесь включить их работу в свою. +Когда вы что-то перемещаете, вы отменяете существующие коммиты и создаёте новые, которые похожи на старые, но являются другими. Если вы выкладываете (push) свои коммиты куда-нибудь, и другие забирают (pull) их себе и в дальнейшем основывают на них свою работу, а затем вы переделываете эти коммиты командой `git rebase` и выкладываете их снова, ваши коллеги будут вынуждены заново выполнять слияние для своих наработок. В итоге вы получите путаницу, когда в очередной раз попытаетесь включить их работу в свою. Давайте рассмотрим пример того, как перемещение публично доступных наработок может вызвать проблемы. Представьте себе, что вы склонировали себе репозиторий с центрального сервера и поработали в нём. И ваша история коммитов выглядит как на рисунке 3-36. From 4c9089110ca0c9ab3b77f550a0f9beb123e8a330 Mon Sep 17 00:00:00 2001 From: Denis Costa Date: Sat, 19 Oct 2013 01:02:59 -0300 Subject: [PATCH 025/862] =?UTF-8?q?Fix=20typo.=20tr=C3=A7os=20->=20tra?= =?UTF-8?q?=C3=A7os.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pt-br/02-git-basics/01-chapter2.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pt-br/02-git-basics/01-chapter2.markdown b/pt-br/02-git-basics/01-chapter2.markdown index 0893b149a..8051f8914 100644 --- a/pt-br/02-git-basics/01-chapter2.markdown +++ b/pt-br/02-git-basics/01-chapter2.markdown @@ -595,7 +595,7 @@ Este comando funciona com vários formatos — você pode especificar uma data e Você pode ainda filtrar a lista de commits que batem com alguns critérios de busca. A opção `--author` permite que você filtre por algum autor específico, e a opção `--grep` deixa você buscar por palavras chave nas mensagens dos commits. (Note que se você quer especificar ambas as opções author e grep, você deve adicionar `--all-match` ou o comando considerará commits que batem com qualquer um). -A última opção realmente útil para passar para `git log` como um filtro é o caminho. Se você especificar um diretório ou um nome de arquivo, você pode limitar a saída a commits que modificaram aqueles arquivos. Essa é sempre a última opção e é geralmente precedida por dois trços (`--`) para separar caminhos das opções. +A última opção realmente útil para passar para `git log` como um filtro é o caminho. Se você especificar um diretório ou um nome de arquivo, você pode limitar a saída a commits que modificaram aqueles arquivos. Essa é sempre a última opção e é geralmente precedida por dois traços (`--`) para separar caminhos das opções. Na Tabela 2-3 nós listamos estas e outras opções comuns para sua referência. From dd6488cbb96a276303e47e7c515c988b0f3b1859 Mon Sep 17 00:00:00 2001 From: Jean-Noel Avila Date: Fri, 30 Aug 2013 23:07:34 +0200 Subject: [PATCH 026/862] enable parallel check of languages Use parallel to spawn as many subprocesses as possible to accelerate the tests. --- Gemfile | 2 +- Rakefile | 127 ++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 80 insertions(+), 49 deletions(-) diff --git a/Gemfile b/Gemfile index 79f6c3029..aa6b79223 100644 --- a/Gemfile +++ b/Gemfile @@ -2,4 +2,4 @@ source 'https://rubygems.org' gem 'maruku', '0.6.1' gem 'redcarpet' -gem 'rdiscount' +gem 'parallel' diff --git a/Rakefile b/Rakefile index 03c0bb9e7..836f5044b 100644 --- a/Rakefile +++ b/Rakefile @@ -168,7 +168,78 @@ class StderrDecorator end end +def test_lang(lang) + error_code = false + chapter_figure = { + "01-introduction" => 7, + "02-git-basics" => 2, + "03-git-branching" => 39, + "04-git-server" => 15, + "05-distributed-git" => 27, + "06-git-tools" => 1, + "07-customizing-git" => 3, + "08-git-and-other-scms" => 0, + "09-git-internals" => 4} + mark = '' + source_files = FileList.new(File.join(lang, '0*', '*.markdown')).sort + source_files.each do |mk_filename| + mk_file = File.open(mk_filename, 'r') do |mk| + mark+= mk.read.encode("UTF-8") + end + src_file = File.open(mk_filename, 'r') + figure_count = 0 + until src_file.eof? + line = src_file.readline + matches = line.match /^#/ + if matches + if line.match /^(#+).*#[[:blank:]]+$/ + print "\nBadly formatted title in #{mk_filename}: #{line}\n" + error_code = true + end + end + if line.match /^\s*Insert\s(.*)/ + figure_count = figure_count + 1 + end + end + # This extraction is a bit contorted, because the pl translation renamed + # the files, so the match is done on the directories. + tab_fig_count = chapter_figure[File.basename(File.dirname(mk_filename))] + expected_figure_count = tab_fig_count ? tab_fig_count:0 + if figure_count > expected_figure_count + print "\nToo many figures declared in #{mk_filename}\n" + error_code = true + end + end + begin + require 'maruku' + code = Maruku.new(mark, :on_error => :raise, :error_stream => StderrDecorator.new) + rescue + print $! + error_code = true + end + error_code +end + namespace :ci do + desc "Parallel Continuous integration" + task :parallel_check do + require 'parallel' + langs = FileList.new('??')+FileList.new('??-??') + results = Parallel.map(langs) do |lang| + Rake::Task["ci:" +lang+"_check"].execute + 0 + end + fail "At least one language conversion failed" if results.any? { |result| result!=0} + end + + (FileList.new('??')+FileList.new('??-??')).each do |lang| + desc "testing " + lang + task (lang+"_check").to_sym do + error_code = test_lang(lang) + fail "processing #{lang} KO\n" if error_code + print "processing #{lang} OK\n" + end + end desc "Continuous Integration" task :check do @@ -184,59 +255,19 @@ namespace :ci do end langs -= excluded_langs end - error_code = false - chapter_figure = { - "01-introduction" => 7, - "02-git-basics" => 2, - "03-git-branching" => 39, - "04-git-server" => 15, - "05-distributed-git" => 27, - "06-git-tools" => 1, - "07-customizing-git" => 3, - "08-git-and-other-scms" => 0, - "09-git-internals" => 4} + global_error_code = false langs.each do |lang| print "processing #{lang} " - mark = '' - source_files = FileList.new(File.join(lang, '0*', '*.markdown')).sort - source_files.each do |mk_filename| - mk_file = File.open(mk_filename, 'r') do |mk| - mark+= mk.read.encode("UTF-8") - end - src_file = File.open(mk_filename, 'r') - figure_count = 0 - until src_file.eof? - line = src_file.readline - matches = line.match /^#/ - if matches - if line.match /^(#+).*#[[:blank:]]+$/ - print "\nBadly formatted title in #{mk_filename}: #{line}\n" - error_code = true - end - end - if line.match /^\s*Insert\s(.*)/ - figure_count = figure_count + 1 - end - end - # This extraction is a bit contorted, because the pl translation renamed - # the files, so the match is done on the directories. - tab_fig_count = chapter_figure[File.basename(File.dirname(mk_filename))] - expected_figure_count = tab_fig_count ? tab_fig_count:0 - if figure_count > expected_figure_count - print "\nToo many figures declared in #{mk_filename}\n" - error_code = true - end - end - begin - code = Maruku.new(mark, :on_error => :raise, :error_stream => StderrDecorator.new) - print "OK\n" - rescue + error_code=test_lang(lang) + if error_code print "KO\n" - print $! - error_code = true + else + print "OK\n" end + global_error_code|=error_code + end - fail "At least one language conversion failed" if error_code + fail "At least one language conversion failed" if global_error_code end end From 80cea1a541607440c70fc84e36e7531210cfb055 Mon Sep 17 00:00:00 2001 From: Denis Parchenko Date: Tue, 4 Jun 2013 22:58:15 +0300 Subject: [PATCH 027/862] Correct stylistic issues in Russian translation --- ru/04-git-server/01-chapter4.markdown | 4 ++-- ru/05-distributed-git/01-chapter5.markdown | 2 +- ru/06-git-tools/01-chapter6.markdown | 8 ++++---- ru/07-customizing-git/01-chapter7.markdown | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ru/04-git-server/01-chapter4.markdown b/ru/04-git-server/01-chapter4.markdown index 4d4cf4ee1..10f5e9784 100644 --- a/ru/04-git-server/01-chapter4.markdown +++ b/ru/04-git-server/01-chapter4.markdown @@ -189,7 +189,7 @@ Git-протокол — самый быстрый из доступных пр Сначала необходимо указать расположение файла для сохранения ключа (`.ssh/id_rsa`), затем дважды ввести пароль, который вы можете оставить пустым, если не хотите его вводить каждый раз, когда используете ключ. -Теперь каждый пользователь должен послать свой открытый ключ вам или тому, кто администрирует Git-сервер (предположим, что ваш SSH-сервер уже настроен на работу с открытыми ключами). Для этого им нужно скопировать всё содержимое файла с расширением `.pub` и отправить его по электронной почте. Открытый ключ выглядит как-то так: +Теперь каждый пользователь должен послать свой открытый ключ вам или тому, кто администрирует Git-сервер (предположим, что ваш SSH-сервер уже настроен на работу с открытыми ключами). Для этого им нужно скопировать всё содержимое файла с расширением `.pub` и отправить его по электронной почте. Открытый ключ выглядит следующим образом: $ cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU @@ -827,7 +827,7 @@ Insert 18333fig0413.png ### Ответвления проектов ### -Если вы хотите внести вклад в существующий проект, в который у вас нет права на отправку изменений, GitHub приветствует ответвления. Когда вы смотрите на страницу заинтересовавшего вас проекта и хотите немного поработать над ним, вы можете нажать на кнопку "Fork" в заголовке проекта, чтобы GitHub скопировал проект вашему пользователю, и вы смогли отправлять туда свои изменения. +Если вы хотите внести вклад в существующий проект, на отправку изменений в который у вас нет прав, GitHub приветствует ответвления. Когда вы смотрите на страницу заинтересовавшего вас проекта и хотите немного поработать над ним, вы можете нажать на кнопку "Fork" в заголовке проекта, чтобы GitHub скопировал проект вашему пользователю, и вы смогли отправлять туда свои изменения. Таким образом, проектам не нужно беспокоиться о добавлении пользователей в качестве участников для предоставления им доступа на отправку изменений. Люди могут ответвить проект и отправлять изменения в свою копию. А мейнтейнер главного проекта может вернуть эти изменения, добавляя форки как удалённые серверы и сливая из них наработки. diff --git a/ru/05-distributed-git/01-chapter5.markdown b/ru/05-distributed-git/01-chapter5.markdown index 08cd532ca..1ea5e3f30 100644 --- a/ru/05-distributed-git/01-chapter5.markdown +++ b/ru/05-distributed-git/01-chapter5.markdown @@ -33,7 +33,7 @@ Insert 18333fig0501.png Insert 18333fig0502.png Рисунок 5-2. Рабочий процесс с менеджером по интеграции. -Это очень распространённый тип рабочего процесса для сайтов вроде GitHub, где можно легко форкнуть проект и выложить свои изменения на всеобщее обозрение в собственную копию. Одно из главных преимуществ такого подхода — возможность продолжать работать, в то время как владелец основного репозитория может включить себе ваши изменения, когда ему угодно. Участникам проекта не придётся ждать, пока их изменения не будут включены в проект — каждый может работать в своём собственном ритме. +Это очень распространённый тип рабочего процесса для сайтов вроде GitHub, где можно легко форкнуть проект и выложить свои изменения на всеобщее обозрение в собственную копию. Одно из главных преимуществ такого подхода — возможность продолжать работать, в то время как владелец основного репозитория может включить себе ваши изменения, когда ему угодно. Участникам проекта не придётся ждать включения своих изменений в проект — каждый может работать в своём собственном ритме. ### Рабочий процесс с диктатором и его помощниками ### diff --git a/ru/06-git-tools/01-chapter6.markdown b/ru/06-git-tools/01-chapter6.markdown index 6a1d88245..37f95dd7b 100644 --- a/ru/06-git-tools/01-chapter6.markdown +++ b/ru/06-git-tools/01-chapter6.markdown @@ -70,7 +70,7 @@ Git может показать короткие уникальные сокра $ git show ca82a6dff817ec66f44342007202690a93763949 $ git show topic1 -Чтобы посмотреть, на какой именно SHA указывает ветка, или понять для какого-то из приведённых примеров, к каким SHA он сводится, можно использовать служебную (plumbing) утилиту Git'а, которая называется `rev-parse`. Вы можете заглянуть в главу 9 для получения большей информации о служебных утилитах; в основном `rev-parse` нужна для выполнения низкоуровневых операций и не предназначена для использования в повседневной работе. Однако, она может пригодиться, если вам необходимо разобраться, что происходит на самом деле. Сейчас вы можете попробовать применить `rev-parse` к своей ветке. +Чтобы посмотреть, на какой именно SHA указывает ветка, или понять для какого-то из приведённых примеров, к каким SHA он сводится, можно использовать служебную (plumbing) утилиту Git'а, которая называется `rev-parse`. Вы можете заглянуть в главу 9 для получения более подробной информации о служебных утилитах; в основном `rev-parse` нужна для выполнения низкоуровневых операций и не предназначена для использования в повседневной работе. Однако, она может пригодиться, если вам необходимо разобраться, что происходит на самом деле. Сейчас вы можете попробовать применить `rev-parse` к своей ветке. $ git rev-parse topic1 ca82a6dff817ec66f44342007202690a93763949 @@ -556,7 +556,7 @@ Insert 18333fig0601.png Снова напомним, что это команда для перемещения, то есть все коммиты в диапазоне `HEAD~3..HEAD` будут переписаны вне зависимости от того, меняли ли вы в них сообщение или нет. Не трогайте те коммиты, которые вы уже отправили на центральный сервер — сделав так, вы запутаете других разработчиков, дав им разные версии одних и тех же изменений. -Запуск этой команды выдаст вам в текстовом редакторе список коммитов, который будет выглядеть как-нибудь так: +Запуск этой команды выдаст вам в текстовом редакторе список коммитов, который будет выглядеть следующим образом: pick f7f3f6d changed my name a bit pick 310154e updated README formatting and added blame @@ -573,7 +573,7 @@ Insert 18333fig0601.png # However, if you remove everything, the rebase will be aborted. # -Важно отметить, что эти коммиты выведены в обратном порядке по сравнению с тем, как вы их обычно видите, используя команду `log`. Запустив `log`, вы получите что-то типа следующего: +Важно отметить, что эти коммиты выведены в обратном порядке по сравнению с тем, как вы их обычно видите, используя команду `log`. Запустив `log`, вы получите что-то вроде этого: $ git log --pretty=format:"%h %s" HEAD~3..HEAD a5f4a0d added cat-file @@ -736,7 +736,7 @@ Git также предоставляет несколько инструмен ### Аннотация файла ### -Если вы отловили ошибку в коде и хотите узнать, когда и по какой причине она была внесена, то аннотация файла — лучший инструмент для этого случая. Он покажет вам, какие коммиты модифицировали каждую строку файла в последний раз. Так что, если вы видите, что какой-то метод в коде глючный, то можно сделать аннотацию нужного файла с помощью `git blame`, чтобы посмотреть, когда и кем каждая строка метода была в последний раз отредактирована. В этом примере используется опция `-L`, чтобы ограничить вывод строками с 12ой по 22ую: +Если вы отловили ошибку в коде и хотите узнать, когда и по какой причине она была внесена, то аннотация файла — лучший инструмент для этого случая. Он покажет вам, какие коммиты модифицировали каждую строку файла в последний раз. Так что, если вы видите, что какой-то метод в коде содержит ошибку, то можно сделать аннотацию нужного файла с помощью `git blame`, чтобы посмотреть, когда и кем каждая строка метода была в последний раз отредактирована. В этом примере используется опция `-L`, чтобы ограничить вывод строками с 12ой по 22ую: $ git blame -L 12,22 simplegit.rb ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 12) def show(tree = 'master') diff --git a/ru/07-customizing-git/01-chapter7.markdown b/ru/07-customizing-git/01-chapter7.markdown index 3b501e569..3fc54cceb 100644 --- a/ru/07-customizing-git/01-chapter7.markdown +++ b/ru/07-customizing-git/01-chapter7.markdown @@ -571,7 +571,7 @@ Insert 18333fig0703.png #### Перехватчики для работы с e-mail #### -Для рабочих процессов, основанных на электронной почте, есть три специальных клиентских перехватчика. Все они вызываются командой `git am`, так что, если вы не пользуетесь этой командой в процессе своей работы, то можете смело переходить к следующему разделу. Если вы принимаете патчи, отправленные по e-mail и подготовленные с помощью `git format-patch`, то некоторые из них могут оказать для вас полезными. +Для рабочих процессов, основанных на электронной почте, есть три специальных клиентских перехватчика. Все они вызываются командой `git am`, так что, если вы не пользуетесь этой командой в процессе своей работы, то можете смело переходить к следующему разделу. Если вы принимаете патчи, отправленные по e-mail и подготовленные с помощью `git format-patch`, то некоторые из них могут оказаться для вас полезными. Первый запускаемый перехватчик — это `applypatch-msg`. Он принимает один аргумент — имя временного файла, содержащего предлагаемое сообщение коммита. Git прерывает наложение патча, если сценарий завершается с ненулевым кодом. Это может быть использовано для того, чтобы убедиться, что сообщение коммита правильно отформатировано или, чтобы нормализовать сообщение, отредактировав его на месте из сценария. From e36c02acad6d7fd7ab356f90842ad17ac1c3d9e8 Mon Sep 17 00:00:00 2001 From: Jean-Noel Avila Date: Sun, 27 Oct 2013 11:50:11 +0100 Subject: [PATCH 028/862] Change Maruku check to fully functional mode this is cleans up the code. --- Rakefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Rakefile b/Rakefile index 836f5044b..7d3039367 100644 --- a/Rakefile +++ b/Rakefile @@ -180,12 +180,8 @@ def test_lang(lang) "07-customizing-git" => 3, "08-git-and-other-scms" => 0, "09-git-internals" => 4} - mark = '' source_files = FileList.new(File.join(lang, '0*', '*.markdown')).sort source_files.each do |mk_filename| - mk_file = File.open(mk_filename, 'r') do |mk| - mark+= mk.read.encode("UTF-8") - end src_file = File.open(mk_filename, 'r') figure_count = 0 until src_file.eof? @@ -211,6 +207,8 @@ def test_lang(lang) end end begin + mark = (source_files.map{|mk_filename| File.open(mk_filename, 'r'){ + |mk| mk.read.encode("UTF-8")}}).join('') require 'maruku' code = Maruku.new(mark, :on_error => :raise, :error_stream => StderrDecorator.new) rescue From cc1d0d6ace74ea67222d5684997e2d6932c2748a Mon Sep 17 00:00:00 2001 From: Jean-Noel Avila Date: Wed, 30 Oct 2013 22:44:32 +0100 Subject: [PATCH 029/862] Force output of Rake messages to stderr --- Rakefile | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/Rakefile b/Rakefile index 7d3039367..8e8f9eac3 100644 --- a/Rakefile +++ b/Rakefile @@ -160,15 +160,19 @@ namespace :pdf do end class StderrDecorator + def initialize(out) + @out = out + end + def <<(x) - $stderr<< "#{x}" + @out << "#{x}" if x.match /REXML/ raise "" end end end -def test_lang(lang) +def test_lang(lang, out) error_code = false chapter_figure = { "01-introduction" => 7, @@ -189,7 +193,7 @@ def test_lang(lang) matches = line.match /^#/ if matches if line.match /^(#+).*#[[:blank:]]+$/ - print "\nBadly formatted title in #{mk_filename}: #{line}\n" + out<< "\nBadly formatted title in #{mk_filename}: #{line}\n" error_code = true end end @@ -202,7 +206,7 @@ def test_lang(lang) tab_fig_count = chapter_figure[File.basename(File.dirname(mk_filename))] expected_figure_count = tab_fig_count ? tab_fig_count:0 if figure_count > expected_figure_count - print "\nToo many figures declared in #{mk_filename}\n" + out << "\nToo many figures declared in #{mk_filename}\n" error_code = true end end @@ -210,7 +214,7 @@ def test_lang(lang) mark = (source_files.map{|mk_filename| File.open(mk_filename, 'r'){ |mk| mk.read.encode("UTF-8")}}).join('') require 'maruku' - code = Maruku.new(mark, :on_error => :raise, :error_stream => StderrDecorator.new) + code = Maruku.new(mark, :on_error => :raise, :error_stream => StderrDecorator.new(out)) rescue print $! error_code = true @@ -218,22 +222,29 @@ def test_lang(lang) error_code end +$out = $stdout + namespace :ci do desc "Parallel Continuous integration" task :parallel_check do require 'parallel' langs = FileList.new('??')+FileList.new('??-??') results = Parallel.map(langs) do |lang| - Rake::Task["ci:" +lang+"_check"].execute - 0 + error_code = test_lang(lang, $out) + if error_code + print "processing #{lang} KO\n" + else + print "processing #{lang} OK\n" + end + error_code end - fail "At least one language conversion failed" if results.any? { |result| result!=0} + fail "At least one language conversion failed" if results.any? end (FileList.new('??')+FileList.new('??-??')).each do |lang| desc "testing " + lang task (lang+"_check").to_sym do - error_code = test_lang(lang) + error_code = test_lang(lang, $out) fail "processing #{lang} KO\n" if error_code print "processing #{lang} OK\n" end @@ -253,19 +264,17 @@ namespace :ci do end langs -= excluded_langs end - global_error_code = false - langs.each do |lang| + errors = langs.each do |lang| print "processing #{lang} " - error_code=test_lang(lang) + error_code=test_lang(lang, $out) if error_code print "KO\n" else print "OK\n" end - global_error_code|=error_code - + error_code end - fail "At least one language conversion failed" if global_error_code + fail "At least one language conversion failed" if errors.any? end end From ea87c9c8b8faf6c22cea63ea69387dcd9caebe09 Mon Sep 17 00:00:00 2001 From: Masaki Kawabata Neto Date: Fri, 1 Nov 2013 07:41:36 -0200 Subject: [PATCH 030/862] fix duplicated typo "...fez o rebase do seu do seu trabalho..." --- pt-br/03-git-branching/01-chapter3.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pt-br/03-git-branching/01-chapter3.markdown b/pt-br/03-git-branching/01-chapter3.markdown index d6461a501..ee35c017d 100644 --- a/pt-br/03-git-branching/01-chapter3.markdown +++ b/pt-br/03-git-branching/01-chapter3.markdown @@ -577,7 +577,7 @@ Agora, outra pessoa faz modificações que inclui um merge, e envia (push) esse Insert 18333fig0337.png Figura 3-37. Obtêm mais commits e faz o merge deles no seu trabalho. -Em seguida, a pessoa que envio o merge voltou atrás e fez o rebase do seu do seu trabalho; eles executam `git push --force` para sobrescrever o histórico no servidor. Você então obtém os dados do servidor, trazendo os novos commits. +Em seguida, a pessoa que envio o merge voltou atrás e fez o rebase do seu trabalho; eles executam `git push --force` para sobrescrever o histórico no servidor. Você então obtém os dados do servidor, trazendo os novos commits. Insert 18333fig0338.png Figura 3-38. Alguém envia commits com rebase, abandonando os commits que você usou como base para o seu trabalho. From 0229cd603d15787492237f232dc663f98e265c16 Mon Sep 17 00:00:00 2001 From: cattail Date: Thu, 7 Nov 2013 16:54:21 +0800 Subject: [PATCH 031/862] [zh] fix branch name half translate to chinese --- zh/06-git-tools/01-chapter6.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh/06-git-tools/01-chapter6.markdown b/zh/06-git-tools/01-chapter6.markdown index b360ae563..61e777dc6 100644 --- a/zh/06-git-tools/01-chapter6.markdown +++ b/zh/06-git-tools/01-chapter6.markdown @@ -1107,7 +1107,7 @@ Git 通过子模块处理这个问题。子模块允许你将一个 Git 仓库 $ ls README -要将 Rack 项目当作子目录拉取到你的`master`项目中。你可以在 Git 中用`git read-tree`来实现。你会在第9章学到更多与`read-tree`和它的朋友相关的东西,当前你会知道它读取一个分支的根目录树到当前的暂存区和工作目录。你只要切换回你的`master`分支,然后拉取`rack`分支到你主项目的`master`分支的`rack`子目录: +要将 Rack 项目当作子目录拉取到你的`master`项目中。你可以在 Git 中用`git read-tree`来实现。你会在第9章学到更多与`read-tree`和它的朋友相关的东西,当前你会知道它读取一个分支的根目录树到当前的暂存区和工作目录。你只要切换回你的`master`分支,然后拉取`rack_branch`到你主项目的`master`分支的`rack`子目录: $ git read-tree --prefix=rack/ -u rack_branch From 5f3f7797cb277e6ea28e2444f25a1945cfc4082a Mon Sep 17 00:00:00 2001 From: Seonghwan Lee Date: Wed, 31 Jul 2013 11:26:45 +0900 Subject: [PATCH 032/862] [ko] translation update [ko] translation update ch1 to ch4 [ko] translation update ch5 [ko] translation update ch6 [ko] translation update ch7 [ko] translation update ch8 [ko] translation update ch9 [ko] proofreading. [ko] fix mistyping. --- ko/01-introduction/01-chapter1.markdown | 6 +- ko/02-git-basics/01-chapter2.markdown | 58 ++++++++-- ko/03-git-branching/01-chapter3.markdown | 4 +- ko/04-git-server/01-chapter4.markdown | 103 ++++++------------ ko/05-distributed-git/01-chapter5.markdown | 32 +++--- ko/06-git-tools/01-chapter6.markdown | 28 ++--- ko/07-customizing-git/01-chapter7.markdown | 52 ++++----- ko/08-git-and-other-scms/01-chapter8.markdown | 30 +++-- ko/09-git-internals/01-chapter9.markdown | 16 +-- 9 files changed, 169 insertions(+), 160 deletions(-) diff --git a/ko/01-introduction/01-chapter1.markdown b/ko/01-introduction/01-chapter1.markdown index 291402bd8..0cbacd34b 100644 --- a/ko/01-introduction/01-chapter1.markdown +++ b/ko/01-introduction/01-chapter1.markdown @@ -101,7 +101,7 @@ Git을 사용하면 프로젝트가 심각하게 망가질 걱정 없이 매우 이 세 가지 상태는 Git 프로젝트의 세 가지 단계와 연결돼 있다. Git 디렉토리, 워킹 디렉토리, Staging Area 이렇게 세 가지 단계를 이해하고 넘어가자. -Insert 18333fig0106.png +Insert 18333fig0106.png 그림 1-6 워킹 디렉토리, Staging Area, Git 디렉토리 Git 디렉토리는 Git이 프로젝트의 메타데이터와 객체 데이터베이스를 저장하는 곳을 말한다. Git 디렉토리가 Git의 핵심이다. 다른 컴퓨터에 있는 저장소를 Clone 할 때 Git 디렉토리가 만들어진다. @@ -182,6 +182,8 @@ MacPorts(`http://www.macports.org`)를 사용하는 방법도 있다. MacPorts 설치가 완료되면 CLI 프로그램과 GUI 프로그램을 둘 다 사용할 수 있다. CLI 프로그램에는 SSH 클라이언트가 포함돼 있기 때문에 유용하다. +Windows 사용자 필독:이 책에서 소개하는 다양한 명령어를 사용하려면 유닉스 스타일의 msysGit 쉘을 사용하는 것이 좋다. 어쩔 수 없이 Windows에 포함된 기본 쉘(Command Prompt, 명령 프롬프트)을 꼭 써야 하면 공백이 포함된 파라미터를 Git 명령어에 넘길 때 작은 따옴표(' ') 대신 큰 따옴표(" ")를 사용해야 한다. 파라미터 끝에 `^` 기호가 있을 때도 큰 따옴표로 파라미터를 감싸야 한다. Windows 쉘에서 `^` 기호는 다음 줄로 명령어가 이어짐을 나타낸다. + ## Git 최초 설정 ## Git을 설치하고 나면 Git의 사용 환경을 적절하게 설정해 주어야 한다. 한 번만 설정하면 된다. 설정한 내용은 Git을 업그레이드해도 유지된다. 언제든지 다시 바꿀 수 있는 명령어가 있다. @@ -192,7 +194,7 @@ Git을 설치하고 나면 Git의 사용 환경을 적절하게 설정해 주어 * `~/.gitconfig` 파일: 특정 사용자에게만 적용되는 설정이다. `git config --global` 옵션으로 이 파일을 읽고 쓸 수 있다. * `.git/config`: 이 파일은 Git 디렉토리에 있고 특정 저장소(혹은 현재 작업 중인 프로젝트)에만 적용된다. 각 설정은 역순으로 우선시 된다. 그래서 `.git/config`가 `/etc/gitconfig`보다 우선한다. -윈도용 Git은 `$HOME` 디렉토리(`C:\Documents and Settings\$USER`)에 있는 `.gitconfig` 파일을 찾는다. msysGit에도 /etc/gitconfig 파일이 있다. 경로는 MSys 루트에 따른 상대 경로다. 인스톨러로 msysGit을 설치할 때 설치 경로를 선택할 수 있다. +윈도용 Git은 `$HOME` 디렉토리(`%USERPROFILE%` 환경변수)에 있는 `.gitconfig` 파일을 찾는다. 보통 `C:\Documents and Settings\$USER` 또는 `C:\Users\$USER` 이다(윈도우에서는 `$USER` 대신 `%USERNAME%`를 사용한다). 그리고 msysGit도 /etc/gitconfig를 가지고 있다. 경로는 MSys 루트에 따른 상대 경로다. 인스톨러로 msysGit을 설치할 때 설치 경로를 선택할 수 있다. ### 사용자 정보 ### diff --git a/ko/02-git-basics/01-chapter2.markdown b/ko/02-git-basics/01-chapter2.markdown index 3a7d51cc1..123b17df7 100644 --- a/ko/02-git-basics/01-chapter2.markdown +++ b/ko/02-git-basics/01-chapter2.markdown @@ -57,7 +57,7 @@ Insert 18333fig0201.png # On branch master nothing to commit (working directory clean) -위의 내용은 파일을 하나도 수정하지 않았다는 것을 말해준다. 즉, Tracked와 Modified 상태의 파일이 없다. Untracked 파일은 아직 없어서 목록에 나타나지 않는다. 그리고 현재 작업 중인 브랜치를 알려준다. 기본 브랜치가 master이기 때문에 현재 master로 나오는 것이다. 브랜치 관련 내용은 차차 알아가자. 다음 장에서 브랜치와 레퍼런스에 대해 자세히 다룬다. +위의 내용은 파일을 하나도 수정하지 않았다는 것을 말해준다. Tracked나 Modified 상태인 파일이 없다는 의미다. Untracked 파일은 아직 없어서 목록에 나타나지 않는다. 그리고 현재 작업 중인 브랜치를 알려준다. 기본 브랜치가 master이기 때문에 현재 master로 나오는 것이다. 브랜치 관련 내용은 차차 알아가자. 다음 장에서 브랜치와 레퍼런스에 대해 자세히 다룬다. 프로젝트에 `README` 파일을 만들어보자. `README` 파일은 새로 만든 파일이기 때문에 `git status`를 실행하면 'Untracked files'에 들어 있다: @@ -180,6 +180,10 @@ Glob 패턴은 정규표현식을 단순하게 만든 것으로 생각하면 되 build/ # `doc/notes.txt`같은 파일은 무시하고 doc/server/arch.txt같은 파일은 무시하지 않는다. doc/*.txt + # `doc` 디렉토리 아래의 모든 .txt 파일을 무시한다. + doc/**/*.txt + +`**/` 스타일의 문법은 Git 1.8.2 버전부터 사용할 수 있다. ### Staged와 Unstaged 상태의 변경 내용을 보기 ### @@ -289,7 +293,6 @@ Staged 상태인 파일은 `git diff --cached` 옵션으로 확인한다: ### 변경사항 커밋하기 ### 수정한 것을 커밋하기 위해 Staging Area에 파일을 정리했다. Unstaged 상태의 파일은 커밋되지 않는다는 것을 기억해야 한다. Git은 생성하거나 수정하고 나서 `git add` 명령으로 추가하지 않은 파일은 커밋하지 않는다. 그 파일은 여전히 Modified 상태로 남아 있다. - 커밋하기 전에 `git status` 명령으로 모든 것이 Staged 상태인지 확인할 수 있다. 그리고 `git commit`을 실행하여 커밋한다: $ git commit @@ -380,7 +383,7 @@ Git에서 파일을 제거하려면 `git rm` 명령으로 Tracked 상태의 파 $ git rm log/\*.log -`*`앞에 `\`을 사용한 것을 기억하자. 파일명 확장 기능은 쉘에만 있는 것이 아니라 Git 자체에도 있기 때문에 필요하다. 이 명령은 `log/` 디렉토리에 있는 `.log` 파일을 모두 삭제한다. 아래의 예제처럼 할 수도 있다: +`*`앞에 `\`을 사용한 것을 기억하자. 파일명 확장 기능은 쉘에만 있는 것이 아니라 Git 자체에도 있기 때문에 필요하다. Windows 기본 쉘을 쓸 때는 `\` 기호를 붙이지 않는다. 이 명령은 `log/` 디렉토리에 있는 `.log` 파일을 모두 삭제한다. 아래의 예제처럼 할 수도 있다: $ git rm \*~ @@ -461,11 +464,13 @@ Git은 다른 VCS 시스템과는 달리 파일 이름의 변경이나 파일의 index a874b73..8f94139 100644 --- a/Rakefile +++ b/Rakefile - @@ -5,7 +5,7 @@ require 'rake/gempackagetask' + @@ -5,7 +5,5 @@ require 'rake/gempackagetask' spec = Gem::Specification.new do |s| + s.name = "simplegit" - s.version = "0.1.0" + s.version = "0.1.1" s.author = "Scott Chacon" + s.email = "schacon@gee-mail.com" commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 Author: Scott Chacon @@ -488,7 +493,27 @@ Git은 다른 VCS 시스템과는 달리 파일 이름의 변경이나 파일의 -end \ No newline at end of file -이 옵션은 직접 diff를 실행한 것과 같은 결과를 출력하기 때문에 동료가 무엇을 커밋했는지 리뷰하고 빨리 조회하는데 유용하다. +이 옵션은 직접 diff를 실행한 것과 같은 결과를 출력하기 때문에 동료가 무엇을 커밋했는지 리뷰하고 빨리 조회하는데 유용하다. + +가끔은 diff 결과를 줄 단위로 보기보다는 단어 단위로 보는 것이 좋을 때도 있다. `git log -p`와 같은 명령에 `--word-diff` 옵션을 사용하면 줄 단위 대신 단어 단위로 변경사항을 보여준다. 단어 단위로 다른 부분을 확인하는 것은 소스코드에는 별로 유용하지 않다. 책이나 에세이 같이 문장이 긴 글을 쓸 때는 단어 단위로 보는 것이 편하다. `--word-diff` 옵션은 다음과 같이 사용한다: + + $ git log -U1 --word-diff + commit ca82a6dff817ec66f44342007202690a93763949 + Author: Scott Chacon + Date: Mon Mar 17 21:52:11 2008 -0700 + + changed the version number + + diff --git a/Rakefile b/Rakefile + index a874b73..8f94139 100644 + --- a/Rakefile + +++ b/Rakefile + @@ -7,3 +7,3 @@ spec = Gem::Specification.new do |s| + s.name = "simplegit" + s.version = [-"0.1.0"-]{+"0.1.1"+} + s.author = "Scott Chacon" + +위의 예제는 줄 단위로 보여주는 일반적인 diff와 좀 다르다. 줄 안에서 변경한 부분을 단어 단위로 표시한다. 추가한 단어는 `{+ +}` 기호가 둘러싸고 삭제한 단어는 `[- -]` 기호가 둘러싼다. diff는 기본적으로 다른 줄과 위아래 줄을 포함해서 3줄을 보여준다. 줄 단위가 아니라 단어 단위로 비교해서 볼 때는 굳이 3줄을 다 볼 필요가 없다. 예제에서 처럼 `-U1` 옵션을 주면 해당 줄만 보여준다. 또 `git log` 명령에는 히스토리의 통계를 보여주는 옵션도 있다. `--stat` 옵션으로 각 커밋의 통계 정보를 조회할 수 있다: @@ -538,7 +563,12 @@ Git은 다른 VCS 시스템과는 달리 파일 이름의 변경이나 파일의 085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code a11bef0 - Scott Chacon, 11 months ago : first commit -표 2-1 포맷에서 사용하는 유용한 옵션들. + + +표 2-1 형식에서 사용하는 유용한 옵션들. Option Description of Output %H Commit hash @@ -575,8 +605,14 @@ _저자(Author)_ 와 _커미터(Committer)_ 를 구분하는 것이 조금 이 `git log` 명령의 기본적인 옵션과 출력물의 형식에 관련된 옵션을 살펴보았다. `git log` 명령은 앞서 살펴본 것보다 더 많은 옵션을 지원한다. 표 2-2 는 지금 설명한 것과 함께 유용하게 사용할 수 있는 옵션이다. 각 옵션으로 어떻게 `log` 명령을 제어할 수 있는지 보여준다. + + 옵션 설명 -p 각 커밋에 적용된 패치를 보여준다. + --word-diff diff 결과를 단어 단위로 보여준다. --stat 각 커밋에서 수정된 파일의 통계정보를 보여준다. --shortstat `--stat` 명령의 결과 중에서 수정한 파일, 추가된 줄, 삭제된 줄만 보여준다. --name-only 커밋 정보중에서 수정된 파일의 목록만 보여준다. @@ -585,6 +621,7 @@ _저자(Author)_ 와 _커미터(Committer)_ 를 구분하는 것이 조금 이 --relative-date 정확한 시간을 보여주는 것이 아니라 `2 주전`처럼 상대적인 형식으로 보여준다. --graph 브랜치와 머지 히스토리 정보까지 아스키 그래프로 보여준다. --pretty 지정한 형식으로 보여준다. 이 옵션에는 oneline, short, full, fuller, format이 있다. format은 원하는 형식으로 출력하고자 할 때 사용한다. + --oneline `--pretty=oneline --abbrev-commit` 옵션을 함께 사용한 것과 동일하다. ### 조회 제한조건 ### @@ -602,6 +639,11 @@ _저자(Author)_ 와 _커미터(Committer)_ 를 구분하는 것이 조금 이 표 2-3은 조회 범위를 제한하는 옵션들이다. + + 옵션 설명 -(n) 최근 n 개의 커밋만 조회한다. --since, --after 명시한 날짜 이후의 커밋만 검색한다. @@ -761,7 +803,7 @@ Git으로 커밋한 모든 것은 언제나 복구할 수 있다. 삭제한 브 origin git://github.com/schacon/ticgit.git pb git://github.com/paulboone/ticgit.git -이제 URL 대신에 스트링 pb를 사용할 수 있다. 예를 들어 로컬 저장소에는 없지만 Paul의 저장소에 있는 것을 가져오려면 아래와 같이 실행한다: +이제 URL 대신에 스트링 `pb`를 사용할 수 있다. 예를 들어 로컬 저장소에는 없지만 Paul의 저장소에 있는 것을 가져오려면 아래과 같이 실행한다: $ git fetch pb remote: Counting objects: 58, done. @@ -1006,7 +1048,7 @@ Lightweight 태그는 기본적으로 파일에 커밋 체크섬을 저장하는 "updated rakefile" 커밋을 v1.2로 태그하지 못했다고 해도 차후에 태그를 붙일 수 있다. 특정 커밋에 태그하기 위해서 명령의 끝에 커밋 체크섬을 명시한다(긴 체크섬을 전부 사용할 필요는 없다): - $ git tag -a v1.2 9fceb02 + $ git tag -a v1.2 -m 'version 1.2' 9fceb02 이제 아래와 같이 만든 태그를 확인한다: diff --git a/ko/03-git-branching/01-chapter3.markdown b/ko/03-git-branching/01-chapter3.markdown index 0b47f5803..aede41a06 100644 --- a/ko/03-git-branching/01-chapter3.markdown +++ b/ko/03-git-branching/01-chapter3.markdown @@ -150,7 +150,7 @@ Insert 18333fig0312.png hotfix라는 브랜치를 만들고 새로운 이슈를 해결할 때까지 사용한다: - $ git checkout -b 'hotfix' + $ git checkout -b hotfix Switched to a new branch 'hotfix' $ vim index.html $ git commit -a -m 'fixed the broken email address' @@ -316,7 +316,7 @@ Merge 도구를 종료하면 Git은 잘 Merge했는지 물어본다. 잘 마쳤 * master 7a98805 Merge branch 'iss53' testing 782fd34 add scott to the author list in the readmes -각 브랜치가 지금 어떤 상태인지 확인하기에 좋은 옵션도 있다. 현재 Checkout한 브랜치를 기준으로 Merge된 브랜치인지 그렇지 않은지 필터링해 볼 수 있다. `--merged`와 `--no-merged` 옵션을 사용하여 해당 목록을 볼 수 있는데, Git 1.5.6 이후 버전부터 사용할 수 있다. `git branch --merged` 명령으로 이미 Merge한 브랜치 목록을 확인한다: +각 브랜치가 지금 어떤 상태인지 확인하기에 좋은 옵션도 있다. 현재 Checkout한 브랜치를 기준으로 Merge된 브랜치인지 그렇지 않은지 필터링해 볼 수 있다. `--merged`와 `--no-merged` 옵션을 사용하여 해당 목록을 볼 수 있다. `git branch --merged` 명령으로 이미 Merge한 브랜치 목록을 확인한다: $ git branch --merged iss53 diff --git a/ko/04-git-server/01-chapter4.markdown b/ko/04-git-server/01-chapter4.markdown index 51ef75bf2..253e5866c 100644 --- a/ko/04-git-server/01-chapter4.markdown +++ b/ko/04-git-server/01-chapter4.markdown @@ -241,6 +241,7 @@ something, something.pub이라는 형식으로 된 파일을 볼 수 있다. som 이제 이 프로젝트를 Clone하고 나서 수정하고 Push한다: $ git clone git@gitserver:/opt/git/project.git + $ cd project $ vim README $ git commit -am 'fix for the README file' $ git push origin master @@ -277,9 +278,7 @@ something, something.pub이라는 형식으로 된 파일을 볼 수 있다. som $ mv hooks/post-update.sample hooks/post-update $ chmod a+x hooks/post-update -만약 1.6보다 낮은 버전의 Git을 사용하고 있으면 `mv` 명령은 필요하지 않다. Git은 최근에서야 훅 예제에 `.sample` 확장자를 사용하기 시작했다. - -`post-update` 훅은 무슨 일을 할까? 기본적으로 아래와 같다: +`post-update` 훅은 무슨 일을 할까? 기본적으로 다음과 같다: $ cat .git/hooks/post-update #!/bin/sh @@ -500,91 +499,67 @@ Gitosis의 접근제어 방법은 매우 단순하다. 만약 이 프로젝트 ## Gitolite ## -주의사항: 이 절의 최신판은 항상 [gitolite documentation][gldpg]에서 확인하는 것이 좋다. 저자는 다른 참고 문서 없이 이 절만 읽고서도 Gitolite를 설치할 수 있도록 문서를 작성했다고 말했다. 이 절은 꼭 필요하지만 완벽하지 않고 Gitolite에 대한 방대한 문서를 대체할 수도 없다. +이 절에서는 Gitolite가 뭐고 기본적으로 어떻게 설치하는 지를 살펴본다. 물론 Gitolite에 들어 있는 [Gitolite 문서][gltoc]는 양이 많아서 이 절에서 모두 다룰 수 없다. Gitolite는 계속 진화하고 있기 때문에 이 책의 내용과 다를 수 있다. 최신 내용은 [여기][gldpg]에서 확인해야 한다. [gldpg]: http://sitaramc.github.com/gitolite/progit.html +[gltoc]: http://sitaramc.github.com/gitolite/master-toc.html -Git은 좀 더 꼼꼼한 접근 제어가 필요한 기업환경에서도 많이 쓰인다. 원래 이 요구 사항 덕분에 Gitolite가 만들어졌다. 그리고 오픈 소스 진영에서도 매우 유용하다는 것이 밝혀졌다. Fedora 프로젝트는 Gitolite를 사용하여 10,000개가 넘는 패키지 관리용 저장소의 권한을 제어한다. Fedora의 Gitolite가 아마도 가장 규모가 크다. +Gitolite은 간단히 말해 Git 위에서 운영하는 권한 제어(Authorization) 도구다. 사용자 인증(Authentication)은 `sshd`와 `httpd`를 사용한다. 접속한 접속하는 사용자가 누구인지 가려내는 것이 인증(Authentication)이고 리소스에 대한 접근 권한을 가려내는 일은 권한 제어(Authorization)이다. Gitolite는 저장소뿐만 아니라 저장소의 브랜치나 태그에도 권한을 명시할 수 있다. 즉, 어떤 사람은 refs(브랜치나 태그)에 Push할 수 있고 어떤 사람은 할 수 없게 하는 것이 가능하다. ### 설치하기 ### -별도 문서를 읽지 않아도 유닉스 계정만 하나 있으면 Gitolite를 쉽게 설치할 수 있다. 이 글은 여러 가지 리눅스들과 솔라리스 10에서 테스트를 마쳤다. git, perl, openssh가 호환되는 ssh 서버가 있으면 root 권한도 필요 없다. 앞서 사용했던 `gitserver`라는 서버에 `gitolite` 계정을 만들어 설치한다. - -Gitolite는 보통의 서버 소프트웨어와는 약간 다르다. ssh를 통해서 접근하지만, 서버의 모든 계정은 근본적으로 "Gitolite 호스트"가 될 수 있다. 그래서 설치하는 일은 소프트웨어 자체를 설치하는 일과 한 계정을 "Gitolite 호스트"로 설정하는 작업으로 나눌 수 있다. - -Gitolite를 설치하는 방법은 모두 네 가지이다. Fedora나 Debian을 사용하고 있으면 RPM이나 DEB 패키지를 구해서 설치하거나 수동으로 설치할 수 있다. 이 방법은 root 권한이 필요하다. 이 두 가지 모두 시스템의 모든 사용자를 각각 "Gitolite 호스트"로 만들 수 있다. - -서버의 Root 권한을 얻을 수 없는 사용자는 자신의 계정에 설치할 수 있다. 서버에서 Bash 스크립트를 실행하여 Gitolite를 설치할 수 있다. 심지어 Windows 환경에서 msysgit에 들어 있는 Bash로도 가능하다. - -이 글에서는 마지막 방법을 설명한다; 다른 방법은 다른 문서를 참고하도록 한다. +별도 문서를 읽지 않아도 유닉스 계정만 하나 있으면 Gitolite를 쉽게 설치할 수 있다. 이 글은 여러 가지 리눅스들과 솔라리스 10에서 테스트를 마쳤다. Git, Perl, OpenSSH가 호환되는 SSH 서버가 설치돼 있으면 root 권한도 필요 없다. 앞서 사용했던 `gitserver`라는 서버와 그 서버에 `git` 계정을 만들어 사용한다. -우선 공개키로 서버에 접근할 수 있어야 한다. 그래야 서버로 로그인할 때 암호를 묻지 않는다. `ssh-keygen`으로 만든 키가 이미 있으면 다음처럼 한다. 리눅스에서는 이 방법이 잘 될 테고 다른 OS라면 수동으로 이 작업을 해야 한다: +Gitolite는 보통의 서버 소프트웨어와는 달리 SSH를 통해서 접근한다. 서버의 모든 계정은 근본적으로 "Gitolite 호스트"가 될 수 있다. 이 책에서는 가장 간단한 설치 방법으로 설명한다. 자세한 설명 문서는 Gitolite의 문서를 참고한다. - $ ssh-copy-id -i ~/.ssh/id_rsa gitolite@gitserver - -이 명령은 Gitolite 계정의 암호를 묻고서 이 공개키로 접근할 수 있도록 설정할 것이다. 이것은 설치 스크립트를 실행하는 데 꼭 **필요하다**. 그러니까 명령어를 실행할 때 암호를 물어보는지 다시 한번 확인해봐야 한다: - - $ ssh gitolite@gitserver pwd - /home/gitolite - -그리고 프로젝트 사이트에서 Gitolite를 Clone하고 "easy install" 스크립트를 실행한다(세 번째 아규먼트는 gitolite-admin 저장소에서 사용할 사용자 이름이다): +먼저 서버에 `git` 계정을 만들고 `git` 계정으로 로그인 한다. 사용자의 SSH 공개키(`ssh-keygen`으로 생성한 SSH 공개키는 기본적으로 `~/.ssh/id_rsa.pub`에 위치함)를 복사하여 `<이름>.pub` 파일로 저장한다(이 책의 예제에서는 `scott.pub`로 저장). 그리고 다음과 같은 명령을 실행한다: $ git clone git://github.com/sitaramc/gitolite - $ cd gitolite/src - $ ./gl-easy-install -q gitolite gitserver sitaram - -이제 다 됐다. Gitolite를 서버에 설치했고 홈 디렉토리에 `gitolite-admin`이라는 저장소를 만들었다. 이 저장소를 수정하고 Push하는 방법으로 Gitolite 서버를 관리한다. + $ gitolite/install -ln + # $HOME/bin가 이미 $PATH에 등록돼있다고 가정 + $ gitolite setup -pk $HOME/scott.pub -마지막 명령에는 중요한 정보가 많이 들어 있다. 이 명령을 처음 실행하면 키쌍이(keypair) 새로 만들어진다. 암호가 필요하면 입력하고 필요 없으면 그냥 엔터를 친다. 왜 키를 하나 더 만드는지, 그것을 어떻게 사용하는지는 Gitolite의 "ssh troubleshooing" 문서를 참고하라(이 문서가 필요할 때가 있다). - -서버에는 기본적으로 `gitolite-admin`과 `testing` 저장소가 생성되고 필요하면 이 저장소를 아래와 같이 Clone한다(*authorized_keys* 파일에 공개키가 등록돼서 SSH 접근이 가능한 계정으로 Gitolite 계정에 접근하는 것임): - - $ git clone gitolite:gitolite-admin - $ git clone gitolite:testing - -다른 계정으로도 이 저장소를 Clone할 수 있다: - - $ git clone gitolite@servername:gitolite-admin - $ git clone gitolite@servername:testing +마지막 명령은 `gitolite-admin`라는 새 Git 저장소를 서버에 만든다. +다시 작업하던 환경으로 돌아가서 `git clone git@gitserver:gitolite-admin` 명령으로 서버의 저장소를 Clone 했을 떄 문제없이 Clone 되면 Gitolite가 정상적으로 설치된 것이다. 이 `gitolite-admin` 저장소의 내용을 수정하고 Push하여 Gitolite을 설치를 마치도록 한다. ### 자신에게 맞게 설치하기 ### -보통은 기본설정만으로 빠르게 설치하는 것으로 충분하지만, 자신에게 맞게 고쳐서 설치할 수 있다. `-q` 아규먼트를 주면 설치 단계마다 상세한 정보를 보여주는 verbose 모드로 설치한다. 이 모드로 실행하면 저장소의 경로 같은 것들을 바꿔서 설치할 수 있고 결국엔 서버가 사용하는 rc 파일이 수정된다. rc 파일은 주석이 정말 잘 달렸기 때문에 필요한 것이 있으면 언제든지 쉽게 수정할 수 있다. 이 파일에서 Gitolite의 고급 기능들을 켜고 끄는 등 다양한 설정을 한다. +보통은 기본설정으로 빠르게 설치하는 것으로 충분하지만, 자신에게 맞게 고쳐서 설치할 수 있다. 일부 설정은 주석이 잘 달려있는 rc 파일을 간단히 고쳐서 쓸 수 있지만, 자세한 설정을 위해서는 Gitolite가 제공하는 문서를 살펴보도록 한다. ### 설정 파일과 접근제어 규칙 ### -설치가 완료되면 홈 디렉토리에 있는 `gitolite-admin` 저장소로 이동해서 저장소에 어떤 것이 있는지 한번 살펴보자: +설치가 완료되면 홈 디렉토리에 Clone한 `gitolite-admin` 디렉토리로 이동해서 어떤 것들이 있는지 한번 살펴보자: $ cd ~/gitolite-admin/ $ ls conf/ keydir/ $ find conf keydir -type f conf/gitolite.conf - keydir/sitaram.pub + keydir/scott.pub $ cat conf/gitolite.conf - #gitolite conf - # please see conf/example.conf for details on syntax and features repo gitolite-admin - RW+ = sitaram + RW+ = scott repo testing RW+ = @all -`gl-easy-install` 명령을 실행했을 때 줬던 마지막 아규먼트가 기억나는가? 그때 사용했던 sitaram은 `gitolite-admin` 저장소에 대한 읽기, 쓰기 권한을 모두 가지고 있고 공개키도 이미 등록돼 있다. +`gitolite setup` 명령을 실행했을 때 주었던 공개키 파일의 이름인 `scott`은 `gitolite-admin` 저장소에 대한 읽기와 쓰기 권한을 갖도록 공개키가 등록돼 있다. + +사용자를 새로 추가하기도 쉽다. "alice"라는 사용자를 새로 등록하려면 우선 등록할 사람의 공개키 파일을 얻어서 `alice.pub`라는 이름으로 `gitolite-admin` 디렉토리 아래에 `keydir` 디렉토리에 저장한다. 새로 추가한 이 파일을 Add하고 커밋한 후 Push를 하면 `alice`라는 사용자가 등록된 것이다. -Gitolite의 설정 파일은 `conf/example.conf` 파일 안에 상세히 설명돼 있다. 여기에서는 중요 부분에 대해서만 다룬다. +Gitolite의 설정 파일인 `conf/example.conf`에 대한 내용은 Gitolite 문서에 설명이 잘 되어 있다. 이 책에서는 주요 일부 설정에 대해서만 간단히 살펴본다. -사용자 그룹과 저장소 그룹을 만들 수 있다. 이 그룹은 매크로와 비슷하다. 그룹을 만들 때는 그 그룹이 프로젝트의 그룹인지 사용자의 그룹인지 구분하지 않지만 사용할 때에는 구분해야 한다. +저장소의 사용자 그룹을 쉽게 만들 수 있다. 이 그룹은 매크로와 비슷하다. 그룹을 만들 때는 그 그룹이 프로젝트의 그룹인지 사용자의 그룹인지 구분하지 않지만 *사용*할 때에는 다르다. @oss_repos = linux perl rakudo git gitolite @secret_repos = fenestra pear - @admins = scott # Adams, not Chacon, sorry :) - @interns = ashok # get the spelling right, Scott! + @admins = scott + @interns = ashok @engineers = sitaram dilbert wally alice @staff = @admins @engineers @interns @@ -630,13 +605,11 @@ Gitolite는 접근 제어를 두 단계로 한다. 첫 단계가 저장소 단 브랜치 단위로 Push를 제어할 수 있지만 수정된 파일 단위로도 제어할 수 있다. 예를 들어 Makefile을 보자. Makefile 파일에 의존하는 파일은 매우 많고 보통 *꼼꼼하게* 수정하지 않으면 문제가 생긴다. 그래서 아무나 Makefile을 수정하게 둘 수 없다. 그러면 아래와 같이 설정한다: repo foo - RW = @junior_devs @senior_devs + RW = @junior_devs @senior_devs - RW NAME/ = @senior_devs - - NAME/Makefile = @junior_devs - RW NAME/ = @junior_devs + - VREF/NAME/Makefile = @junior_devs -이 내용은 `conf/example.conf`에도 자세히 설명돼 있다. +예전 버전의 Gitolite에서 버전을 올리려는 사용자는 설정이 많이 달라진 것을 알게 될 것이다. Gitolite의 버전업 가이드를 필히 참고하자. ### Personal 브랜치 ### @@ -646,26 +619,22 @@ Git을 사용하다 보면 코드를 공유하려고 "Pull 해주세요"라고 중앙집중식 VCS에서 이렇게 마구 사용하면 브랜치 이름이 충돌할 확률이 높다. 그때마다 관리자는 추가로 권한을 관리해줘야 하기 때문에 관리자의 노력이 쓸데없이 낭비된다. -Gitolite는 모든 개발자가 "personal"이나 "scratch" 네임스페이스를 가질 수 있도록 허용한다. 이 네임스페이스는 `refs/personal//*` 라고 표현한다. 자세한 것은 `doc/3-faq-tips-etc.mkd`의 "Personal 브랜치" 절을 참고한다. +Gitolite는 모든 개발자가 "personal"이나 "scratch" 네임스페이스를 가질 수 있도록 허용한다. 이 네임스페이스는 `refs/personal//*` 라고 표현한다. 자세한 내용은 Gitolite 문서를 참고한다. ### "와일드카드" 저장소 ### -Gitolite는 펄 정규표현식으로 저장소 이름을 표현하기 때문에 와일드카드를 사용할 수 있다. 그래서 `assignments/s[0-9][0-9]/a[0-9][0-9]` 같은 정규표현식도 사용 가능하다. - -rc 파일에 `$GL_WILDREPOS = 1`로 설정하면 이 기능을 사용할 수 있다. 게다가 새로운 권한 모드인 "C"를 사용할 수 있게 된다. 이것은 저장소를 만들 수 있는 권한을 부여하는 것이다. 와일드카드 정규표현식에 만족하는 저장소를 만들 수 있다. 사용자가 저장소를 만들면 자동으로 사용자를 소유자로 만든다. 이 소유자는 R과 RW 권한이 필요한 사람들에게 권한을 부여할 수 있다. 이 기능은 `doc/4-wildcard-repositories.mkd`에 자세히 설명돼 있다. +Gitolite는 펄 정규표현식으로 저장소 이름을 표현하기 때문에 와일드카드를 사용할 수 있다. 그래서 `assignments/s[0-9][0-9]/a[0-9][0-9]` 같은 정규표현식을 사용할 수 있다. 사용자가 새로운 저장소를 만들 수 있는 새로운 권한 모드인 `C` 모드를 사용할 수도 있다. 저장소를 새로 만든 사람에게는 자동으로 접근 권한이 부여된다. 다른 사용자에게 접근 권한을 주려면 `R` 또는 `RW` 권한을 설정한다. 다시 한번 말하지만 문서에 모든 내용이 다 있으므로 꼭 보기를 바란다. ### 그 밖의 기능들 ### 마지막으로 알고 있으면 유용한 것들이 있다. Gitolite에는 많은 기능이 있고 자세한 내용은 "Faq, Tip, 등등"의 다른 문서에 잘 설명돼 있다. -**로깅**: 누군가 접근하면 Gitolite는 무조건 로그를 남긴다. 관리자가 한눈파는 사이에 되돌리기(`RW+`) 권한을 가진 망나니가 "master" 브랜치를 날려버릴 수 있다. 이럴때는 로그 파일이 구원해준다. 이 로그 파일을 참고하여 버려진 SHA를 빠르고 쉽게 찾을 수 있다. - -**Git이 설치된 경로에 자유롭다**: 이것은 정말 편리하고 유용한 기능이다. Gitolite는 Git을 `$PATH` 안에 찾을 수 있도록 설치하지 않아도 된다. 생각하는 것보다 자주 이 특징이 필요하다. 회사나 호스팅 업체는 시스템 전체에 영향이 끼쳐지도록 설치하지 못하게 한다. 그래서 결국엔 해당 계정 디렉토리에 설치해야 한다. 그리고 *클라이언트 쪽*에서 어떤 이유로든 표준 위치에 git을 설치하지 못할 수 있다. Gitolite를 verbose 모드로 설치하면 "rc" 파일의 "$GIT_PATH"를 수정할 수 있다. 그 외 클라이언트에서 해야 할 일은 전혀 없다. +**로깅**: 누군가 성공적으로 접근하면 Gitolite는 무조건 로그를 남긴다. 관리자가 한눈파는 사이에 되돌리기(`RW+`) 권한을 가진 망나니가 `master` 브랜치를 날려버릴 수 있다. 이 경우 로그 파일이 구원해준다. 이 로그 파일을 참고하여 버려진 SHA를 빠르고 쉽게 찾을 수 있다. **접근 권한 보여주기**: 만약 어떤 서버에서 작업을 시작하려고 할 때 필요한 것이 무엇일까? Gitolite는 해당 서버에 대해 접근할 수 있는 저장소가 무엇인지, 어떤 권한을 가졌는지 보여준다: - hello sitaram, the gitolite version here is v1.5.4-19-ga3397d4 - the gitolite config gives you the following access: + hello scott, this is git@git running gitolite3 v3.01-18-g9609868 on git 1.7.4.4 + R anu-wsd R entrans R W git-notes @@ -676,9 +645,7 @@ rc 파일에 `$GL_WILDREPOS = 1`로 설정하면 이 기능을 사용할 수 있 **권한 위임**: 조직 규모가 크면 저장소에 대한 책임을 여러 사람이 나눠 가지는 게 좋다. 여러 사람이 각자 맡은 바를 관리하도록 한다. 그래서 주요 관리자의 업무가 줄어들기에 병목현상이 적어진다. 이 기능에 대해서는 `doc/` 디렉토리에 포함된 Gitolite 문서를 참고하라. -**Gitweb 지원**: Gitolite에는 GitWeb을 지원하는 방법이 몇 가지 있다. Gitweb을 사용할 저장소가 무엇인지 명시할 수 있다. 그리고 Gitolite 설정 파일에서 "owner"와 "description" 항목을 Gitweb으로 가져올 수 있다. Gitolite 설정 파일을 HTTP 인증 설정 파일로 컴파일할 수 있고 Gitweb은 이 HTTP 인증 파일을 사용해서 접근을 제어한다. 그래서 Gitweb과 Gitolite은 같은 접근 규칙을 사용하게 된다. - -**미러링**: Gitolite의 미러는 여러 개 만들 수 있어서 주 서버가 다운되면 변경해 사용할 수 있다. +**미러링**: Gitolite의 미러는 여러 개 만들 수 있어서 주 서버가 다운 돼도 변경하면 된다. ## Git 데몬 ## @@ -715,7 +682,7 @@ rc 파일에 `$GL_WILDREPOS = 1`로 설정하면 이 기능을 사용할 수 있 다른 시스템에서는 `sysvinit` 시스템의 `xinetd` 스크립트를 사용하거나 자신만의 방법으로 해야 한다. -아무나 읽을 수 있는 Git 데몬이 있다는 것을 Gitosis 서버에 알려주어야 한다. Git 데몬으로 읽기 접근을 허용하는 저장소가 무엇인지 설정에 추가해야 한다. 만약 iphone 프로젝트에 Git 프로토콜을 허용했다면 아래와 같은 것을 `gitosis.conf` 파일의 하단에 추가한다: +Git 데몬을 통해서 아무나 읽을 수 있다는 것을 Gitosis 서버에 알려주어야 한다. Git 데몬으로 읽기 접근을 허용하는 저장소가 무엇인지 설정에 추가해야 한다. 만약 `iphone_project`에 Git 프로토콜을 허용했다면 아래와 같은 것을 `gitosis.conf` 파일의 하단에 추가한다: [repo iphone_project] daemon = yes @@ -742,7 +709,7 @@ Gitosis 설정 파일에 `gitweb` 설정을 넣거나 빼면 사용자는 GitWeb daemon = yes gitweb = yes -이제 이것을 커밋하고 Push하면 GitWeb을 통해 iphone 프로젝트를 볼 수 있다. +이제 이것을 커밋하고 Push하면 GitWeb을 통해 `iphone_project`를 볼 수 있다. ## Hosted Git ## diff --git a/ko/05-distributed-git/01-chapter5.markdown b/ko/05-distributed-git/01-chapter5.markdown index 17c30d765..79a6dff8b 100644 --- a/ko/05-distributed-git/01-chapter5.markdown +++ b/ko/05-distributed-git/01-chapter5.markdown @@ -23,12 +23,12 @@ Insert 18333fig0501.png Git을 사용하면 리모트 저장소를 여러 개 운영할 수 있다. 다른 개발자는 읽기만 가능하고 자신은 쓰기도 가능한 공개 저장소를 만드는 Workflow도 가능하다. 이 Worlflow에는 보통 프로젝트를 대표하는 하나의 공식 저장소가 있다. 기여자는 우선 공식 저장소를 하나 Clone하고 수정하고 나서 자신의 저장소에 Push한다. 그다음에 프로젝트 Integration-Manager에게 새 저장소에서 Pull하라고 요청한다. 그러면 그 Integration-Manager는 기여자의 저장소를 리모트 저장소로 등록하고, 로컬에서 기여물을 테스트하고, 프로젝트 메인 브랜치에 Merge하고, 그 내용을 다시 프로젝트 메인 저장소에 Push한다. 이런 과정은 아래와 같다(그림 5-2). -1. 프로젝트 Integration-Manager는 프로젝트 메인 저장소에 Push를 한다. -2. 프로젝트 기여자는 메인 저장소를 Clone하고 수정한다. -3. 기여자는 자신의 저장소에 Push하고 Integration-Manager가 접근할 수 있도록 공개해 놓는다. -4. 기여자는 Integration-Manager에게 E-mail 같은 것으로 변경사항을 적용해 달라고 요청한다. -5. Integration-Manager는 기여자의 저장소를 리모트 저장소로 등록하고 수정사항을 Merge하여 테스트한다. -6. Integration-Manager는 Merge한 사항을 메인 저장소에 Push한다. +1. 프로젝트 Integration-Manager는 프로젝트 메인 저장소에 Push를 한다. +2. 프로젝트 기여자는 메인 저장소를 Clone하고 수정한다. +3. 기여자는 자신의 저장소에 Push하고 Integration-Manager가 접근할 수 있도록 공개해 놓는다. +4. 기여자는 Integration-Manager에게 변경사항을 적용해 줄 것을 E-mail 같은 것으로 요청한다. +5. Integration-Manager는 기여자의 저장소를 리모트 저장소로 등록하고 수정사항을 Merge하여 테스트한다. +6. Integration-Manager는 Merge한 사항을 메인 저장소에 Push한다. Insert 18333fig0502.png 그림 5-2 Integration-Manager Workflow @@ -39,10 +39,10 @@ Insert 18333fig0502.png 이 방식은 저장소를 여러개 운영하는 방식을 변형한 구조이다. 보통 수백 명의 개발자가 참여하는 아주 큰 프로젝트를 운영할 때 이 방식을 사용한다. 리눅스 커널 프로젝트가 대표적이다. 여러 명의 Integration-Manager가 저장소에서 자신이 맡은 부분만을 담당하는데 이들을 Lieutenants라고 부른다. 모든 Lieutenant는 최종 관리자 아래에 있으며 이 최종 관리자를 Dictator라고 부른다(그림 5-3). -1. 개발자는 코드를 수정하고 master 브랜치를 기준으로 자신의 토픽 브랜치를 Rebase한다. 여기서 master 브랜치란 Dictator의 브랜치를 말한다. -2. Lieutenant들은 개발자들의 수정사항을 자신이 관리하는 master 브랜치에 Merge한다. -3. Dictator는 Lieutenant의 master 브랜치를 자신의 master 브랜치로 Merge한다. -4. Dictator는 Merge한 자신의 master 브랜치를 Push하여 다른 모든 개발자가 Rebase할 수 있는 기준으로 만든다. +1. 개발자는 코드를 수정하고 master 브랜치를 기준으로 자신의 토픽 브랜치를 Rebase한다. 여기서 master 브랜치란 Dictator의 브랜치를 말한다. +2. Lieutenant들은 개발자들의 수정사항을 자신이 관리하는 master 브랜치에 Merge한다. +3. Dictator는 Lieutenant의 master 브랜치를 자신의 master 브랜치로 Merge한다. +4. Dictator는 Merge한 자신의 master 브랜치를 Push하여 다른 모든 개발자가 Rebase할 수 있는 기준으로 만든다. Insert 18333fig0503.png 그림 5-3 Benevolent dictator Workflow @@ -83,14 +83,14 @@ Insert 18333fig0503.png 그리고 각 커밋은 논리적으로 구분되는 Changeset이다. 최대한 수정사항을 하나의 주제로 요약할 수 있어야 하고 여러 가지 이슈에 대한 수정사항을 하나의 커밋에 담지 않아야 한다. 여러 가지 이슈를 한꺼번에 수정했다고 하더라도 Staging Area을 이용하여 한 커밋에 하나의 이슈만 담기도록 한다. 작업 내용을 분할하고, 각 커밋마다 적절한 메시지를 작성한다. 같은 파일의 다른 부분을 수정하는 경우에는 `git add -patch` 명령을 써서 한 부분씩 나누어 Staging Area에 저장해야 한다(관련 내용은 *6장*에서 다룬다). 결과적으로 최종 프로젝트의 모습은 한 번에 커밋을 하든 다섯 번에 나누어 커밋을 하든 똑같다. 하지만, 여러 번 나누어 커밋하는 것이 좋다. 다른 동료가 수정한 부분을 확인할 때나 각 커밋의 시점으로 복원해서 검토할 때 이해하기 훨씬 쉽다. *6장*에서 이미 저장된 커밋을 다시 수정하거나 파일을 단계적으로 Staging Area에 저장하는 방법을 살펴본다. 다양한 도구를 이용해서 간단하고 이해하기 쉬운 커밋을 쌓아가야 한다. -마지막으로 명심해야 할 점은 커밋 메시지 자체다. 좋은 커밋 메시지를 작성하는 습관은 Git을 사용하는 데 도움이 많이 된다. 일반적으로 커밋 메시지를 작성할 때 사용하는 규칙이 있다. 메시지의 첫 줄에 50자가 넘지 않는 아주 간략한 메시지를 적어 해당 커밋을 요약한다. 다음 한 줄은 비우고 그다음 줄부터 커밋을 자세히 설명한다. 예를 들어 Git 개발 프로젝트에서는 개발 동기와 구현 상황의 제약조건이나 상황 등을 자세하게 요구한다. 이런 점은 따를 만한 좋은 가이드라인이다. 그리고 현재형 표현을 사용하는 것이 좋다. 예를 들어 "I added tests for (테스트를 추가함)" 보다는 "Add tests for (테스트 추가)" 와 같은 메시지를 작성한다. 아래 예제는 Pope_at_tpope.net이 작성한 커밋 메시지이다. +마지막으로 명심해야 할 점은 커밋 메시지 자체다. 좋은 커밋 메시지를 작성하는 습관은 Git을 사용하는 데 도움이 많이 된다. 일반적으로 커밋 메시지를 작성할 때 사용하는 규칙이 있다. 메시지의 첫 줄에 50자가 넘지 않는 아주 간략한 메시지를 적어 해당 커밋을 요약한다. 다음 한 줄은 비우고 그다음 줄부터 커밋을 자세히 설명한다. 예를 들어 Git 개발 프로젝트에서는 개발 동기와 구현 상황의 제약조건이나 상황 등을 자세하게 요구한다. 이런 점은 따를 만한 좋은 가이드라인이다. 그리고 현재형 표현을 사용하는 것이 좋다. 예를 들어 "I added tests for (테스트를 추가함)" 보다는 "Add tests for (테스트 추가)" 와 같은 메시지를 작성한다. 아래 예제는 Pope at tpope.net이 작성한 커밋 메시지이다. 영문 50글자 이하의 간략한 수정 요약 자세한 설명. 영문 72글자 이상이 되면 줄 바꿈을 하고 이어지는 내용을 작성한다. 특정 상황에서는 첫 번째 줄이 이메일 메시지의 제목이 되고 - 나머지는 메일 내용이 된다. 간략하게 요약하고 넣는 빈 줄은 매우 - 중요하다. 자세한 설명이 있으면 꼭 넣는다. + 나머지는 메일 내용이 된다. 간략하게 요약하고 넣는 빈 줄은 자세한 + 설명을 아예 쓰지 않는 한 매우 중요하다. 이어지는 내용도 한 줄 띄우고 쓴다. @@ -354,12 +354,12 @@ John씨가 몇 가지 작업을 하고 나서 featureA에 Push했고 확인해 Jessica씨는 일부 수정하고, 수정한 내용을 다시 서버로 Push한다: $ git commit -am 'small tweak' - [featureA ed774b3] small tweak + [featureA 774b3ed] small tweak 1 files changed, 1 insertions(+), 1 deletions(-) $ git push origin featureA ... To jessica@githost:simplegit.git - 3300904..ed774b3 featureA -> featureA + 3300904..774b3ed featureA -> featureA 위와 같은 작업을 마치고 나면 Jessica씨의 저장소는 그림 5-13과 같은 모습이 된다. @@ -571,7 +571,7 @@ Git으로 메일을 보내면 아래와 같은 로그 메시지가 출력된다: $ git branch sc/ruby_client master -`checkout -b` 옵션으로 브랜치를 만들고 Checkout까지 한 번에 할 수 있다: +`checkout -b` 명령으로 브랜치를 만들고 Checkout까지 한 번에 할 수 있다: $ git checkout -b sc/ruby_client master diff --git a/ko/06-git-tools/01-chapter6.markdown b/ko/06-git-tools/01-chapter6.markdown index f9b23b67c..0bac5d29a 100644 --- a/ko/06-git-tools/01-chapter6.markdown +++ b/ko/06-git-tools/01-chapter6.markdown @@ -105,7 +105,7 @@ Git은 브랜치가 가리키는 것이 변경될 때마다 그 정보를 임시 $ git log -g master commit 734713bc047d87bf7eac9674765ae793478c50d3 Reflog: master@{0} (Scott Chacon ) - Reflog message: commit: fixed refs handling, added gc auto, updated + Reflog message: commit: fixed refs handling, added gc auto, updated Author: Scott Chacon Date: Fri Jan 2 18:32:33 2009 -0800 @@ -128,10 +128,10 @@ reflog의 일은 모두 로컬의 일이기 때문에 내 reflog가 동료의 $ git log --pretty=format:'%h %s' --graph * 734713b fixed refs handling, added gc auto, updated tests * d921970 Merge commit 'phedders/rdocs' - |\ + |\ | * 35cfb2b Some rdoc changes * | 1c002dd added some blame and merge stuff - |/ + |/ * 1c36188 ignore *.gem * 9b29157 add open3_detach to gemspec file list @@ -260,7 +260,7 @@ Git은 대화형 명령어도 제공해서 좀 더 쉽게 사용할 수 있다. *** Commands *** 1: status 2: update 3: revert 4: add untracked 5: patch 6: diff 7: quit 8: help - What now> + What now> 이 명령어는 Staging Area의 현재 상태가 어떻고 할 수 있는 일이 무엇인지 보여준다. 기본적으로 `git status` 명령이 보여주는 것과 같지만 좀 더 간결하고 정돈돼 있다. 왼쪽에는 Staged 상태인 파일들을 보여주고 오른쪽에는 Unstaged인 파일들을 보여준다. @@ -288,7 +288,7 @@ TODO와 index.html 파일을 Stage하려면 아래와 같이 입력한다: `*` 표시가 붙은 파일은 stage하도록 선택한 것이다. 선택하고 `Update>>` 프롬프트에 아무것도 입력하지 않고 엔터를 치면 Git은 선택한 파일을 Staging Area로 추가한다: - Update>> + Update>> updated 2 paths *** Commands *** @@ -300,7 +300,7 @@ TODO와 index.html 파일을 Stage하려면 아래와 같이 입력한다: 2: +1/-1 nothing index.html 3: unchanged +5/-1 lib/simplegit.rb -이제 TODO와 index.html 파일은 Stage했고 simplegit.rb 파일만 아직 Unstaged 상태로 남아 있다. 이제 TODO 파일을 다시 Unstage하고 싶으면 `3`이나 `r`을(Revert) 입력한다: +이제 TODO와 index.html 파일은 Stage했고 simplegit.rb 파일만 아직 Unstaged 상태로 남아 있다. 이제 TODO 파일을 다시 Unstage하고 싶으면 `3`이나 `r`을(Revert) 입력한다: *** Commands *** 1: status 2: update 3: revert 4: add untracked @@ -370,7 +370,7 @@ Staged 파일의 변경내용을 보려면 `6`이나 `d`를(diff) 입력한다. end def blame(path) - Stage this hunk [y,n,a,d,/,j,J,g,e,?]? + Stage this hunk [y,n,a,d,/,j,J,g,e,?]? 여기에서 `?`를 입력하면 선택 가능한 명령어를 설명해준다: @@ -409,7 +409,7 @@ Stash 명령을 사용하면 워킹 디렉토리에서 수정한 파일만 저 ### 하던 일을 Stash하기 ### -예제 프로젝트를 하나 살펴보자. 파일을 두 개 수정하고 그 중 하나는 Staging Area에 추가한다. 그리고 `git status` 명령을 실행하면 아래와 같은 결과를 볼 수 있다: +예제 프로젝트를 하나 살펴보자. 파일을 두 개 수정하고 그 중 하나는 Staging Area에 추가한다. 그리고 `git status` 명령을 실행하면 아래와 같은 결과를 볼 수 있다: $ git status # On branch master @@ -456,7 +456,7 @@ Stash 두 개는 원래 있었던 것이다. 그래서 현재 총 세 개의 Sta # modified: lib/simplegit.rb # -Git은 Stash에 저장할 때 수정하던 파일을 복원해준다. 복원할 때의 워킹 디렉토리는 Stash할 때의 그 브랜치이고 워킹 디렉토리도 깨끗한 상태였다. 하지만, 꼭 깨끗한 워킹 디렉토리나 Stash할 때와 같은 브랜치에 적용해야 하는 것은 아니다. 어떤 브랜치에서 Stash하고 다른 브랜치로 옮기고서 거기에 Stash를 복원할 수 있다. 그리고 꼭 워킹 디렉토리가 깨끗한 상태일 필요도 없다. 워킹 디렉토리에 수정하고 커밋하지 않은 파일들이 있을 때에도 Stash를 적용할 수 있다. 만약 충돌이 나면 알려준다. +Git은 Stash에 저장할 때 수정하던 파일을 복원해준다. 복원할 때의 워킹 디렉토리는 Stash할 때의 그 브랜치이고 워킹 디렉토리도 깨끗한 상태였다. 하지만, 꼭 깨끗한 워킹 디렉토리나 Stash할 때와 같은 브랜치에 적용해야 하는 것은 아니다. 어떤 브랜치에서 Stash하고 다른 브랜치로 옮기고서 거기에 Stash를 복원할 수 있다. 그리고 꼭 워킹 디렉토리가 깨끗한 상태일 필요도 없다. 워킹 디렉토리에 수정하고 커밋하지 않은 파일들이 있을 때에도 Stash를 적용할 수 있다. 만약 충돌이 나면 알려준다. Git은 Stash를 적용할 때 Staged 상태였던 파일을 자동으로 다시 Staged 상태로 만들어 주지 않는다. 그래서 `git stash apply` 명령을 실행할 때 `--index` 옵션을 주어야 Staged 상태까지 복원한다. 그럼 원래 작업하던 상태로 돌아올 수 있다: @@ -665,7 +665,7 @@ Git으로 일하다 보면 어떤 이유로든 커밋 히스토리를 수정해 edit 310154e updated README formatting and added blame pick a5f4a0d added cat-file -저장해서 명령 프롬프트로 넘어가면 그 커밋을 Reset하고 그 내용을 다시 두 개로 나눠서 커밋하면 된다. 저장하고 편집기를 종료하면 Git은 제일 오래된 커밋의 부모로 이동하고서 `f7f3f6d`과 `310154e`을 처리하고 콘솔 프롬프트를 보여준다. 여기서 커밋을 Reset하는 `git reset HEAD^`라는 명령으로 커밋을 Reset한다. 그러면 수정했던 파일은 Unstaged 상태가 된다. 그다음에 파일을 Stage하고 커밋하는 일을 원하는 만큼 반복하고 나서 `git rebase --continue`라는 명령을 실행하면 Rebase 작업이 모두 끝난다: +위와 같이 수정하고 나서 저장하고 편집기를 종료하면 Git은 제일 오래된 커밋의 부모로 이동하고서 `f7f3f6d`과 `310154e`을 처리하고 콘솔 프롬프트를 보여준다. 여기서 커밋을 해제하는 `git reset HEAD^`라는 명령으로 커밋을 해제한다. 그러면 수정했던 파일은 Unstaged 상태가 된다. 그다음에 파일들을 Stage한 후 커밋하는 일을 원하는 만큼 반복하고 나서 `git rebase --continue`라는 명령을 실행하면 남은 Rebase작업이 끝난다: $ git reset HEAD^ $ git add README @@ -734,7 +734,7 @@ Git은 굉장히 유연해서 어떤 프로젝트에나 사용할 수 있다. 버그를 찾을 때 먼저 그 코드가 왜, 언제 추가했는지 알고 싶을 것이다. 이때는 파일 어노테이션을 활용한다. 한줄한줄 마지막으로 커밋한 사람이 누구인지, 언제 마지막으로 커밋했는지 볼 수 있다. 어떤 메소드에 버그가 있으면 `git blame` 명령으로 그 메소드의 각 줄을 누가 언제 마지막으로 고쳤는지 찾아낼 수 있다: - $ git blame -L 12,22 simplegit.rb + $ git blame -L 12,22 simplegit.rb ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 12) def show(tree = 'master') ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 13) command("git show #{tree}") ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 14) end @@ -751,8 +751,8 @@ Git은 굉장히 유연해서 어떤 프로젝트에나 사용할 수 있다. Git은 파일 이름을 변경한 이력을 별도로 기록해두지 않는다. 하지만, 원래 이 정보들은 각 스냅샷에 저장되고 이 정보를 이용하여 변경 이력을 만들어 낼 수 있다. 그러니까 파일에 생긴 변화는 무엇이든지 알아낼 수 있다. Git은 파일 어노테이션을 분석하여 코드들이 원래 어떤 파일에서 커밋된 것인지 찾아준다. 예를 들어보자. `GITServerHandler.m`을 여러 개의 파일로 리팩토링했는데 그 중 한 파일이 `GITPackUpload.m`이라는 파일이라고 하자. `-C` 옵션으로 `GITPackUpload.m` 파일을 추적해보면 각 코드가 원래 어떤 파일로 커밋된 것인지 알 수 있다: - $ git blame -C -L 141,153 GITPackUpload.m - f344f58d GITServerHandler.m (Scott 2009-01-04 141) + $ git blame -C -L 141,153 GITPackUpload.m + f344f58d GITServerHandler.m (Scott 2009-01-04 141) f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC f344f58d GITServerHandler.m (Scott 2009-01-04 143) { 70befddd GITServerHandler.m (Scott 2009-03-22 144) //NSLog(@"GATHER COMMI @@ -849,7 +849,7 @@ Git의 서브모듈은 이런 문제를 해결해준다. 서브모듈은 Git 저 `.gitmodules` 파일을 살펴보자. 이 것은 로컬 디렉토리와 프로젝트 URL의 매핑 정보가 저장된 설정파일이다: - $ cat .gitmodules + $ cat .gitmodules [submodule "rack"] path = rack url = git://github.com/chneukirchen/rack.git diff --git a/ko/07-customizing-git/01-chapter7.markdown b/ko/07-customizing-git/01-chapter7.markdown index b7a2c2c18..b5662e4be 100644 --- a/ko/07-customizing-git/01-chapter7.markdown +++ b/ko/07-customizing-git/01-chapter7.markdown @@ -93,7 +93,7 @@ Git이 무시하는 untracked 파일은 `.gitignore`에 해당 패턴을 적으 #### help.autocorrect #### -이 옵션은 Git 1.6.1 버전부터 사용할 수 있다. 명령어를 잘못 입력하면 Git 1.6에서는 메시지를 아래와 같이 보여 준다: +이 옵션은 Git 1.6.1 버전부터 사용할 수 있다. 명령어를 잘못 입력하면 Git은 메시지를 아래와 같이 보여 준다: $ git com git: 'com' is not a git-command. See 'git --help'. @@ -113,13 +113,13 @@ Git이 무시하는 untracked 파일은 `.gitignore`에 해당 패턴을 적으 $ git config --global color.ui true -이 옵션을 켜면 Git은 터미널에 컬러로 결과를 출력한다. 이 값을 false로 설정하면 절대 컬러로 출력하지 않는다. 결과를 파일로 리다이렉트하거나 다른 프로그램으로 보낼(Piping. 파이프라인)때도 그렇다. 이 설정은 1.5.5 버전에 이르러 추가됐고 예전 버전을 사용하고 있으면 해당 요소마다 직접 컬러를 지정해주어야 한다. +이 옵션을 켜면 Git은 터미널에 컬러로 결과를 출력한다. 이 값을 false로 설정하면 절대 컬러로 출력하지 않는다. 결과를 파일로 리다이렉트하거나 다른 프로그램으로 보낼(Piping. 파이프라인)때도 그렇다. `color.ui = always`라고 설정하면 결과를 리다이렉트할 때에도 컬러 코드가 출력된다. 이렇게까지 설정해야 하는 경우는 매우 드물다. 대신 Git 명령에는 `--color` 옵션이 있어서 어떻게 출력할지 그때그때 정해줄 수 있다. 보통은 `color.ui = true` 만으로도 충분하다. #### `color.*` #### -좀 더 꼼꼼하게 컬러를 설정하거나 예전 버전이라서 `color.ui` 옵션을 사용할 수 없으면 아래와 같이 종류별로 설정할 수 있다. 모두 `true`, `false`, `always` 중 하나를 고를 수 있다: +Git은 좀 더 꼼꼼하게 컬러를 설정하는 방법을 제공한다. 아래와 같은 설정들이 있다. 모두 `true`, `false`, `always` 중 하나를 고를 수 있다: color.branch color.diff @@ -128,7 +128,7 @@ Git이 무시하는 untracked 파일은 `.gitignore`에 해당 패턴을 적으 또한, 각 옵션의 컬러를 직접 지정할 수도 있다. 아래처럼 설정하면 diff 명령에서 meta 정보의 포그라운드는 blue, 백그라운드는 black, 테스트는 bold로 바뀐다: - $ git config --global color.diff.meta “blue black bold” + $ git config --global color.diff.meta "blue black bold" 컬러는 normal, black, red, green, yellow, blue, magenta, cyan, white 중에서 고를 수 있고 텍스트 속성은 bold, dim, ul, blink, reverse 중에서 고를 수 있다. @@ -156,13 +156,13 @@ P4Merge는 중요 플랫폼을 모두 지원하기 때문에 웬만한 환경이 이 중에서 `old-file`과 `new-file` 만 사용하는 wrapper script를 만든다: - $ cat /usr/local/bin/extDiff + $ cat /usr/local/bin/extDiff #!/bin/sh [ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5" 이 두 스크립트에 실행 권한을 부여한다: - $ sudo chmod +x /usr/local/bin/extMerge + $ sudo chmod +x /usr/local/bin/extMerge $ sudo chmod +x /usr/local/bin/extDiff Git config 파일에 이 스크립트를 모두 추가한다. 설정해야 하는 옵션이 좀 많다. `merge.tool`로 무슨 Merge 도구를 사용할지, `mergetool.*.cmd`로 실제로 어떻게 명령어를 실행할지, `mergetool.trustExitCode`로 Merge 도구가 반환하는 exit 코드가 merge의 성공여부를 나타내는지, `diff.external`은 diff할 때 실행할 명령어가 무엇인지를 설정할 때 사용한다. 모두 `git config` 명령으로 설정한다: @@ -197,7 +197,7 @@ Insert 18333fig0701.png Wrapper를 만들어 설정해두면 다른 diff, Merge 도구로 바꾸기도 쉽다. 예를 들어, KDiff3를 사용하도록 extDiff와 extMerge 스크립트를 수정한다: $ cat /usr/local/bin/extMerge - #!/bin/sh + #!/bin/sh /Applications/kdiff3.app/Contents/MacOS/kdiff3 $* 이제부터 Git은 diff 결과를 보여주거나 충돌을 해결할 때 KDiff3 도구를 사용한다. @@ -255,7 +255,7 @@ Git에는 공백 문자를 다루는 방법으로 네 가지가 미리 정의돼 ### 서버 설정 ### -서버 설정은 많지 않지만, 꼭 짚고 넘어가야 하는 것이 몇 개 있다. +서버 설정은 많지 않지만, 꼭 짚고 넘어가야 하는 것이 몇 개 있다. #### receive.fsckObjects #### @@ -307,13 +307,13 @@ Git은 Push할 때 기본적으로 개체를 검증하지(check for consistency) #### 바이너리 파일 Diff하기 #### -Git 1.6부터 바이너리 파일도 diff할 수 있게 됐다. 이 Attribute는 바이너리 파일을 텍스트 포맷으로 변환하고 그 결과를 diff로 비교하도록 하는 것이다. +Git은 바이너리 파일도 diff할 수 있다. 이 Attribute는 바이너리 파일을 텍스트 포맷으로 변환하고 그 결과를 diff로 비교하도록 하는 것이다. ##### MS Word 파일 ##### 이 Attribute는 잘 알려지진 않았지만 끝내준다. Word 문서를 버전 관리하는 상황을 살펴보자. 이 문제는 인류에게 알려진 가장 귀찮은 문제 중 하나다. 모든 사람이 Word가 가장 끔찍한 편집기라고 말하지만 애석하게도 모두 Word를 사용한다. Git 저장소에 넣고 커밋하는 것으로도 Word 문서를 버전 관리할 수 있다. 하지만 `git diff`를 실행하면 아래와 같은 메시지를 보여준다: - $ git diff + $ git diff diff --git a/chapter1.doc b/chapter1.doc index 88839c4..4afcb7c 100644 Binary files a/chapter1.doc and b/chapter1.doc differ @@ -345,9 +345,9 @@ Git 1.6부터 바이너리 파일도 diff할 수 있게 됐다. 이 Attribute는 @@ -8,7 +8,8 @@ re going to cover Version Control Systems (VCS) and Git basics re going to cover how to get it and set it up for the first time if you don t already have it on your system. - In Chapter Two we will go over basic Git usage - how to use Git for the 80% - -s going on, modify stuff and contribute changes. If the book spontaneously - +s going on, modify stuff and contribute changes. If the book spontaneously + In Chapter Two we will go over basic Git usage - how to use Git for the 80% + -s going on, modify stuff and contribute changes. If the book spontaneously + +s going on, modify stuff and contribute changes. If the book spontaneously +Let's see if this works. Git은 "Let's see if this works"가 추가됐다는 것을 정확하게 찾아 준다. 이것은 완벽하지는 않지만(끝에 아무거나 왕창 집어넣지만 않으면) 어쨌든 잘 동작한다. Word 문서를 텍스트로 잘 변환해 주는 프로그램이 있으면 이 방법은 좀 더 완벽해질 수 있다. Mac이나 Linux 같은 시스템에는 `strings`가 이미 설치되어 있기 때문에 당장 사용할 수 있다. @@ -371,13 +371,13 @@ OpenDocument 파일은 사실 여러 파일(XML, 스타일, 이미지 등등)을 #! /usr/bin/env perl # Simplistic OpenDocument Text (.odt) to plain text converter. # Author: Philipp Kempgen - + if (! defined($ARGV[0])) { print STDERR "No filename given!\n"; print STDERR "Usage: $0 filename\n"; exit 1; } - + my $content = ''; open my $fh, '-|', 'unzip', '-qq', '-p', $ARGV[0], 'content.xml' or die $!; { @@ -418,7 +418,7 @@ OpenDocument 파일은 사실 여러 파일(XML, 스타일, 이미지 등등)을 @@ -1,12 +1,12 @@ ExifTool Version Number : 7.74 -File Size : 70 kB - -File Modification Date/Time : 2009:04:21 07:02:45-07:00 + -File Modification Date/Time : 2009:04:17 10:12:35-07:00 +File Size : 94 kB +File Modification Date/Time : 2009:04:21 07:02:43-07:00 File Type : PNG @@ -445,7 +445,7 @@ Git은 이 파일을 Checkout할 때마다 SHA 값을 삽입해준다: $ rm test.txt $ git checkout -- test.txt - $ cat test.txt + $ cat test.txt $Id: 42812b7653c7b88933f8a9d6cad0ca16714b9bb3 $ 하지만 이것은 별로 유용하지 않다. CVS나 SVN의 키워드 치환(Keyword Substitution)을 써봤으면 날짜(Datestamp)도 가능했다는 것을 알고 있을 것이다. SHA는 그냥 해시이고 식별할 수 있을 뿐이지 다른 것을 알려주진 않는다. SHA만으로는 예전 것보다 새 것인지 오래된 것인지는 알 수 없다. @@ -547,7 +547,7 @@ Git도 다른 버전 관리 시스템처럼 어떤 이벤트가 생겼을 때 ### 훅 설치하기 ### -훅은 `.git/hooks`라는 디렉토리에 저장한다. 이 디렉토리에 가보면 Git이 자동으로 넣어준 매우 유용한 스크립트 예제가 몇 개 있다. 그리고 스크립트가 입력받는 값이 어떤 값인지 파일 안에 자세히 설명돼 있다. 모든 예제는 쉘과 Perl 스크립트로 작성돼 있지만 실행할 수만 있으면 되고 Ruby나 Python같은 스크립트 언어로 만들어도 된다. Git 1.6부터 예제 스크립트의 파일 이름에 `.sample`이라는 확장자가 붙었다. 그래서 이름만 바꿔주면 그 훅을 사용할 수 있다. 1·6 이전 버전에서는 파일 이름과 상관없이 비실행파일이 예제 파일이었다. +훅은 Git 디렉토리 밑에 `hooks`라는 디렉토리에 저장한다. 기본 훅 디렉토리는 `.git/hooks`이다. 이 디렉토리에 가보면 Git이 자동으로 넣어준 매우 유용한 스크립트 예제가 몇 개 있다. 그리고 스크립트가 입력받는 값이 어떤 값인지 파일 안에 자세히 설명돼 있다. 모든 예제는 쉘과 Perl 스크립트로 작성돼 있지만 실행할 수만 있으면 되고 Ruby나 Python같은 다른 스크립트 언어로 만들어도 된다.예제 스크립트의 파일 이름에는 `.sample`이라는 확장자가 붙어 있다. 그래서 이름만 바꿔주면 그 훅을 사용할 수 있다. 실행할 수 있는 스크립트 파일을 저장소의 `hooks` 디렉토리에 넣으면 훅 스크립트가 켜진다. 이 스크립트는 앞으로 계속 호출된다. 중요한 훅은 여기서 모두 설명한다. @@ -559,7 +559,7 @@ Git도 다른 버전 관리 시스템처럼 어떤 이벤트가 생겼을 때 먼저 커밋과 관련된 훅을 살펴보자. 커밋과 관련된 훅은 모두 네 가지다. `pre-commit` 훅은 커밋할 때 가장 먼저 호출되는 훅으로 커밋 메시지를 작성하기 전에 호출된다. 이 훅에서 커밋하는 Snapshot을 점검한다. 빠트린 것은 없는지, 테스트는 확실히 했는지 등을 검사한다. 커밋할 때 꼭 확인해야 할 게 있으면 이 훅으로 확인한다. 그리고 이 훅의 Exit 코드가 0이 아니면 커밋은 취소된다. 물론 `git commit --no-verify`라고 실행하면 이 훅을 일시적으로 생략할 수 있다. lint 같은 프로그램으로 코드 스타일을 검사하거나, 줄 끝의 공백 문자를 검사하거나(예제로 들어 있는 `pre-commit` 훅이 하는 게 이 일이다), 코드에 주석을 달았는지 검사하는 일은 이 훅으로 하는 것이 좋다. -`prepare-commit-msg` 훅은 Git이 커밋 메시지를 생성하고 나서 편집기를 실행하기 전에 실행된다. 이 훅은 사람이 커밋 메시지를 수정하기 전에 먼저 프로그램으로 손보고 싶을 때 사용한다. 이 훅은 커밋 메시지가 들어 있는 파일의 경로, 커밋의 종류를 아규먼트로 받는다. 그리고 최근 커밋을 수정할 때에는(Amending Commit) SHA-1 값을 추가 아규먼트로 더 받는다. 사실 이 훅은 일반 커밋에는 별로 필요 없고 커밋 메시지가 자동으로 생성될 때 좋다. 커밋 메시지에 템플릿을 적용하거나, Merge 커밋, Squash 커밋, Amend 커밋일 때 유용하다. 이 스크립트로 커밋 메시지 템플릿에 정보를 삽입할 수 있다. +`prepare-commit-msg` 훅은 Git이 커밋 메시지를 생성하고 나서 편집기를 실행하기 전에 실행된다. 이 훅은 사람이 커밋 메시지를 수정하기 전에 먼저 프로그램으로 손보고 싶을 때 사용한다. 이 훅은 커밋 메시지가 들어 있는 파일의 경로, 커밋의 종류를 아규먼트로 받는다. 그리고 최근 커밋을 수정할 때에는(Amending 커밋) SHA-1 값을 추가 아규먼트로 더 받는다. 사실 이 훅은 일반 커밋에는 별로 필요 없고 커밋 메시지를 자동으로 생성하는 커밋에 좋다. 커밋 메시지에 템플릿을 적용하거나, Merge 커밋, Squash 커밋, Amend 커밋일 때 유용하다. 이 스크립트로 커밋 메시지 템플릿에 정보를 삽입할 수 있다. `commit-msg` 훅은 커밋 메시지가 들어 있는 임시 파일의 경로를 아규먼트로 받는다. 그리고 이 스크립트가 0이 아닌 값을 반환하면 커밋되지 않는다. 이 훅에서 최종적으로 커밋이 완료되기 전에 프로젝트 상태나 커밋 메시지를 검증한다. 이 장의 마지막 절에서 이 훅을 사용하는 예제를 보여준다. 커밋 메시지가 정책에 맞는지 검사하는 스크립트를 만들어 보자. @@ -601,7 +601,7 @@ update 스크립트는 각 브랜치마다 한 번씩 실행된다는 것을 제 ## 정책 구현하기 ## -지금까지 배운 것을 한 번 적용해보자. 커밋 메시지 규칙 검사하고, Fast-forward Push만 허용하고, 디렉토리마다 사용자의 수정 권한을 제어하는 Workflow를 만들어 본다. 실질적으로 정책을 강제하려면 서버 훅으로 만들어야 한다. 하지만, 개발자들이 Push할 수 없는 커밋은 아예 만들지 않도록 클라이언트 훅도 만들어 본다. +지금까지 배운 것을 한 번 적용해보자. 커밋 메시지 규칙 검사하고, Fast-forward Push만 허용하고, 디렉토리마다 사용자의 수정 권한을 제어하는 Workflow를 만든다. 실질적으로 정책을 강제하려면 서버 훅으로 만들어야 한다. 하지만, 개발자들이 Push할 수 없는 커밋은 아예 만들지 않도록 클라이언트 훅도 만든다. 필자가 제일 좋아하는 Ruby로 만든다. 필자는 독자가 슈도코드를 읽듯이 Ruby 코드를 읽을 수 있다고 생각한다. Ruby를 모르더라도 충분히 개념을 이해할 수 있을 것이다. 하지만, Git은 언어를 가리지 않는다. Git이 자동으로 생성해주는 예제는 모두 Perl과 Bash로 작성돼 있다. 그래서 예제를 열어 보면 Perl과 Bash로 작성된 예제를 참고 할 수 있다. @@ -754,11 +754,11 @@ update 스크립트는 각 브랜치마다 한 번씩 실행된다는 것을 제 #### Fast-Forward Push만 허용하기 #### -이제 Fast-forward Push가 아니면 거절되게 해보자. Git 1.6부터 `receive.denyDeletes`와 `receive.denyNonFastForwards` 설정으로 간단하게 거절할 수 있다. 하지만, 그 이전 버전에는 꼭 훅으로 구현해야 했다. 게다가 특정 사용자만 제한하거나 허용하려면 훅으로 구현해야 한다. +이제 Fast-forward Push가 아니면 거절되게 해보자. `receive.denyDeletes`와 `receive.denyNonFastForwards` 설정으로 간단하게 거절할 수 있다. 하지만, 그 이전 버전에는 꼭 훅으로 구현해야 했다. 게다가 특정 사용자만 제한하거나 허용하려면 훅으로 구현해야 한다. 기존에 있던 커밋이 Push하는 브랜치에 없으면 Fast-forward Push가 아니라고 판단한다. 커밋 하나라도 없으면 거절하고 모두 있으면 Fast-forward Push이므로 그대로 둔다: - # enforces fast-forward only pushes + # enforces fast-forward only pushes def check_fast_forward missed_refs = `git rev-list #{$newrev}..#{$oldrev}` missed_ref_count = missed_refs.split("\n").size @@ -778,7 +778,7 @@ update 스크립트는 각 브랜치마다 한 번씩 실행된다는 것을 제 Writing objects: 100% (3/3), 323 bytes, done. Total 3 (delta 1), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. - Enforcing Policies... + Enforcing Policies... (refs/heads/master) (8338c5) (c5b616) [POLICY] Cannot push a non fast-forward reference error: hooks/update exited with error code 1 @@ -789,7 +789,7 @@ update 스크립트는 각 브랜치마다 한 번씩 실행된다는 것을 제 정책과 관련해 하나씩 살펴보자. 먼저 훅이 실행될 때마다 다음 메시지가 출력된다. - Enforcing Policies... + Enforcing Policies... (refs/heads/master) (8338c5) (c5b616) 이것은 update 스크립트 맨 윗부분에서 표준출력(STDOUT)에 출력한 내용이다. 스크립트에서 표준출력으로 출력하면 클라이언트로 전송된다. 이점을 꼭 기억하자. @@ -820,7 +820,7 @@ update 스크립트는 각 브랜치마다 한 번씩 실행된다는 것을 제 ### 클라이언트 훅 ### -서버 훅의 단점은 Push할 때까지 Push할 수 있는지 없는지 알 수 없다는데 있다. 기껏 공들여 정성껏 구현했는데 막상 Push할 수 없으면 곤혹스럽다. 히스토리를 제대로 고치는 일은 정신건강에 매우 해롭다. +서버 훅의 단점은 Push할 때까지 Push할 수 있는지 없는지 알 수 없다는데 있다. 기껏 공들여 정성껏 구현했는데 막상 Push할 수 없으면 곤혹스럽다. 히스토리를 제대로 고치는 일은 정신건강에 매우 해롭다. 이 문제는 클라이언트 훅으로 해결한다. 클라이언트 훅으로 서버가 거부할지 말지 검사한다. 사람들은 커밋하기 전에, 그러니까 시간이 지나 고치기 어려워지기 전에 문제를 해결할 수 있다. Clone할 때 이 훅은 전송되지 않기 때문에 다른 방법으로 동료에게 배포해야 한다. 그 훅을 가져다 `.git/hooks` 디렉토리에 복사하고 실행할 수 있게 만든다. 이 훅 파일을 프로젝트에 넣어서 배포해도 되고 Git 훅 프로젝트를 만들어서 배포해도 된다. 하지만, 자동으로 설치하는 방법은 없다. @@ -916,7 +916,7 @@ Fast-forward Push인지 확인하는 일이 남았다. 보통은 Fast-forward가 target_shas.each do |sha| remote_refs.each do |remote_ref| shas_pushed = `git rev-list ^#{sha}^@ refs/remotes/#{remote_ref}` - if shas_pushed.split(“\n”).include?(sha) + if shas_pushed.split("\n").include?(sha) puts "[POLICY] Commit #{sha} has already been pushed to #{remote_ref}" exit 1 end diff --git a/ko/08-git-and-other-scms/01-chapter8.markdown b/ko/08-git-and-other-scms/01-chapter8.markdown index ffc60d675..449dbb3b6 100644 --- a/ko/08-git-and-other-scms/01-chapter8.markdown +++ b/ko/08-git-and-other-scms/01-chapter8.markdown @@ -29,14 +29,14 @@ Git과 Subversion을 이어주는 명령은 `git svn` 으로 시작한다. 이 그리고 모든 사용자가 revprops 속성을 변경할 수 있도록 항상 0을 반환하는 pre-revprop-change 스크립트를 준비한다(역주: 파일이 없거나, 다른 이름으로 되어있을 수 있다. 이 경우 아래 내용으로 새로 파일을 만들고 실행 권한을 준다): - $ cat /tmp/test-svn/hooks/pre-revprop-change + $ cat /tmp/test-svn/hooks/pre-revprop-change #!/bin/sh exit 0; $ chmod +x /tmp/test-svn/hooks/pre-revprop-change 이제 `svnsync init` 명령으로 다른 Subversion 저장소를 로컬로 복사할 수 있도록 지정한다: - $ svnsync init file:///tmp/test-svn http://progit-example.googlecode.com/svn/ + $ svnsync init file:///tmp/test-svn http://progit-example.googlecode.com/svn/ 이렇게 다른 저장소의 주소를 설정하면 복사할 준비가 된다. 아래 명령으로 저장소를 실제로 복사한다: @@ -281,7 +281,7 @@ Subversion에 익숙한 사람은 Git 히스토리를 SVN 형식으로 보고 ------------------------------------------------------------------------ r85 | schacon | 2009-05-02 16:00:09 -0700 (Sat, 02 May 2009) | 2 lines - + updated the changelog `git svn log`명령에서 기억해야 할 것은 두 가지다. 우선 오프라인에서 동작한다는 점이다. SVN의 `svn log` 명령어는 히스토리 데이터를 조회할 때 서버가 필요하다. 둘째로 이미 서버로 전송한 커밋만 출력해준다. 아직 `dcommit` 명령으로 서버에 전송하지 않은 로컬 Git 커밋은 보여주지 않는다. Subversion 서버에는 있지만 아직 내려받지 않은 변경사항도 보여주지 않는다. 즉, 현재 알고있는 Subversion 서버의 상태만 보여준다. @@ -290,19 +290,19 @@ Subversion에 익숙한 사람은 Git 히스토리를 SVN 형식으로 보고 `git svn log` 명령이 `svn log` 명령을 흉내내는 것처럼 `git svn blame [FILE]` 명령으로 `svn annotate` 명령을 흉내낼 수 있다. 실행한 결과는 아래와 같다: - $ git svn blame README.txt + $ git svn blame README.txt 2 temporal Protocol Buffers - Google's data interchange format 2 temporal Copyright 2008 Google Inc. 2 temporal http://code.google.com/apis/protocolbuffers/ - 2 temporal + 2 temporal 22 temporal C++ Installation - Unix 22 temporal ======================= - 2 temporal + 2 temporal 79 schacon Committing in git-svn. - 78 schacon + 78 schacon 2 temporal To build and install the C++ Protocol Buffer runtime and the Protocol 2 temporal Buffer compiler (protoc) execute the following: - 2 temporal + 2 temporal 다시 한번 말하지만 이 명령도 아직 서버로 전송하지 않은 커밋은 보여주지 않는다. @@ -393,19 +393,17 @@ SVN에 기록된 Author 이름을 아래 명령으로 조회한다: Author 정보가 훨씬 Git답고 `git-svn-id` 항목도 기록되지 않았다. -이제 뒷 정리를 해야 한다. `git svn`이 만들어 준 이상한 브랜치나 태그를 제거한다. 우선 이상한 리모트 태그를 모두 진짜 Git 태그로 옮긴다. 그리고 리모트 브랜치도 로컬 브랜치로 옮긴다. +이제 뒷 정리를 해야 한다. `git svn`이 만들어 준 이상한 브랜치나 태그를 제거한다. 우선 이상한 리모트 태그를 모두 진짜 Git 태그로 옮긴다. 그리고 리모트 브랜치도 로컬 브랜치로 옮긴다. 아래와 같이 태그를 진정한 Git 태그로 만든다: - $ cp -Rf .git/refs/remotes/tags/* .git/refs/tags/ - $ rm -Rf .git/refs/remotes/tags + $ git for-each-ref refs/remotes/tags | cut -d / -f 4- | grep -v @ | while read tagname; do git tag "$tagname" "tags/$tagname"; git branch -r -d "tags/$tagname"; done `tags/` 로 시작하는 리모트 브랜치를 가져다 (Lightweight) 태그로 만들었다. `refs/remotes` 밑에 있는 레퍼런스는 전부 로컬 브랜치로 만든다: - $ cp -Rf .git/refs/remotes/* .git/refs/heads/ - $ rm -Rf .git/refs/remotes + $ git for-each-ref refs/remotes | cut -d / -f 3- | grep -v @ | while read branchname; do git branch "$branchname" "refs/remotes/$branchname"; git branch -r -d "$branchname"; done 이제 모든 태그와 브랜치는 진짜 Git 태그와 브랜치가 됐다. Git 서버를 새로 추가를 하고 지금까지 작업한 것을 Push하는 일이 남았다. 아래처럼 리모트 서버를 추가한다: @@ -419,7 +417,7 @@ Author 정보가 훨씬 Git답고 `git-svn-id` 항목도 기록되지 않았다. ### Perforce ### -이제 Perforce 차례다. Preforce Importer도 Git에 들어 있지만 소스코드의 `contrib` 에 있기 때문에 `git svn` 처럼 바로 사용할 수 없다. Perforce Importer를 사용하려면 우선 git.kernel.org에서 Git 소스코드를 가져와야 한다: +이제 Perforce 차례다. Preforce Importer도 Git에 들어 있다. Git 1.7.11 이전 버전을 사용한다면 소스코드의 `contrib` 에 포함되어 있다.이런 경우라면 Perforce Importer를 사용하기 위해 우선 git.kernel.org에서 Git 소스코드를 가져와야 한다: $ git clone git://git.kernel.org/pub/scm/git/git.git $ cd git/contrib/fast-import @@ -513,7 +511,7 @@ Importer를 만들기 전에 우선 Git이 어떻게 데이터를 저장하는 next if File.file?(dir) # move into the target directory - Dir.chdir(dir) do + Dir.chdir(dir) do last_mark = print_export(dir, last_mark) end end @@ -631,7 +629,7 @@ Mark는 정수 값을 사용해야 하기 때문에 디렉토리를 배열에 new version one (...) -디렉토리를 하나 만들고 `git init` 명령을 실행해서 옮길 Git 프로젝트를 만든다. 그리고 그 프로젝트 디렉토리로 이동해서 이 명령의 표준출력을 `git fast-import` 명령의 표준입력으로 연결한다(pipe). +디렉토리를 하나 만들고 `git init` 명령을 실행해서 옮길 Git 프로젝트를 만든다. 그리고 그 프로젝트 디렉토리로 이동해서 이 명령의 표준출력을 `git fast-import` 명령의 표준입력으로 연결한다(pipe). $ git init Initialized empty Git repository in /opt/import_to/.git/ diff --git a/ko/09-git-internals/01-chapter9.markdown b/ko/09-git-internals/01-chapter9.markdown index 001d96a6a..8386c83ea 100644 --- a/ko/09-git-internals/01-chapter9.markdown +++ b/ko/09-git-internals/01-chapter9.markdown @@ -432,7 +432,7 @@ Linux Kernel 저장소에도 커밋이 아닌 다른 개체를 가리키는 태 Git은 zlib으로 파일 내용을 압축하기 때문에 저장 공간이 많이 필요하지 않다. 그래서 이 데이터베이스에 저장된 파일은 겨우 925바이트밖에 되지 않는다. 크기가 큰 파일을 추가해서 이 기능의 효과를 좀 더 살펴보자. 앞 장에서 사용했던 Grit 라이브러리에 들어 있는 repo.rb 파일을 추가한다. 이 파일의 크기는 약 12K이다. - $ curl http://github.com/mojombo/grit/raw/master/lib/grit/repo.rb > repo.rb + $ curl https://raw.github.com/mojombo/grit/master/lib/grit/repo.rb > repo.rb $ git add repo.rb $ git commit -m 'added repo.rb' [master 484a592] added repo.rb @@ -448,10 +448,10 @@ Git은 zlib으로 파일 내용을 압축하기 때문에 저장 공간이 많 100644 blob 9bc1dc421dcd51b4ac296e3e5b6e2a99cf44391e repo.rb 100644 blob e3f094f522629ae358806b17daf78246c27c007b test.txt -개체의 크기도 `git cat-file` 명령으로 확인할 수 있다: +개체의 크기는 아래와 같이 확인한다: - $ git cat-file -s 9bc1dc421dcd51b4ac296e3e5b6e2a99cf44391e - 12898 + $ du -b .git/objects/9b/c1dc421dcd51b4ac296e3e5b6e2a99cf44391e + 4102 .git/objects/9b/c1dc421dcd51b4ac296e3e5b6e2a99cf44391e 피일을 수정하면 어떻게 되는지 살펴보자: @@ -469,10 +469,10 @@ Git은 zlib으로 파일 내용을 압축하기 때문에 저장 공간이 많 이 Blob 개체는 다른 개체다. 새 Blob 개체는 400줄 이후에 한 줄을 더 추가한 새 개체이다. Git은 완전히 새로운 Blob 개체를 만들어 저장한다: - $ git cat-file -s 05408d195263d853f09dca71d55116663690c27c - 12908 + $ du -b .git/objects/05/408d195263d853f09dca71d55116663690c27c + 4109 .git/objects/05/408d195263d853f09dca71d55116663690c27c -그럼 약 12K짜리 파일이 두 개나 생긴다. 거의 같은 파일이 두 개나 있는 것이 좀 못마땅하다. 처음 것과 두 번째 것 사이의 차이만 저장할 수 없을까? +그럼 약 4K짜리 파일을 두 개 가지게 된다. 거의 같은 파일을 두 개나 가지게 되는 것이 못마땅할 수도 있다. 처음 것과 두 번째 것 사이의 차이점만 저장할 수 없을까? 가능하다. Git이 처음 개체를 저장하는 형식은 Loose 개체 포멧이라고 부른다. 하지만 나중에 이 개체를 파일 하나로 압축(Pack)할 수 있다. 그래서 공간을 절약하고 효율을 높일 수 있다. Git이 이렇게 압축하는 때는 Loose 개체가 너무 많거나, `git gc` 명령을 실행했을 때, 그리고 리모트 서버로 Push할 때 압축한다. `git gc` 명령을 실행해서 어떻게 압축하는지 살펴보자: @@ -494,7 +494,7 @@ Git은 zlib으로 파일 내용을 압축하기 때문에 저장 공간이 많 압축되지 않은 Blob 개체는 어떤 커밋도 가리키지 않는 개체다. 즉, "what is up, doc?"과 "test content" 예제에서 만들었던 개체이다. 어떤 커밋에도 추가돼 있지 않으면 이 개체는 `dangling` 개체로 취급되고 Packfile에 추가되지 않는다. -새로 생긴 파일은 Packfile과 그 Index이다. 파일 시스템에서 삭제된 개체가 전부 이 Packfile에 저장된다. Index 파일은 빠르게 찾을 수 있도록 Packfile의 오프셋이 들어 있다. `git gc` 명령을 실행하기 전에 있던 파일 크기는 약 12K 정도였었는데 새로 만들어진 Packfile은 겨우 6K에 불과하다. 짱이다. 개체를 압축해서 디스크 사용량을 절반으로 줄였다. +새로 생긴 파일은 Packfile과 그 Index이다. 파일 시스템에서 삭제된 개체가 전부 이 Packfile에 저장된다. Index 파일은 빠르게 찾을 수 있도록 Packfile의 오프셋이 들어 있다. `git gc` 명령을 실행하기 전에 있던 파일 크기는 약 8K 정도였었는데 새로 만들어진 Packfile은 겨우 4K에 불과하다. 짱이다. 개체를 압축하면 디스크 사용량은 절반으로 줄었다. 어떻게 이런 일이 가능할까? 개체를 압축하면 Git은 먼저 이름이나 크기가 비슷한 파일을 찾는다. 그리고 두 파일을 비교해서 한 파일은 다른 부분만 저장한다. Git이 얼마나 공간을 절약해 주는지 Packfile을 열어 확인할 수 있다. `git verify-pack` 명령어는 압축한 내용을 보여준다: From 12255b973e27c607045a8ee33e4b61310eb419ee Mon Sep 17 00:00:00 2001 From: Changwoo Park Date: Thu, 7 Nov 2013 23:16:58 +0900 Subject: [PATCH 033/862] [ko] update translation. Conflicts: ko/03-git-branching/01-chapter3.markdown ko/04-git-server/01-chapter4.markdown ko/07-customizing-git/01-chapter7.markdown --- ko/03-git-branching/01-chapter3.markdown | 12 +- ko/04-git-server/01-chapter4.markdown | 84 ++++++------- ko/05-distributed-git/01-chapter5.markdown | 18 +-- ko/06-git-tools/01-chapter6.markdown | 12 +- ko/07-customizing-git/01-chapter7.markdown | 111 +++++++++--------- ko/08-git-and-other-scms/01-chapter8.markdown | 2 +- 6 files changed, 121 insertions(+), 118 deletions(-) diff --git a/ko/03-git-branching/01-chapter3.markdown b/ko/03-git-branching/01-chapter3.markdown index aede41a06..a9cc52748 100644 --- a/ko/03-git-branching/01-chapter3.markdown +++ b/ko/03-git-branching/01-chapter3.markdown @@ -242,7 +242,7 @@ Git은 자동으로 Merge하지 못해서 새 커밋이 생기지 않는다. 변 # unmerged: index.html # -충돌이 일어난 파일은 unmerged 상태로 표시된다. Git은 충돌이 난 부분을 표준 형식에 따라 표시해준다. 그러면 개발자는 해당 부분을 수동으로 해결한다. 충돌 난 부분은 다음과 같이 표시된다: +충돌이 일어난 파일은 unmerged 상태로 표시된다. Git은 충돌이 난 부분을 표준 형식에 따라 표시해준다. 그러면 개발자는 해당 부분을 수동으로 해결한다. 충돌 난 부분은 다음과 같이 표시된다. <<<<<<< HEAD:index.html @@ -357,7 +357,7 @@ Insert 18333fig0318.png Insert 18333fig0319.png 그림 3-19 각 브랜치를 하나의 실험실로 생각하라 -코드를 여러 단계로 나누고 안정성을 높이면서 운영해 갈 수 있다. 큰 규모의 프로젝트라면 proposed 혹은 pu(proposed updates)라는 이름의 브랜치를 두어 next나 master 브랜치에 아직 Merge할 준비가 되지 않은 것을 일단 Merge시킨다. +코드를 여러 단계로 나누어 안정성을 높여가며 운영할 수 있다. 큰 규모의 프로젝트라면 proposed 혹은 pu(proposed updates)라는 이름의 브랜치를 두어 next나 master 브랜치에 아직 Merge할 준비가 되지 않은 것을 일단 Merge시킨다. 중요한 개념은 브랜치를 이용해 여러 단계에 걸쳐서 안정화해 나아가면서 충분히 안정화가 됐을 때 안정 브랜치로 Merge한다는 점이다. 다시 말해서 반드시 Long-Running의 브랜치를 여러 개 만들어야 하는 것은 아니지만 정말 유용하다. 특히 규모가 크고 복잡한 프로젝트일수록 그 유용성이 반짝반짝 빛난다. @@ -426,7 +426,7 @@ serverfix라는 브랜치를 다른 사람과 공유할 때에도 브랜치를 To git@github.com:schacon/simplegit.git * [new branch] serverfix -> serverfix -이 메시지에는 여러가지 의미가 숨겨져 있다. +이 메시지에는 숨겨진 내용이 많다. Git은 serverfix라는 브랜치 이름을 `refs/heads/serverfix:refs/heads/serverfix`로 확장한다. 이것은 serverfix라는 로컬 브랜치를 서버로 Push하는데 리모트의 serverfix 브랜치로 업데이트한다는 것을 의미한다. 나중에 *9장*에서 `refs/heads/`의 뜻을 자세히 알아볼 것이기 때문에 일단 넘어가도록 한다. `git push origin serverfix:serverfix`라고 Push하는 것도 같은 의미인데 이것은 '로컬의 serverfix 브랜치를 리모트 저장소의 serverfix 브랜치로 Push하라'라는 뜻이다. 로컬 브랜치의 이름과 리모트 서버의 브랜치 이름이 다를 때 필요하다. 리모트 저장소에 serverfix라는 이름 대신 다른 이름을 사용하려면 `git push origin serverfix:awesomebranch`처럼 사용한다. @@ -440,7 +440,7 @@ Git은 serverfix라는 브랜치 이름을 `refs/heads/serverfix:refs/heads/serv From git@github.com:schacon/simplegit * [new branch] serverfix -> origin/serverfix -여기서 짚고 넘어가야 할 게 있다. Fetch 명령으로 리모트 브랜치를 내려받는다고 해서 로컬 저장소에 수정할 수 있는 브랜치가 새로 생기는 것이 아니다. 다시 말해서 serverfix라는 브랜치가 생기는 것이 아니라 그저 수정 못 하는 origin/serverfix 브랜치 포인터가 생기는 것이다. +여기서 짚고 넘어가야 할 게 있다. Fetch 명령으로 리모트 브랜치를 내려받는다고 해서 로컬 저장소에 수정할 수 있는 브랜치가 새로 생기는 것이 아니다. 다시 말해서 serverfix라는 브랜치가 생기는 것이 아니라 그저 수정 못 하는 origin/serverfix 브랜치 포인터가 생기는 것이다. 새로 받은 브랜치의 내용을 Merge하려면 `git merge origin/serverfix` 명령을 사용한다. Merge하지 않고 리모트 브랜치에서 시작하는 새 브랜치를 만들려면 아래와 같은 명령을 사용한다. @@ -513,7 +513,7 @@ Insert 18333fig0329.png Insert 18333fig0330.png 그림 3-30 master 브랜치를 Fast-forward시키기 -C3'로 표시된 커밋에서의 내용은 Merge 예제에서 살펴본 C5 커밋에서의 내용과 같을 것이다. Merge이든 Rebase든 둘 다 합치는 관점에서는 서로 다를 게 없다. 하지만, Rebase가 좀 더 깨끗한 히스토리를 만든다. Rebase한 브랜치의 Log를 살펴보면 히스토리가 선형적이다. 일을 병렬로 동시에 진행해도 Rebase하고 나면 모든 작업이 차례대로 수행된 것처럼 보인다. +C3'로 표시된 커밋에서의 내용은 Merge 예제에서 살펴본 C5 커밋에서의 내용과 같을 것이다. Merge이든 Rebase든 둘 다 합치는 관점에서는 서로 다를 게 없다. 하지만, Rebase가 좀 더 깨끗한 히스토리를 만든다. Rebase한 브랜치의 Log를 살펴보면 히스토리가 선형적이다. 일을 병렬로 동시에 진행해도 Rebase하고 나면 모든 작업이 차례대로 수행된 것처럼 보인다. Rebase는 보통 리모트 브랜치에 커밋을 깔끔하게 적용하고 싶을 때 사용한다. 아마 이렇게 Rebase하는 리모트 브랜치는 직접 관리하는 것이 아니라 그냥 참여하는 브랜치일 것이다. 메인 프로젝트에 패치를 보낼 준비가 되면 하는 것이 Rebase이니까 브랜치에서 하던 일을 완전히 마치고 origin/master로 Rebase한다. 프로젝트 관리자는 어떠한 통합작업도 필요 없다. 그냥 master 브랜치를 Fast-forward 시키면 된다. @@ -571,7 +571,7 @@ Rebase가 장점이 많은 기능이지만 단점이 없는 것은 아니니 조 **이미 공개 저장소에 Push한 커밋을 Rebase하지 마라** -이 지침만 지키면 Rebase를 하는 데 문제 될 게 없다. 하지만, 이 주의사항을 지키지 않으면 사람들에게 욕을 먹을 것이다(역주 - 아마도 가카의 호연지기가 필요해질 것이다). +이 지침만 지키면 Rebase를 하는 데 문제 될 게 없다. 하지만, 이 주의사항을 지키지 않으면 사람들에게 욕을 먹을 것이다(역주 - 아마도 가카의 호연지기가 필요해질 것이다). Rebase는 기존의 커밋을 그대로 사용하는 것이 아니라 내용은 같지만 다른 커밋을 새로 만든다. 새 커밋을 서버에 Push하고 동료 중 누군가가 그 커밋을 Pull해서 작업을 한다고 하자. 그런데 그 커밋을 `git rebase`로 바꿔서 Push해버리면 동료가 다시 Push했을 때 동료는 다시 Merge해야 한다. 그리고 동료가 다시 Merge한 내용을 Pull하면 내 코드는 정말 엉망이 된다. diff --git a/ko/04-git-server/01-chapter4.markdown b/ko/04-git-server/01-chapter4.markdown index 253e5866c..043d5be67 100644 --- a/ko/04-git-server/01-chapter4.markdown +++ b/ko/04-git-server/01-chapter4.markdown @@ -54,8 +54,8 @@ SSH를 통해 Git 저장소를 Clone하려면 `ssh://`로 시작하는 URL을 $ git clone ssh://user@server/project.git -아래와 같이 프로토콜 이름을 명시하지 않고도 SSH를 사용할 수 있다: - +아니면 scp 명령어처럼 사용할 수 있다. 이게 조금 더 짧다: + $ git clone user@server:project.git 사용자 계정을 생략할 수도 있는데 계정을 생략하면 Git은 현재 로그인한 사용자의 계정을 사용한다. @@ -141,7 +141,7 @@ Bare 저장소는 이제 만들었으니까 서버에 넣고 프로토콜을 설 $ cd /opt/git/my_project.git $ git init --bare --shared -Git 저장소를 만드는 것이 얼마나 쉬운지 살펴보았다. Bare 저장소를 만들어 SSH로 접근할 수 있는 서버에 올리면 동료와 함께 일할 준비가 끝난다. +Git 저장소를 만드는 것이 얼마나 쉬운지 살펴보았다. Bare 저장소를 만들어 SSH로 접근할 수 있는 서버에 올리면 동료와 함께 일할 준비가 끝난다. 그러니까 Git 서버를 구축하는데 사람이 할 일은 정말 별로 없다. SSH로 접속할 수 있도록 서버에 계정을 만들고 Bare 저장소를 사람들이 읽고 쓸 수 있는 곳에 넣어 두기만 하면 된다. 다른 것은 아무것도 필요 없다. @@ -172,11 +172,11 @@ Git 저장소를 만드는 것이 얼마나 쉬운지 살펴보았다. Bare 저 something, something.pub이라는 형식으로 된 파일을 볼 수 있다. something은 보통 `id_dsa`나 `id_rsa`라고 돼 있다. 그중 `.pub`파일이 공개키이고 다른 파일은 개인키이다. 만약 이 파일이 없거나 `.ssh` 디렉토리도 없으면 `ssh-keygen`이라는 프로그램으로 키를 생성해야 한다. `ssh-keygen` 프로그램은 리눅스나 Mac의 SSH 패키지에 포함돼 있고 윈도는 MSysGit 패키지 안에 들어 있다: - $ ssh-keygen + $ ssh-keygen Generating public/private rsa key pair. - Enter file in which to save the key (/Users/schacon/.ssh/id_rsa): - Enter passphrase (empty for no passphrase): - Enter same passphrase again: + Enter file in which to save the key (/Users/schacon/.ssh/id_rsa): + Enter passphrase (empty for no passphrase): + Enter same passphrase again: Your identification has been saved in /Users/schacon/.ssh/id_rsa. Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub. The key fingerprint is: @@ -186,7 +186,7 @@ something, something.pub이라는 형식으로 된 파일을 볼 수 있다. som 사용자는 그 다음에 자신의 공개기를 Git 서버 관리자에게 보내야 한다. 사용자는 `.pub` 파일의 내용을 복사하여 메일을 보내기만 하면 된다. 공개키는 아래와 같이 생겼다: - $ cat ~/.ssh/id_rsa.pub + $ cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3 Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA @@ -270,7 +270,7 @@ something, something.pub이라는 형식으로 된 파일을 볼 수 있다. som 익명의 사용자에게 읽기 접근을 허용하고 싶을 때는 어떻게 해야 할까? 프로젝트를 비공개가 아니라 오픈 소스 프로젝트로 공개한다거나 자동 빌드 서버나 CI(Continuous Integration) 서버가 많아서 계정마다 하나하나 설정해야 할 수 있다. 아니면 그냥 매번 SSH 키를 생성하는 게 귀찮을 수도 있다. 그러니까 그냥 간단하게 익명의 사용자도 읽을 수 있도록 하고 싶을 때는 어떻게 해야 할까? -분병 웹 서버를 설치하는 것이 가장 쉬운 방법이다. 이 장의 첫 부분에 설명했듯이 웹 서버를 설치하고 Git 저장소를 문서 루트 디렉토리에 두고 `post-update` 훅을 켜기만 하면 된다. 먼저 설명했던 예제를 따라 해보자. `/opt/git` 디렉토리에 저장소가 있고 서버에 Apache가 설치돼 있다고 가정하자. 아무 웹 서버나 다 사용할 수 있지만, 이 예제에서는 Apache를 사용한다. 여기에서는 이해하는 것이 목적이므로 아주 기본적인 Apache 설정만을 보여줄 것이다. +분명 웹 서버를 설치하는 것이 가장 쉬운 방법이다. 이 장의 첫 부분에 설명했듯이 웹 서버를 설치하고 Git 저장소를 문서 루트 디렉토리에 두고 `post-update` 훅을 켜기만 하면 된다. 먼저 설명했던 예제를 따라 해보자. `/opt/git` 디렉토리에 저장소가 있고 서버에 Apache가 설치돼 있다고 가정하자. 아무 웹 서버나 다 사용할 수 있지만, 이 예제에서는 Apache를 사용한다. 여기에서는 이해하는 것이 목적이므로 아주 기본적인 Apache 설정만을 보여줄 것이다. 먼저 이 훅을 설정해야 한다: @@ -280,7 +280,7 @@ something, something.pub이라는 형식으로 된 파일을 볼 수 있다. som `post-update` 훅은 무슨 일을 할까? 기본적으로 다음과 같다: - $ cat .git/hooks/post-update + $ cat .git/hooks/post-update #!/bin/sh exec git-update-server-info @@ -297,7 +297,7 @@ SSH를 통해서 서버에 Push하면 Git은 이 명령어를 실행하여 HTTP -그리고 Apache 서버는 `www-data` 권한으로 CGI 스크립트를 실행시키기 때문에 `/opt/git` 디렉토리의 그룹 소유 권한을 `www-data`로 수정해 주어야 웹 서버로 접근하는 사용자들이 읽을 수 있다. +그리고 Apache 서버는 `www-data` 권한으로 CGI 스크립트를 실행시키기 때문에 `/opt/git` 디렉토리의 그룹 소유 권한을 `www-data`로 수정해 주어야 웹 서버로 접근하는 사용자들이 읽을 수 있다. $ chgrp -R www-data /opt/git @@ -311,7 +311,7 @@ Apache를 재시작하면 아래와 같은 URL로 저장소를 Clone할 수 있 프로젝트 저장소를 단순히 읽거나 쓰는 것에 대한 설정은 다뤘다. 이제는 웹 기반 인터페이스를 설정해보자. Git에는 GitWeb이라는 CGI 스크립트를 제공해서 쉽게 웹에서 저장소를 조회하도록 할 수 있다. `http://git.kernel.org`같은 사이트에서 GitWeb을 구경할 수 있다(그림 4-1). -Insert 18333fig0401.png +Insert 18333fig0401.png 그림 4-1 Git 웹용 UI, GitWeb Git은 GitWeb을 쉽게 사용해 볼 수 있도록 서버를 잠시 띄우는 명령을 제공한다. 시스템에 `lighttpd`나 `webrick` 같은 경량 웹서버가 설치돼 있어야 이 명령을 사용할 수 있다. 리눅스에서는 `lighttpd`가 설치돼 있을 확률이 높고 프로젝트 디렉토리에서 그냥 `git instaweb`을 실행하면 바로 실행된다. Mac의 Leopard 버전은 Ruby가 미리 설치돼 있기 때문에 `webrick`이 더 낫다. lighttpd이 아니라면 아래와 같이 `--httpd` 옵션을 사용해야 한다: @@ -329,7 +329,7 @@ Git은 GitWeb을 쉽게 사용해 볼 수 있도록 서버를 잠시 띄우는 $ git clone git://git.kernel.org/pub/scm/git/git.git $ cd git/ $ make GITWEB_PROJECTROOT="/opt/git" \ - prefix=/usr gitweb + prefix=/usr gitweb/gitweb.cgi $ sudo cp -Rf gitweb /var/www/ 빌드할 때 `GITWEB_PROJECTROOT` 변수로 Git 저장소의 위치를 알려줘야 한다. 이제 Apache가 이 스크립트를 사용하도록 VirtualHost 항목을 설정한다: @@ -417,7 +417,7 @@ Gitosis가 키들을 관리할 것이기 때문에 현재 파일은 삭제하고 이제 `gitosis.conf` 파일을 열어보자. 지금 막 Clone한 `gitosis-admin` 프로젝트에 대한 정보만 들어 있다: - $ cat gitosis.conf + $ cat gitosis.conf [gitosis] [group gitosis-admin] @@ -604,10 +604,10 @@ Gitolite는 접근 제어를 두 단계로 한다. 첫 단계가 저장소 단 브랜치 단위로 Push를 제어할 수 있지만 수정된 파일 단위로도 제어할 수 있다. 예를 들어 Makefile을 보자. Makefile 파일에 의존하는 파일은 매우 많고 보통 *꼼꼼하게* 수정하지 않으면 문제가 생긴다. 그래서 아무나 Makefile을 수정하게 둘 수 없다. 그러면 아래와 같이 설정한다: - repo foo - RW = @junior_devs @senior_devs + repo foo + RW = @junior_devs @senior_devs - - VREF/NAME/Makefile = @junior_devs + - VREF/NAME/Makefile = @junior_devs 예전 버전의 Gitolite에서 버전을 올리려는 사용자는 설정이 많이 달라진 것을 알게 될 것이다. Gitolite의 버전업 가이드를 필히 참고하자. @@ -633,15 +633,15 @@ Gitolite는 펄 정규표현식으로 저장소 이름을 표현하기 때문에 **접근 권한 보여주기**: 만약 어떤 서버에서 작업을 시작하려고 할 때 필요한 것이 무엇일까? Gitolite는 해당 서버에 대해 접근할 수 있는 저장소가 무엇인지, 어떤 권한을 가졌는지 보여준다: - hello scott, this is git@git running gitolite3 v3.01-18-g9609868 on git 1.7.4.4 + hello scott, this is git@git running gitolite3 v3.01-18-g9609868 on git 1.7.4.4 - R anu-wsd - R entrans - R W git-notes - R W gitolite - R W gitolite-admin - R indic_web_input - R shreelipi_converter + R anu-wsd + R entrans + R W git-notes + R W gitolite + R W gitolite-admin + R indic_web_input + R shreelipi_converter **권한 위임**: 조직 규모가 크면 저장소에 대한 책임을 여러 사람이 나눠 가지는 게 좋다. 여러 사람이 각자 맡은 바를 관리하도록 한다. 그래서 주요 관리자의 업무가 줄어들기에 병목현상이 적어진다. 이 기능에 대해서는 `doc/` 디렉토리에 포함된 Gitolite 문서를 참고하라. @@ -713,7 +713,7 @@ Gitosis 설정 파일에 `gitweb` 설정을 넣거나 빼면 사용자는 GitWeb ## Hosted Git ## -Git 서버를 설치하는 등의 일을 하고 싶지 않으면 전문 호스팅 사이트를 이용하면 된다. 호스팅 사이트는 몇 가지 장점이 있다. 설정이 쉬워서 바로 프로젝트를 시작할 수 있을 뿐만 아니라 직접 서버를 관리하고 모니터링하지 않아도 된다. 내부적으로 Git 서버를 직접 설치하고 운영하고 있어도 오픈소스 프로젝트는 호스팅 사이트를 이용하는 것이 좋다. 이렇게 하면 보통 오픈소스 커뮤니티로부터 좀 더 쉽게 도움받을 수 있다. +Git 서버를 설치하는 등의 일을 하고 싶지 않으면 전문 호스팅 사이트를 이용하면 된다. 호스팅 사이트는 몇 가지 장점이 있다. 설정이 쉬워서 바로 프로젝트를 시작할 수 있을 뿐만 아니라 직접 서버를 관리하고 모니터링하지 않아도 된다. 내부적으로 Git 서버를 직접 설치하고 운영하고 있어도 오픈소스 프로젝트는 호스팅 사이트를 이용하는 것이 좋다. 이렇게 하면 보통 오픈소스 커뮤니티로부터 좀 더 쉽게 도움받을 수 있다. 요즘은 이용할 수 있는 호스팅 사이트들이 많다. 각각 장단점이 있기 때문에 다음 페이지에서 최신 정보를 확인해보자: @@ -731,19 +731,19 @@ GitHub은 이윤을 목적으로 하는 회사이기 때문에 비공개 저장 ### 계정 설정하기 ### -먼저 무료 계정을 하나 만든다. 가격 정책에 대해 알려주며 가입을 시작할 수 있는 `http://github.com/plans`에 방문하여 "Sign up" 버튼을 클릭한다. 그러면 가입 페이지로 이동한다. +먼저 무료 계정을 하나 만든다. 가격 정책에 대해 알려주며 가입을 시작할 수 있는 `http://github.com/plans`에 방문하여 "Sign up" 버튼을 클릭한다. 그러면 가입 페이지로 이동한다. Insert 18333fig0402.png 그림 4-2 GitHub 가격 정책 페이지 아직 등록되지 않은 사용자 이름을 입력하고 e-mail 주소와 암호를 입력한다(그림 4-3). -Insert 18333fig0403.png +Insert 18333fig0403.png 그림 4-3 GitHub 가입 폼 그리고 SSH 공개키가 있으면 바로 등록한다. SSH 키를 만드는 방법은 "바로 설정하기" 절에서 이미 설명했다. 그 공개키 파일의 내용을 복사해서 SSH 공개키 입력 박스에 붙여 넣는다. "explain ssh keys" 링크를 클릭하면 key를 생성하는 방법을 자세히 설명해준다. 주요 운영체제에서 하는 방법이 모두 설명돼 있다. "I agree, sign me up" 버튼을 클릭하면 자신만의 대쉬보드 페이지가 나타난다. -Insert 18333fig0404.png +Insert 18333fig0404.png 그림 4-4 GitHub 사용자 대쉬보드 그리고 저장소를 만들자. @@ -752,17 +752,17 @@ Insert 18333fig0404.png `Your Repositories`옆에 있는 "create a new one" 링크를 클릭하면 저장소를 만드는 입력 폼을 볼 수 있다(그림 4-5). -Insert 18333fig0405.png +Insert 18333fig0405.png 그림 4-5 GitHub의 저장소를 생성하는 폼 이 폼에 프로젝트 이름과 프로젝트 설명을 적는다. 다 적은 후에 "Create Repository" 버튼을 클릭하면 GitHub에 저장소가 생긴다. -Insert 18333fig0406.png +Insert 18333fig0406.png 그림 4-6 GitHub 프로젝트 정보 이 저장소에는 아직 코드가 없어서 GitHub은 프로젝트를 새로 만드는 방법, 이미 있는 Git 프로젝트를 Push하는 법, 공개된 Subversion 저장소에서 프로젝트를 가져오는(Import) 방법 등을 보여준다. -Insert 18333fig0407.png +Insert 18333fig0407.png 그림 4-7 새 저장소를 위한 사용설명서 여기 설명하는 내용은 이미 우리가 배웠다. 프로젝트가 없을 때는 아래와 같이 프로젝트를 초기화한다: @@ -773,12 +773,12 @@ Insert 18333fig0407.png 만약 이미 로컬에 Git 저장소가 있으면 GitHub 저장소를 리모트 저장소로 등록하고 master 브랜치를 Push한다: - $ git remote add origin git@github.com:testinguser/iphone_project.git + $ git remote add origin git@GitHub.com:testinguser/iphone_project.git $ git push origin master 이제 프로젝트가 GitHub에서 서비스되니 공유하고 싶은 사람에게 URL을 알려 주면 된다. URL은 `http://github.com/testinguser/iphone_project`이다. 그리고 이 저장소의 정보를 잘 살펴보면 Git URL이 두 개라는 것을 발견할 수 있다. -Insert 18333fig0408.png +Insert 18333fig0408.png 그림 4-8 프로젝트의 공개 URL과 비공개 URL `Public Clone URL`은 말 그대로 누구나 프로젝트를 Clone할 수 있도록 모두에게 읽기 전용으로 공개하는 것이다. 이 URL을 다른 사람에 알려주거나 웹사이트 같은데 공개하는 것을 부담스러워 하지 않아도 된다. @@ -789,23 +789,23 @@ Insert 18333fig0408.png GitHub은 공개 중인 Subversion 프로젝트를 Git 프로젝트로 만들어 준다. 사용설명서 하단에 있는 "Subversion에서 Import하기" 링크를 클릭하면 임포트 폼을 볼 수 있고 거기에 Subversion 프로젝트의 URL을 넣는다(그림 4-9). -Insert 18333fig0409.png +Insert 18333fig0409.png 그림 4-9 Subversion 프로젝트를 Import하는 화면 프로젝트가 비표준 방식을 사용하거나 규모가 너무 크고 비공개라면 이 기능을 사용할 수 없다. *7장*에서 수동으로 임포트하는 방법에 대해 좀 더 자세히 배운다. ### 동료 추가하기 ### -동료를 추가하자. 먼저 John씨, Josie씨, Jessica씨를 모두 GitHub에 가입시키고 나서 그들을 동료로 추가하고 저장소에 Push할 수 있는 권한을 준다. +동료를 추가하자. 먼저 John씨, Josie씨, Jessica씨를 모두 GitHub에 가입시키고 나서 그들을 동료로 추가하고 저장소에 Push할 수 있는 권한을 준다. 프로젝트 페이지에 있는 Admin 버튼을 클릭해서 관리 페이지로 이동한다(그림 4-10). -Insert 18333fig0410.png +Insert 18333fig0410.png 그림 4-10 GitHub의 프로젝트 관리 페이지 다른 사람에게 쓰기 권한을 주려면 “Add another collaborator” 링크를 클릭한다. 그러면 텍스트 박스가 새로 나타나는 데 거기에 사용자 이름을 입력한다. 사용자 이름을 입력하기 시작하면 자동으로 시스템에 존재하는 사용자를 찾아서 보여 준다. 원하는 사용자를 찾으면 Add 버튼을 클릭해서 그 사용자를 동료로 만든다. -Insert 18333fig0411.png +Insert 18333fig0411.png 그림 4-11 프로젝트에 동료 추가하기 추가한 사람은 동료 목록 박스에서 모두 확인할 수 있다(그림 4-12). @@ -819,7 +819,7 @@ Insert 18333fig0412.png Subversion에서 Import했거나 로컬의 프로젝트를 Push하고 나면 프로젝트 메인 페이지가 그림 4-13같이 바뀐다. -Insert 18333fig0413.png +Insert 18333fig0413.png 그림 4-13 GitHub의 프로젝트 메인 페이지 사람들이 이 프로젝트에 방문하면 이 페이지가 제일 처음 보인다. 이 페이지는 몇 가지 탭으로 구성된다. Commits 탭은 지금까지의 커밋을 `git log` 명령을 실행시킨 것처럼 최신 것부터 보여준다. Network 탭은 프로젝트를 복제한 사람들과 기여한 사람들을 모두 보여준다. Downloads 탭에는 바이너리 파일이나 프로젝트의 태그 버전을 압축해서 올릴 수 있다. Wiki 탭은 프로젝트에 대한 정보나 문서를 쓰는 곳이다. Graphs 탭은 사람들의 활동을 그림과 통계로 보여준다. 메인 탭인 Source 탭은 프로젝트의 메인 디렉토리를 보여주고 README 파일이 있으면 자동으로 화면에 출력해 준다. 그리고 마지막 커밋 내용도 함께 보여준다. @@ -832,12 +832,12 @@ Insert 18333fig0413.png 프로젝트 페이지에 들어가서 상단의 "fork" 버튼을 클릭하여 프로젝트를 복제한다(그림 4-14) 그림 4-14의 예는 mojombo/chronic 프로젝트 페이지이다 -Insert 18333fig0414.png +Insert 18333fig0414.png 그림 4-14 어떤 저장소든지 "fork" 버튼을 클릭하면 Push할 수 있는 저장소를 얻을 수 있다 -클릭하는 순간, 이 프로젝트를 즉시 Fork한다(그림 4-15). +클릭하는 순간, 이 프로젝트를 즉시 Fork한다(그림 4-15). -Insert 18333fig0415.png +Insert 18333fig0415.png 그림 4-15 Fork한 프로젝트 ### GitHub 요약 ### diff --git a/ko/05-distributed-git/01-chapter5.markdown b/ko/05-distributed-git/01-chapter5.markdown index 79a6dff8b..5bf630702 100644 --- a/ko/05-distributed-git/01-chapter5.markdown +++ b/ko/05-distributed-git/01-chapter5.markdown @@ -85,19 +85,19 @@ Insert 18333fig0503.png 마지막으로 명심해야 할 점은 커밋 메시지 자체다. 좋은 커밋 메시지를 작성하는 습관은 Git을 사용하는 데 도움이 많이 된다. 일반적으로 커밋 메시지를 작성할 때 사용하는 규칙이 있다. 메시지의 첫 줄에 50자가 넘지 않는 아주 간략한 메시지를 적어 해당 커밋을 요약한다. 다음 한 줄은 비우고 그다음 줄부터 커밋을 자세히 설명한다. 예를 들어 Git 개발 프로젝트에서는 개발 동기와 구현 상황의 제약조건이나 상황 등을 자세하게 요구한다. 이런 점은 따를 만한 좋은 가이드라인이다. 그리고 현재형 표현을 사용하는 것이 좋다. 예를 들어 "I added tests for (테스트를 추가함)" 보다는 "Add tests for (테스트 추가)" 와 같은 메시지를 작성한다. 아래 예제는 Pope at tpope.net이 작성한 커밋 메시지이다. - 영문 50글자 이하의 간략한 수정 요약 + 영문 50글자 이하의 간략한 수정 요약 - 자세한 설명. 영문 72글자 이상이 되면 줄 바꿈을 하고 이어지는 내용을 - 작성한다. 특정 상황에서는 첫 번째 줄이 이메일 메시지의 제목이 되고 - 나머지는 메일 내용이 된다. 간략하게 요약하고 넣는 빈 줄은 자세한 - 설명을 아예 쓰지 않는 한 매우 중요하다. + 자세한 설명. 영문 72글자 이상이 되면 줄 바꿈을 하고 이어지는 내용을 + 작성한다. 특정 상황에서는 첫 번째 줄이 이메일 메시지의 제목이 되고 + 나머지는 메일 내용이 된다. 간략하게 요약하고 넣는 빈 줄은 자세한 + 설명을 아예 쓰지 않는 한 매우 중요하다. - 이어지는 내용도 한 줄 띄우고 쓴다. + 이어지는 내용도 한 줄 띄우고 쓴다. - - 목록 표시도 사용할 수 있다. + - 목록 표시도 사용할 수 있다. - - 보통 '-' 나 '*' 표시를 사용해서 목록을 표현하고 표시 앞에 공백 - 하나, 각 목록 사이에는 빈 줄을 하나를 넣는데 상황에 따라 다르다. + - 보통 '-' 나 '*' 표시를 사용해서 목록을 표현하고 표시 앞에 공백 + 하나, 각 목록 사이에는 빈 줄을 하나를 넣는데 상황에 따라 다르다. 메시지를 이렇게 작성하면 함께 일하는 사람은 물론이고 자신에게도 매우 유용하다. Git 개발 프로젝트에는 잘 쓰인 커밋 메시지가 많으므로 프로젝트를 내려받아서 `git log --no-merges` 명령으로 꼭 살펴보기를 권한다. diff --git a/ko/06-git-tools/01-chapter6.markdown b/ko/06-git-tools/01-chapter6.markdown index 0bac5d29a..20042ea1e 100644 --- a/ko/06-git-tools/01-chapter6.markdown +++ b/ko/06-git-tools/01-chapter6.markdown @@ -488,18 +488,18 @@ Git은 Stash를 적용할 때 Staged 상태였던 파일을 자동으로 다시 Stash를 적용하고 나서 아차 싶을 때에는 다시 되돌려 놓아야 한다. Git은 `stash unapply` 같은 명령을 제공하지는 않는다. 하지만, Stash를 이용해서 패치를 만들고 그것을 거꾸로 적용할 수 있다: - $ git stash show -p stash@{0} | git apply -R + $ git stash show -p stash@{0} | git apply -R Stash를 명시하지 않으면 Git은 가장 최근의 Stash를 사용한다: - $ git stash show -p | git apply -R + $ git stash show -p | git apply -R `stash-unapply`라는 alias를 만들고 편리하게 할 수도 있다: - $ git config --global alias.stash-unapply '!git stash show -p | git apply -R' - $ git stash - $ #... work work work - $ git stash-unapply + $ git config --global alias.stash-unapply '!git stash show -p | git apply -R' + $ git stash + $ #... work work work + $ git stash-unapply ### Stash를 적용한 브랜치 만들기 ### diff --git a/ko/07-customizing-git/01-chapter7.markdown b/ko/07-customizing-git/01-chapter7.markdown index b5662e4be..3c4f1fe1a 100644 --- a/ko/07-customizing-git/01-chapter7.markdown +++ b/ko/07-customizing-git/01-chapter7.markdown @@ -189,7 +189,7 @@ Git config 파일에 이 스크립트를 모두 추가한다. 설정해야 하 diff 결과가 터미널에 출력되는 대신 P4Merge가 실행된다. 그리고 그림 7-1처럼 그 프로그램 안에서 보여준다: -Insert 18333fig0701.png +Insert 18333fig0701.png 그림 7-1 P4Merge 브랜치를 Merge할 때 충돌이 나면 `git mergetool` 명령을 실행한다. 이 명령을 실행하면 GUI 도구로 충돌을 해결할 수 있도록 P4Merge를 실행해준다. @@ -307,11 +307,15 @@ Git은 Push할 때 기본적으로 개체를 검증하지(check for consistency) #### 바이너리 파일 Diff하기 #### -Git은 바이너리 파일도 diff할 수 있다. 이 Attribute는 바이너리 파일을 텍스트 포맷으로 변환하고 그 결과를 diff로 비교하도록 하는 것이다. +Git은 바이너리 파일도 diff할 수 있다. Git Attribute를 통해 Git이 바이너리 파일을 텍스트 포맷으로 변환하고 그 결과를 diff로 비교하도록 하는 것이다. 그래서 문제는 어떻게 *바이너리*를 텍스트로 변환해야 할까에 있다. 바이너리를 텍스트로 변환해 주는 도구 중에서 내가 필요한 바이너리 파일에 꼭 맞는 도구를 찾는게 가장 좋다. 사람이 읽을 수 있는 텍스트로 표현된 바이너리 포맷은 극히 드물다(오디오 데이터를 텍스트로 변환한다고 생각해보라). 파일 내용을 텍스트로 변환할 방법을 찾지 못했을 때는 파일의 설명이나 메타데이터를 텍스트로 변환하는 방법을 찾아보자. 이런 방법이 가능한 경우가 많다. 메타데이터는 파일 내용을 완벽하게 알려주지 않지만 전혀 비교하지 못하는 것보다 이렇게라도 하는 게 훨씬 낫다. + +여기서 설명한 두 가지 방법을 많이 사용하는 바이너리 파일에 적용해 볼 거다. + +댓글: 전용 변환기는 없지만 텍스트가 들어 있는 바이너리 포맷들이 있다. 이런 포맷은 `strings` 프로그램으로 바이너리 파일에서 텍스트를 추출한다. 이런 종류의 바이너리 파일 중에서 UTF-16 인코딩이나 다른 "codepages"로 된 파일들도 있다. 그런 인코딩으로 된 파일에서 `strings`으로 추출할 수 있는 텍스트는 제한적이다. 상황에 따라 다르게 추출된다. 그래도 `strings`는 Mac과 Linux 시스템에서 쉽게 사용할 수 있기 때문에 다양한 바이너리 파일에 쉽게 적용할 수 있다. ##### MS Word 파일 ##### -이 Attribute는 잘 알려지진 않았지만 끝내준다. Word 문서를 버전 관리하는 상황을 살펴보자. 이 문제는 인류에게 알려진 가장 귀찮은 문제 중 하나다. 모든 사람이 Word가 가장 끔찍한 편집기라고 말하지만 애석하게도 모두 Word를 사용한다. Git 저장소에 넣고 커밋하는 것으로도 Word 문서를 버전 관리할 수 있다. 하지만 `git diff`를 실행하면 아래와 같은 메시지를 보여준다: +먼저 이 기술을 인류에게 알려진 가장 귀찮은 문제 중 하나인 Word 문서를 버전 관리하는 상황을 살펴보자. 모든 사람이 Word가 가장 끔찍한 편집기라고 말하지만 애석하게도 모두 Word를 사용한다. Git 저장소에 넣고 이따금 커밋하는 것만으로도 Word 문서의 버전을 관리할 수 있다. 그렇지만 `git diff`를 실행하면 다음과 같은 메시지를 볼 수 있을 뿐이다: $ git diff diff --git a/chapter1.doc b/chapter1.doc @@ -322,16 +326,16 @@ Git은 바이너리 파일도 diff할 수 있다. 이 Attribute는 바이너리 *.doc diff=word -이것은 `*.doc` 파일을 diff할 때 "word" 필터를 사용하라고 설정하는 것이다. 그럼 "word" 필터는 뭘까? 이 "word" 필터도 정의해야 한다. `strings` 프로그램으로 Word 문서에서 사람이 읽을 수 있는 텍스트를 추출하는 "word" 필터를 정의한다. 그러면 Word 문서도 diff할 수 있다: +이것은 `*.doc` 파일의 두 버전이 무엇이 다른지 diff할 때 "word" 필터를 사용하라고 설정하는 것이다. 그럼 "word" 필터는 뭘까? 이 "word" 필터도 정의해야 한다. Word 문서에서 사람이 읽을 수 있는 텍스트를 추출해주는 `catdoc` 프로그램을 "word" 필터로 사용한다. 그러면 Word 문서를 diff할 수 있다. (catdoc 프로그램은 MS Word 문서에 특화된 텍스트 추출기다. `http://www.wagner.pp.ru/~vitus/software/catdoc/`에서 구할 수 있다): - $ git config diff.word.textconv strings + $ git config diff.word.textconv catdoc 위의 명령은 아래와 같은 내용을 `.git/config` 파일에 추가한다: - [diff "word"] - textconv = strings + [diff "word"] + textconv = strings -덧붙이는 말: `.doc` 파일의 종류는 여러가지이다. UTF-16 인코딩을 쓰거나 "codepages" 기반(역주: 한글은 Codepage 949) 인코딩을 사용하는 파일일 수도 있다. 어쨌든 `strings`으로 유용한 정보를 하나도 찾지 못할 때도 있다. 그때 그때 다르다. +댓글: `.doc` 파일의 종류는 여러가지이다. UTF-16 인코딩을 쓰거나 "codepages" 기반(역주: 한글은 Codepage 949) 인코딩을 사용 할 수도 있다. `catdoc`으로는 유용한 정보를 아무것도 찾지 못할 수 있다. 이제 Git은 확장자가 `.doc`인 파일의 스냅샷을 diff할 때 "word" 필터로 정의한 `strings` 프로그램을 사용한다. 이 프로그램은 Word 파일을 텍스트 파일로 변환해 주기 때문에 diff할 수 있다. @@ -342,15 +346,14 @@ Git은 바이너리 파일도 diff할 수 있다. 이 Attribute는 바이너리 index c1c8a0a..b93c9e4 100644 --- a/chapter1.doc +++ b/chapter1.doc - @@ -8,7 +8,8 @@ re going to cover Version Control Systems (VCS) and Git basics - re going to cover how to get it and set it up for the first time if you don - t already have it on your system. - In Chapter Two we will go over basic Git usage - how to use Git for the 80% - -s going on, modify stuff and contribute changes. If the book spontaneously - +s going on, modify stuff and contribute changes. If the book spontaneously - +Let's see if this works. + @@ -128,7 +128,7 @@ and data size) + Since its birth in 2005, Git has evolved and matured to be easy to use + and yet retain these initial qualities. It’s incredibly fast, it’s + very efficient with large projects, and it has an incredible branching + -system for non-linear development. + +system for non-linear development (See Chapter 3). -Git은 "Let's see if this works"가 추가됐다는 것을 정확하게 찾아 준다. 이것은 완벽하지는 않지만(끝에 아무거나 왕창 집어넣지만 않으면) 어쨌든 잘 동작한다. Word 문서를 텍스트로 잘 변환해 주는 프로그램이 있으면 이 방법은 좀 더 완벽해질 수 있다. Mac이나 Linux 같은 시스템에는 `strings`가 이미 설치되어 있기 때문에 당장 사용할 수 있다. +Git은 "(See Chapter 3)"가 추가됐다는 것을 정확하게 찾아 준다. ##### OpenDocument 파일 ##### @@ -358,47 +361,47 @@ MS Word(`*.doc`) 파일에 사용한 방법은 OpenOffice.org(혹은 LibreOffice 아래의 내용을 `.gitattributes` 파일에 추가한다: - *.odt diff=odt + *.odt diff=odt `.git/config` 파일에 `odt` diff 필터를 설정한다: - [diff "odt"] - binary = true - textconv = /usr/local/bin/odt-to-txt + [diff "odt"] + binary = true + textconv = /usr/local/bin/odt-to-txt OpenDocument 파일은 사실 여러 파일(XML, 스타일, 이미지 등등)을 Zip으로 압축한 형식이다. OpenDocument 파일에서 텍스트만 추출하는 스크립트를 하나 작성한다. 아래와 같은 내용을 `/usr/local/bin/odt-to-txt` 파일로(다른 위치에 저장해도 상관없다) 저장한다: - #! /usr/bin/env perl - # Simplistic OpenDocument Text (.odt) to plain text converter. - # Author: Philipp Kempgen - - if (! defined($ARGV[0])) { - print STDERR "No filename given!\n"; - print STDERR "Usage: $0 filename\n"; - exit 1; - } - - my $content = ''; - open my $fh, '-|', 'unzip', '-qq', '-p', $ARGV[0], 'content.xml' or die $!; - { - local $/ = undef; # slurp mode - $content = <$fh>; - } - close $fh; - $_ = $content; - s/]*>//g; # remove spans - s/]*>/\n\n***** /g; # headers - s/]*>\s*]*>/\n -- /g; # list items - s/]*>/\n\n/g; # lists - s/]*>/\n /g; # paragraphs - s/<[^>]+>//g; # remove all XML tags - s/\n{2,}/\n\n/g; # remove multiple blank lines - s/\A\n+//; # remove leading blank lines - print "\n", $_, "\n\n"; + #! /usr/bin/env perl + # Simplistic OpenDocument Text (.odt) to plain text converter. + # Author: Philipp Kempgen + + if (! defined($ARGV[0])) { + print STDERR "No filename given!\n"; + print STDERR "Usage: $0 filename\n"; + exit 1; + } + + my $content = ''; + open my $fh, '-|', 'unzip', '-qq', '-p', $ARGV[0], 'content.xml' or die $!; + { + local $/ = undef; # slurp mode + $content = <$fh>; + } + close $fh; + $_ = $content; + s/]*>//g; # remove spans + s/]*>/\n\n***** /g; # headers + s/]*>\s*]*>/\n -- /g; # list items + s/]*>/\n\n/g; # lists + s/]*>/\n /g; # paragraphs + s/<[^>]+>//g; # remove all XML tags + s/\n{2,}/\n\n/g; # remove multiple blank lines + s/\A\n+//; # remove leading blank lines + print "\n", $_, "\n\n"; 그리고 실행 가능하도록 만든다: - chmod +x /usr/local/bin/odt-to-txt + chmod +x /usr/local/bin/odt-to-txt 이제 `git diff` 명령으로 `.odt` 파일에 대한 변화를 살펴볼 수 있다. @@ -406,12 +409,12 @@ OpenDocument 파일은 사실 여러 파일(XML, 스타일, 이미지 등등)을 이 방법으로 이미지 파일도 diff할 수 있다. 필터로 EXIF 정보를 추출해서 PNG 파일을 비교한다. EXIF 정보는 대부분의 이미지 파일에 들어 있는 메타데이터다. `exiftool`이라는 프로그램을 설치하고 이미지 파일에서 메타데이터 텍스트를 추출한다. 그리고 그 결과를 diff해서 무엇이 달라졌는지 본다: - $ echo '*.png diff=exif' >> .gitattributes + $ echo '*.pngdiff=exif' >> .gitattributes $ git config diff.exif.textconv exiftool 프로젝트에 들어 있는 이미지 파일을 변경하고 `git diff`를 실행하면 아래와 같이 보여준다: - diff --git a/image.png b/image.png + diff --git a/image.pngb/image.png index 88839c4..4afcb7c 100644 --- a/image.png +++ b/image.png @@ -452,10 +455,10 @@ Git은 이 파일을 Checkout할 때마다 SHA 값을 삽입해준다: Commit/Checkout할 때 사용하는 필터를 직접 만들어 쓸 수 있다. 방향에 따라 "clean" 필터와 "smudge" 필터라고 부른다. ".gitattributes" 파일에 설정하고 파일 경로마다 다른 필터를 설정할 수 있다. Checkout할 때 파일을 처리하는 것이 "smudge" 필터이고(그림 7-2) 커밋할 때 처리하는 필터가 "clean" 필터이다. 이 필터로 할 수 있는 일은 무궁무진하다. -Insert 18333fig0702.png +Insert 18333fig0702.png 그림 7-2 "smudge" 필터는 Checkout할 때 실행된다 -Insert 18333fig0703.png +Insert 18333fig0703.png 그림 7-3 "clean" 필터는 파일을 Stage할 때 실행된다 커밋하기 전에 `indent` 프로그램으로 C 코드 전부를 필터링하지만 커밋 메시지는 단순한 예제를 보자. `*.c` 파일은 indent 필터를 사용하도록 `.gitattributes` 파일에 설정한다: @@ -780,7 +783,7 @@ update 스크립트는 각 브랜치마다 한 번씩 실행된다는 것을 제 Unpacking objects: 100% (3/3), done. Enforcing Policies... (refs/heads/master) (8338c5) (c5b616) - [POLICY] Cannot push a non fast-forward reference + [POLICY] Cannot push a non-fast-forward reference error: hooks/update exited with error code 1 error: hook declined to update refs/heads/master To git@gitserver:project.git @@ -790,7 +793,7 @@ update 스크립트는 각 브랜치마다 한 번씩 실행된다는 것을 제 정책과 관련해 하나씩 살펴보자. 먼저 훅이 실행될 때마다 다음 메시지가 출력된다. Enforcing Policies... - (refs/heads/master) (8338c5) (c5b616) + (refs/heads/master) (fb8c72) (c56860) 이것은 update 스크립트 맨 윗부분에서 표준출력(STDOUT)에 출력한 내용이다. 스크립트에서 표준출력으로 출력하면 클라이언트로 전송된다. 이점을 꼭 기억하자. diff --git a/ko/08-git-and-other-scms/01-chapter8.markdown b/ko/08-git-and-other-scms/01-chapter8.markdown index 449dbb3b6..2ff6aa7bf 100644 --- a/ko/08-git-and-other-scms/01-chapter8.markdown +++ b/ko/08-git-and-other-scms/01-chapter8.markdown @@ -369,7 +369,7 @@ SVN에 기록된 Author 이름을 아래 명령으로 조회한다: 이 파일을 `git svn` 명령에 전달하면 보다 정확한 Author 정보를 Git 저장소에 남길 수 있다. 그리고 `git svn`의 `clone`이나 `init` 명령에 `--no-metadata` 옵션을 주면 Subversion의 메타데이터를 저장하지 않는다. 해당 명령은 아래와 같다: - $ git-svn clone http://my-project.googlecode.com/svn/ \ + $ git svn clone http://my-project.googlecode.com/svn/ \ --authors-file=users.txt --no-metadata -s my_project `my_project` 디렉토리에 진짜 Git 저장소가 생성된다. 결과는 아래와 같지 않고: From b3b536eb208c0654dc7a8118e1d1bd087be6ba82 Mon Sep 17 00:00:00 2001 From: Zorgatone Date: Tue, 12 Nov 2013 18:09:20 +0100 Subject: [PATCH 034/862] perhaps little typo "Modifici" is not an Italian word, maybe "Modifica" --- it/01-introduction/01-chapter1.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/01-introduction/01-chapter1.markdown b/it/01-introduction/01-chapter1.markdown index cd46d2117..858d94367 100644 --- a/it/01-introduction/01-chapter1.markdown +++ b/it/01-introduction/01-chapter1.markdown @@ -112,7 +112,7 @@ L'area di stage è un semplice file, generalmente contenuto nella directory di G Il flusso base di lavoro in Git, funziona come segue: -1. Modifici i file nella directory di lavoro +1. Modifica i file nella directory di lavoro 2. Esegui l'operazione di stage dei file, per aggiungere i relativi snapshot all'area di stage 3. Esegui il commit, per immagazzinare permanentemente nella directory di Git, lo snapshot relativo, una volta presi i file nell'area di stage From 1b99bca72c21168318100c595e0b03a3c25fa5d0 Mon Sep 17 00:00:00 2001 From: Zorgatone Date: Tue, 12 Nov 2013 18:17:18 +0100 Subject: [PATCH 035/862] Typo in word "gender" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "è stato aggiunto" not "è stato aggiunta" --- it/01-introduction/01-chapter1.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/01-introduction/01-chapter1.markdown b/it/01-introduction/01-chapter1.markdown index cd46d2117..3bc9745be 100644 --- a/it/01-introduction/01-chapter1.markdown +++ b/it/01-introduction/01-chapter1.markdown @@ -116,7 +116,7 @@ Il flusso base di lavoro in Git, funziona come segue: 2. Esegui l'operazione di stage dei file, per aggiungere i relativi snapshot all'area di stage 3. Esegui il commit, per immagazzinare permanentemente nella directory di Git, lo snapshot relativo, una volta presi i file nell'area di stage -Se una versione particolare di un file è nella directory git, sarà considerata già affidata. Se il file è stato modificato, ma è stato aggiunta all'area di staging, è in sosta. E se è stato modificato da quando è stata controllato, ma non è stato messo in sosta, sarà modificato. Nel Capitolo 2, imparerai di più su questi stati e come trarne vantaggio da essi o saltare interamente la parte di staging. +Se una versione particolare di un file è nella directory git, sarà considerata già affidata. Se il file è stato modificato, ma è stato aggiunto all'area di staging, è in sosta. E se è stato modificato da quando è stata controllato, ma non è stato messo in sosta, sarà modificato. Nel Capitolo 2, imparerai di più su questi stati e come trarne vantaggio da essi o saltare interamente la parte di staging. ## Installare Git ## From 66fee9b441b115a7b08a1f99817e00c330c20b5f Mon Sep 17 00:00:00 2001 From: Zorgatone Date: Tue, 12 Nov 2013 18:26:57 +0100 Subject: [PATCH 036/862] perhaps little typo "Modifici" is not an Italian word, maybe "Modifica" --- it/01-introduction/01-chapter1.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/01-introduction/01-chapter1.markdown b/it/01-introduction/01-chapter1.markdown index 3bc9745be..17c55c7a7 100644 --- a/it/01-introduction/01-chapter1.markdown +++ b/it/01-introduction/01-chapter1.markdown @@ -112,7 +112,7 @@ L'area di stage è un semplice file, generalmente contenuto nella directory di G Il flusso base di lavoro in Git, funziona come segue: -1. Modifici i file nella directory di lavoro +1. Modifica i file nella directory di lavoro 2. Esegui l'operazione di stage dei file, per aggiungere i relativi snapshot all'area di stage 3. Esegui il commit, per immagazzinare permanentemente nella directory di Git, lo snapshot relativo, una volta presi i file nell'area di stage From a35d38a85943817568e2ec792153d88c5f0ec292 Mon Sep 17 00:00:00 2001 From: Zorgatone Date: Wed, 13 Nov 2013 10:43:55 +0100 Subject: [PATCH 037/862] Grammar error "quale ramo" is correct, "quale rame" is not --- it/02-git-basics/01-chapter2.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/02-git-basics/01-chapter2.markdown b/it/02-git-basics/01-chapter2.markdown index 9ca28e6b2..25de9ca5e 100644 --- a/it/02-git-basics/01-chapter2.markdown +++ b/it/02-git-basics/01-chapter2.markdown @@ -857,7 +857,7 @@ Questo è un semplice esempio che potrai incontrare. Quando usi moltissimo Git, Local branch pushed with 'git push' master:master -Questo comando mostra quale rame è automaticamente caricato quando lanci `git push` su certe diramazioni. Inoltre ti mostrerà quali rami remoti sul server che ancora non possiedi, quali rami remoti possiedi e che saranno rimossi dal server, e le diramazioni che saranno automaticamente unite quando lancerai `git pull`. +Questo comando mostra quale ramo è automaticamente caricato quando lanci `git push` su certe diramazioni. Inoltre ti mostrerà quali rami remoti sul server che ancora non possiedi, quali rami remoti possiedi e che saranno rimossi dal server, e le diramazioni che saranno automaticamente unite quando lancerai `git pull`. ### Rimuovere e Rinominare Sorgenti Remote ### From fa23b2df984897e299d4ff0e6607dab37c70075a Mon Sep 17 00:00:00 2001 From: Zorgatone Date: Wed, 13 Nov 2013 11:53:38 +0100 Subject: [PATCH 038/862] Command typo `git co` is correct, `git ci` is not --- it/02-git-basics/01-chapter2.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/02-git-basics/01-chapter2.markdown b/it/02-git-basics/01-chapter2.markdown index 25de9ca5e..a061f52ac 100644 --- a/it/02-git-basics/01-chapter2.markdown +++ b/it/02-git-basics/01-chapter2.markdown @@ -1118,7 +1118,7 @@ Git non deduce il comando se si digita solo in parte. Se non si vuole scrivere l $ git config --global alias.ci commit $ git config --global alias.st status -Questo significa che, per esempio, invece di digitare `git commit`, hai solamente bisogno di scrivere `git ci`. Andando avanti con l'uso di Git, probabilmente ci saranno altri comandi che userai di frequente; in questi casi, non esitare a creare nuovi alias. +Questo significa che, per esempio, invece di digitare `git commit`, hai solamente bisogno di scrivere `git co`. Andando avanti con l'uso di Git, probabilmente ci saranno altri comandi che userai di frequente; in questi casi, non esitare a creare nuovi alias. Questa tecnica può anche essere molto utile per creare comandi che ritieni dovrebbero esistere. Per esempio, per correggere un problema comune in cui si incorre quando si vuole disimpegnare un file dall'area di stage, puoi aggiungere il tuo alias unstage a Git: From e459dbea8146167fa6ed2c8fcb29f4053e096e11 Mon Sep 17 00:00:00 2001 From: Zorgatone Date: Wed, 13 Nov 2013 11:59:43 +0100 Subject: [PATCH 039/862] Reset last commit `git ci` was correct, instead of `git co` --- it/02-git-basics/01-chapter2.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/02-git-basics/01-chapter2.markdown b/it/02-git-basics/01-chapter2.markdown index a061f52ac..25de9ca5e 100644 --- a/it/02-git-basics/01-chapter2.markdown +++ b/it/02-git-basics/01-chapter2.markdown @@ -1118,7 +1118,7 @@ Git non deduce il comando se si digita solo in parte. Se non si vuole scrivere l $ git config --global alias.ci commit $ git config --global alias.st status -Questo significa che, per esempio, invece di digitare `git commit`, hai solamente bisogno di scrivere `git co`. Andando avanti con l'uso di Git, probabilmente ci saranno altri comandi che userai di frequente; in questi casi, non esitare a creare nuovi alias. +Questo significa che, per esempio, invece di digitare `git commit`, hai solamente bisogno di scrivere `git ci`. Andando avanti con l'uso di Git, probabilmente ci saranno altri comandi che userai di frequente; in questi casi, non esitare a creare nuovi alias. Questa tecnica può anche essere molto utile per creare comandi che ritieni dovrebbero esistere. Per esempio, per correggere un problema comune in cui si incorre quando si vuole disimpegnare un file dall'area di stage, puoi aggiungere il tuo alias unstage a Git: From 6999f178a956184683ddcd73aed2a2538d149090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20Schr=C3=B6der?= Date: Sat, 16 Nov 2013 10:32:08 +0100 Subject: [PATCH 040/862] Added German expressions for chapter, section, etc. --- latex/config.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/latex/config.yml b/latex/config.yml index 7e1786901..4d05cf875 100644 --- a/latex/config.yml +++ b/latex/config.yml @@ -110,8 +110,14 @@ no-nb: thanks: "Dette er PDF filen for innholdet til boken Pro Git. Den er lisensiert under Creative Commons Attribution-Non Commercial-Share Alike 3.0 lisensen. Jeg håper du vil ha nytte av den, jeg håper den vil hjelpe deg til å lære Git, og jeg håper du vil støtte Apress og meg ved å kjøpe en kopi av denne boken hos Amazon: \\url{http://tinyurl.com/amazonprogit}" de: langrule: "\\frenchspacing" + prechap: "Kapitel " + presect: "Abschnitt " + fig: "Abbildung " + tab: "Tabelle " + con: "Inhaltsverzeichnis" dql: "„" dqr: "“" + thanks: "Dies ist die PDF-Datei des Buches „Pro Git“. Es ist lizenziert unter der „Creative Commons Attribution-Non Commercial-Share Alike“-Lizenz. Ich hoffe, es gefällt dir, ich hoffe, es hilft dir, Git zu lernen, und ich hoffe, dass du Apress und mich unterstützt, indem du ein gedrucktes Exemplar des Buches über Amazon bestellst: \\url{http://tinyurl.com/amazonprogit}" ko: langrule: "\\XeTeXlinebreakskip=0em plus 0.1em minus 0.01em\n\\XeTeXlinebreakpenalty=0" font: NanumMyeongjo From 8aafd68e440b4c412b997f27b74b09059fe0cde3 Mon Sep 17 00:00:00 2001 From: yang Date: Mon, 18 Nov 2013 18:31:49 +0100 Subject: [PATCH 041/862] translate gitolite segment into chinese --- zh/04-git-server/01-chapter4.markdown | 106 +++++++++++++------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/zh/04-git-server/01-chapter4.markdown b/zh/04-git-server/01-chapter4.markdown index 376b5ae79..d938f2631 100644 --- a/zh/04-git-server/01-chapter4.markdown +++ b/zh/04-git-server/01-chapter4.markdown @@ -502,63 +502,63 @@ Gitosis 也具有简单的访问控制功能。如果想让 John 只有读权限 ## Gitolite ## -Note: the latest copy of this section of the ProGit book is always available within the [gitolite documentation][gldpg]. The author would also like to humbly state that, while this section is accurate, and *can* (and often *has*) been used to install gitolite without reading any other documentation, it is of necessity not complete, and cannot completely replace the enormous amount of documentation that gitolite comes with. +注:本书此段落的最新拷贝始终存在于[gitolite documentation][gldpg]. 作者谦虚地表示,尽管这个段落是精确的,可以(已经)用于安装gitolite而不用阅读其他的文档,但仍有必要不完整,并且不能完全替代随gitolite自带的大量文档。 [gldpg]: http://sitaramc.github.com/gitolite/progit.html -Git has started to become very popular in corporate environments, which tend to have some additional requirements in terms of access control. Gitolite was originally created to help with those requirements, but it turns out that it's equally useful in the open source world: the Fedora Project controls access to their package management repositories (over 10,000 of them!) using gitolite, and this is probably the largest gitolite installation anywhere too. +Git已经变成了非常流行的写作环境,并倾向于为了访问控制而增加额外的需求。Gitolite用于帮助这些需求而创建,但它变成了对开源世界同样有用的东西:Fedora项目使用gitolite控制访问他们的包管理仓库 (超过 10,000个包!) , 而且这也可能是最大的gitolite装置。 -Gitolite allows you to specify permissions not just by repository, but also by branch or tag names within each repository. That is, you can specify that certain people (or groups of people) can only push certain "refs" (branches or tags) but not others. +Gitolite 允许你定义访问许可而不只作用于仓库,而同样于仓库中的每个branch和tag name。你可以定义确切的人 (或一组人) 只能push特定的 "refs" (或者branches或者tags)而不是其他人。 -### Installing ### +### 安装 ### -Installing Gitolite is very easy, even if you don't read the extensive documentation that comes with it. You need an account on a Unix server of some kind; various Linux flavours, and Solaris 10, have been tested. You do not need root access, assuming git, perl, and an openssh compatible ssh server are already installed. In the examples below, we will use the `gitolite` account on a host called `gitserver`. +安装 Gitolite非常简单, 你甚至不用读自带的那一大堆文档。你需要一个unix服务器上的账户;许多linux变种和solaris 10都已经试过了。你不需要root访问,假设git,perl,和一个openssh兼容的ssh服务器已经装好了。在下面的例子里,我们会用 `gitolite` 账户在 `gitserver`上. -Gitolite is somewhat unusual as far as "server" software goes -- access is via ssh, and so every userid on the server is a potential "gitolite host". As a result, there is a notion of "installing" the software itself, and then "setting up" a user as a "gitolite host". +Gitolite 是不同于 "server" 的软件 -- 通过ssh访问, 而且每个在服务器上的userid都是一个潜在的 "gitolite host". 因此, "安装" 这个软件的概念意味着安装它自身, 然后"设置" 一个用户作为 "gitolite host". -Gitolite has 4 methods of installation. People using Fedora or Debian systems can obtain an RPM or a DEB and install that. People with root access can install it manually. In these two methods, any user on the system can then become a "gitolite host". +Gitolite 有4种安装方法。用 Fedora 或 Debian 的人可以获取一个 RPM或者 DEB安装。有root权限的人可以手动安装。在这两种方法中,任意系统上的用户变成一个 "gitolite host"。 -People without root access can install it within their own userids. And finally, gitolite can be installed by running a script *on the workstation*, from a bash shell. (Even the bash that comes with msysgit will do, in case you're wondering.) +没有 root访问权限的人可以安装在他们自己的 userid 下面。最后,gitolite可以用一个“工作站上”的脚本在bash shell安装。(如果你想的话甚至msysgit带的bash就可以。) -We will describe this last method in this article; for the other methods please see the documentation. +我们要描述这个最后一个方法;其他方法请看文档。 -You start by obtaining public key based access to your server, so that you can log in from your workstation to the server without getting a password prompt. The following method works on Linux; for other workstation OSs you may have to do this manually. We assume you already had a key pair generated using `ssh-keygen`. +首先你要获取一个访问服务器的公钥,你可以从你自己的工作站部属密码访问服务器。下面的方法在linux上管用;其他的工作站系统你可以手动做这些事。我们假设你已经用'ssh-keygen'生成了一对密钥。 $ ssh-copy-id -i ~/.ssh/id_rsa gitolite@gitserver -This will ask you for the password to the gitolite account, and then set up public key access. This is **essential** for the install script, so check to make sure you can run a command without getting a password prompt: +这会要你 gitolite账户的密码,然后设置公钥访问。这个对安装脚本非常 **重要**,所以试一下保证你可以不输密码: $ ssh gitolite@gitserver pwd /home/gitolite -Next, you clone Gitolite from the project's main site and run the "easy install" script (the third argument is your name as you would like it to appear in the resulting gitolite-admin repository): +接下俩,你 clone Gitolite从项目的主目录运行 "easy install" 脚本 (第三个参数是你的作为 gitolite-admin仓库用户的名字): $ git clone git://github.com/sitaramc/gitolite $ cd gitolite/src $ ./gl-easy-install -q gitolite gitserver sitaram -And you're done! Gitolite has now been installed on the server, and you now have a brand new repository called `gitolite-admin` in the home directory of your workstation. You administer your gitolite setup by making changes to this repository and pushing. +然后就完成了!Gitolite已经在服务器上装好了,现在你有一个全新的仓库叫做 `gitolite-admin` 在你工作站的 home目录。你管理你的 gitolite 安装通过改变这个项目和push。 -That last command does produce a fair amount of output, which might be interesting to read. Also, the first time you run this, a new keypair is created; you will have to choose a passphrase or hit enter for none. Why a second keypair is needed, and how it is used, is explained in the "ssh troubleshooting" document that comes with Gitolite. (Hey the documentation has to be good for *something*!) +最后的命令产生大量的输出,你可能想读一下。而且你第一次运行的时候会产生一对新密钥;你会选择密码或者什么都不输。为什么需要第二个密钥对以及怎么用在Gitolite带的 "ssh troubleshooting" 文件里解释了。 (文档肯定有点什么用!) -Repos named `gitolite-admin` and `testing` are created on the server by default. If you wish to clone either of these locally (from an account that has SSH console access to the gitolite account via *authorized_keys*), type: +叫做 `gitolite-admin` 和 `testing` 的仓库默认创建在服务器上。如果你想在本地 clone这些 (从一个有ssh控制台 gitolite通过 *authorized_keys*访问的用户),输入: $ git clone gitolite:gitolite-admin $ git clone gitolite:testing -To clone these same repos from any other account: +clone 这些同样的仓库从任意其他账户: $ git clone gitolite@servername:gitolite-admin $ git clone gitolite@servername:testing -### Customising the Install ### +### 定制安装 ### -While the default, quick, install works for most people, there are some ways to customise the install if you need to. If you omit the `-q` argument, you get a "verbose" mode install -- detailed information on what the install is doing at each step. The verbose mode also allows you to change certain server-side parameters, such as the location of the actual repositories, by editing an "rc" file that the server uses. This "rc" file is liberally commented so you should be able to make any changes you need quite easily, save it, and continue. This file also contains various settings that you can change to enable or disable some of gitolite's advanced features. +默认快速安装对大多数人都管用,还有一些定制安装方法如果你用的上的话。如果你不用 `-q` 参数,则用 "罗嗦" 模式安装 -- 详细信息关于安装的每一步都在做什么。 罗嗦模式也允许你改变服务器端参数,诸如实际仓库的位置,通过编辑服务器使用的 "rc" 文件。这个 "rc" 有好多注释让你编辑的时候变得非常简单,保存退出。这个文件也包括了许多设置你能改变来启用或者禁用一些gitolite的高级功能。 -### Config File and Access Control Rules ### +### 配置文件和访问规则 ### -Once the install is done, you switch to the `gitolite-admin` repository (placed in your HOME directory) and poke around to see what you got: +安装结束后,你切换到 `gitolite-admin` 仓库 (放在你的 HOME 目录) 然后看看都有啥: $ cd ~/gitolite-admin/ $ ls @@ -576,11 +576,11 @@ Once the install is done, you switch to the `gitolite-admin` repository (placed repo testing RW+ = @all -Notice that "sitaram" (the last argument in the `gl-easy-install` command you gave earlier) has read-write permissions on the `gitolite-admin` repository as well as a public key file of the same name. +注意 "sitaram" ( 之前用`gl-easy-install` 命令时候的最后一个参数) 有读写权限而且在 `gitolite-admin` 仓库里有一个同名的公钥文件。 -The config file syntax for gitolite is liberally documented in `conf/example.conf`, so we'll only mention some highlights here. +gitolite配置文件的语法在 `conf/example.conf`里,我们只会提到一些主要的。 -You can group users or repos for convenience. The group names are just like macros; when defining them, it doesn't even matter whether they are projects or users; that distinction is only made when you *use* the "macro". +你可以给用户或者仓库分组。分组名就像一些宏;定义的时候,无所谓他们是工程还是用户;区别在于你’使用‘“宏”的时候 @oss_repos = linux perl rakudo git gitolite @secret_repos = fenestra pear @@ -590,7 +590,7 @@ You can group users or repos for convenience. The group names are just like mac @engineers = sitaram dilbert wally alice @staff = @admins @engineers @interns -You can control permissions at the "ref" level. In the following example, interns can only push the "int" branch. Engineers can push any branch whose name starts with "eng-", and tags that start with "rc" followed by a digit. And the admins can do anything (including rewind) to any ref. +你可以控制许可在 "ref" 级别。在下面的例子里,实习生可以 push "int" branch. 工程师可以 push任何有 "eng-"开头的branch,还有refs/tags下面用 "rc"开头的后面跟数字的。而且管理员可以随便改 (包括rewind) 对任何参考名. repo @oss_repos RW int$ = @interns @@ -598,38 +598,38 @@ You can control permissions at the "ref" level. In the following example, inter RW refs/tags/rc[0-9] = @engineers RW+ = @admins -The expression after the `RW` or `RW+` is a regular expression (regex) that the refname (ref) being pushed is matched against. So we call it a "refex"! Of course, a refex can be far more powerful than shown here, so don't overdo it if you're not comfortable with perl regexes. +在 `RW` or `RW+`之后的表达式是正则表达式 (regex) 对应着后面的push用的参考名字 (ref) 。所以我们叫它 "参考正则"(refex)!当然,一个 refex 可以比这里表现的更强大,所以如果你对perl的正则表达式不熟的话就不要改过头。 -Also, as you probably guessed, Gitolite prefixes `refs/heads/` as a syntactic convenience if the refex does not begin with `refs/`. +同样,你可能猜到了,Gitolite 字头 `refs/heads/` 是一个便捷句法如果参考正则没有用 `refs/`开头。 -An important feature of the config file's syntax is that all the rules for a repository need not be in one place. You can keep all the common stuff together, like the rules for all `oss_repos` shown above, then add specific rules for specific cases later on, like so: +一个这个配置文件语法的重要功能是,所有的仓库的规则不需要在同一个位置。你能报所有普通的东西放在一起,就像上面的对所有 `oss_repos` 的规则那样,然后建一个特殊的规则对后面的特殊案例,就像: repo gitolite RW+ = sitaram -That rule will just get added to the ruleset for the `gitolite` repository. +那条规则刚刚加入规则集的 `gitolite` 仓库. -At this point you might be wondering how the access control rules are actually applied, so let's go over that briefly. +这次你可能会想要知道访问控制规则是如何应用的,我们简要介绍一下。 -There are two levels of access control in gitolite. The first is at the repository level; if you have read (or write) access to *any* ref in the repository, then you have read (or write) access to the repository. +在gitolite里有两级访问控制。第一是在仓库级别;如果你已经读或者写访问过了任何在仓库里的参考,那么你已经读或者写访问仓库了。 -The second level, applicable only to "write" access, is by branch or tag within a repository. The username, the access being attempted (`W` or `+`), and the refname being updated are known. The access rules are checked in order of appearance in the config file, looking for a match for this combination (but remember that the refname is regex-matched, not merely string-matched). If a match is found, the push succeeds. A fallthrough results in access being denied. +第二级,应用只能写访问,通过在仓库里的 branch或者 tag。用户名如果尝试过访问 (`W` 或 `+`),参考名被更新为已知。访问规则检查是否出现在配置文件里,为这个联合寻找匹配 (但是记得参考名是正则匹配的,不是字符串匹配的)。如果匹配被找到了,push就成功了。不匹配的访问会被拒绝。 -### Advanced Access Control with "deny" rules ### +### 带'拒绝'的高级访问控制 ### -So far, we've only seen permissions to be one or `R`, `RW`, or `RW+`. However, gitolite allows another permission: `-`, standing for "deny". This gives you a lot more power, at the expense of some complexity, because now fallthrough is not the *only* way for access to be denied, so the *order of the rules now matters*! +目前,我们只看过了许可是 `R`, `RW`, 或者 `RW+`这样子的。但是gitolite还允许另外一种许可:`-`,代表 "拒绝"。这个给了你更多的能力,当然也有一点复杂,因为不匹配并不是唯一的拒绝访问的方法,因此规则的顺序变得无关了! -Let us say, in the situation above, we want engineers to be able to rewind any branch *except* master and integ. Here's how to do that: +这么说好了,在前面的情况中,我们想要工程师可以 rewind 任意 branch 除了master和 integ。 这里是如何做到的 RW master integ = @engineers - master integ = @engineers RW+ = @engineers -Again, you simply follow the rules top down until you hit a match for your access mode, or a deny. Non-rewind push to master or integ is allowed by the first rule. A rewind push to those refs does not match the first rule, drops down to the second, and is therefore denied. Any push (rewind or non-rewind) to refs other than master or integ won't match the first two rules anyway, and the third rule allows it. +你再一次简单跟随规则从上至下知道你找到一个匹配你的访问模式的,或者拒绝。非rewind push到 master或者 integ 被第一条规则允许。一个 rewind push到那些 refs不匹配第一条规则,掉到第二条,因此被拒绝。任何 push (rewind 或非rewind) 到参考或者其他 master 或者 integ不会被前两条规则匹配,即被第三条规则允许。 -### Restricting pushes by files changed ### +### 通过改变文件限制 push ### -In addition to restricting what branches a user can push changes to, you can also restrict what files they are allowed to touch. For example, perhaps the Makefile (or some other program) is really not supposed to be changed by just anyone, because a lot of things depend on it or would break if the changes are not done *just right*. You can tell gitolite: +此外限制用户 push改变到哪条branch的,你也可以限制哪个文件他们可以碰的到。比如, 可能 Makefile (或者其他哪些程序) 真的不能被任何人做任何改动,因为好多东西都靠着它呢,或者如果某些改变刚好不对就会崩溃。你可以告诉 gitolite: repo foo RW = @junior_devs @senior_devs @@ -638,31 +638,31 @@ In addition to restricting what branches a user can push changes to, you can als - NAME/Makefile = @junior_devs RW NAME/ = @junior_devs -This powerful feature is documented in `conf/example.conf`. +这是一个强力的公能写在 `conf/example.conf`里。 -### Personal Branches ### +### 个人分支 ### -Gitolite also has a feature called "personal branches" (or rather, "personal branch namespace") that can be very useful in a corporate environment. +Gitolite 也支持一个叫 "个人分支"的功能 (或者叫, "个人分支命名空间") 在合作环境里非常有用。 -A lot of code exchange in the git world happens by "please pull" requests. In a corporate environment, however, unauthenticated access is a no-no, and a developer workstation cannot do authentication, so you have to push to the central server and ask someone to pull from there. +在 git世界里许多代码交换通过 "pull" 请求发生。然而在合作环境里,委任制的访问是‘绝不’,一个开发者工作站不能认证,你必须push到中心服务器并且叫其他人从那里pull。 -This would normally cause the same branch name clutter as in a centralised VCS, plus setting up permissions for this becomes a chore for the admin. +这个通常会引起一些 branch 名称簇变成像 VCS里一样集中化,加上设置许可变成管理员的苦差事。 -Gitolite lets you define a "personal" or "scratch" namespace prefix for each developer (for example, `refs/personal//*`); see the "personal branches" section in `doc/3-faq-tips-etc.mkd` for details. +Gitolite让你定义一个 "个人的" 或者 "乱七八糟的" 命名空间字首给每个开发人员 (比如,`refs/personal//*`);看在 `doc/3-faq-tips-etc.mkd`里的 "personal branches" 一段获取细节。 -### "Wildcard" repositories ### +### "通配符" 仓库 ### -Gitolite allows you to specify repositories with wildcards (actually perl regexes), like, for example `assignments/s[0-9][0-9]/a[0-9][0-9]`, to pick a random example. This is a *very* powerful feature, which has to be enabled by setting `$GL_WILDREPOS = 1;` in the rc file. It allows you to assign a new permission mode ("C") which allows users to create repositories based on such wild cards, automatically assigns ownership to the specific user who created it, allows him/her to hand out R and RW permissions to other users to collaborate, etc. This feature is documented in `doc/4-wildcard-repositories.mkd`. +Gitolite 允许你定义带通配符的仓库 (其实还是 perl正则式), 比如随便整个例子的话 `assignments/s[0-9][0-9]/a[0-9][0-9]`。 这是一个非常有用的功能,需要通过设置 `$GL_WILDREPOS = 1;` 在 rc文件中启用。允许你安排一个新许可模式 ("C") 允许用户创建仓库基于通配符,自动分配拥有权对特定用户 - 创建者,允许他交出 R和 RW许可给其他合作用户等等。这个功能在`doc/4-wildcard-repositories.mkd`文档里 -### Other Features ### +### 其他功能 ### -We'll round off this discussion with a sampling of other features, all of which, and many more, are described in great detail in the "faqs, tips, etc" and other documents. +我们用一些其他功能的例子结束这段讨论,这些以及其他功能都在 "faqs, tips, etc" 和其他文档里。 -**Logging**: Gitolite logs all successful accesses. If you were somewhat relaxed about giving people rewind permissions (`RW+`) and some kid blew away "master", the log file is a life saver, in terms of easily and quickly finding the SHA that got hosed. +**记录**: Gitolite 记录所有成功的访问。如果你太放松给了别人 rewind许可 (`RW+`) 和其他孩子弄没了 "master", 记录文件会救你的命,如果其他简单快速的找到SHA都不管用。 -**Git outside normal PATH**: One extremely useful convenience feature in gitolite is support for git installed outside the normal `$PATH` (this is more common than you think; some corporate environments or even some hosting providers refuse to install things system-wide and you end up putting them in your own directories). Normally, you are forced to make the *client-side* git aware of this non-standard location of the git binaries in some way. With gitolite, just choose a verbose install and set `$GIT_PATH` in the "rc" files. No client-side changes are required after that :-) +**Git在通常路径外**: 一个在gitolite里的超级有用的简单功能是支持git安装在通常的 `$PATH`之外 (这个比你想象的还要寻常;一些合作环境或者甚至一些主机提供商拒绝安装系统范围外的东西你只能放在自己的目录里)。通常,你被强迫用 *客户端* 用某种方法找到git 为这个非标准的位置。使用 gitolite,只要选择絮叨安装设置 `$GIT_PATH`在 "rc" 文件里。不用改变客户端然后 :-)。 -**Access rights reporting**: Another convenient feature is what happens when you try and just ssh to the server. Gitolite shows you what repos you have access to, and what that access may be. Here's an example: +**访问权报告**: 另一个方便的功能是你尝试用ssh连接到服务器的时候发生了什么。Gitolite告诉你哪个 repos你访问过,那个访问可能是什么。这里是例子: hello sitaram, the gitolite version here is v1.5.4-19-ga3397d4 the gitolite config gives you the following access: @@ -674,11 +674,11 @@ We'll round off this discussion with a sampling of other features, all of which, R indic_web_input R shreelipi_converter -**Delegation**: For really large installations, you can delegate responsibility for groups of repositories to various people and have them manage those pieces independently. This reduces the load on the main admin, and makes him less of a bottleneck. This feature has its own documentation file in the `doc/` directory. +**委托**:真正的大安装,你可以把责任委托给一组仓库给不同的人然后让他们独立管理那些部分。这个减少了主管理者的负担,让他瓶颈更小。这个功能在他自己的文档目录里的 `doc/`下面。 -**Gitweb support**: Gitolite supports gitweb in several ways. You can specify which repos are visible via gitweb. You can set the "owner" and "description" for gitweb from the gitolite config file. Gitweb has a mechanism for you to implement access control based on HTTP authentication, so you can make it use the "compiled" config file that gitolite produces, which means the same access control rules (for read access) apply for gitweb and gitolite. +**Gitweb 支持**: Gitolite支持 gitweb以几种方式。你可以定义哪个仓库在gitweb可见。你能设置 "拥有者" 和 "描述" gitweb 从 gitolite配置文件里。Gitweb 有一个机制给你来实现基于http认证的访问控制,你能让它用 gitolite产生的 "编译过" 的配置文件,意思是同样的访问规则 (为读访问) 用于 gitweb和 gitolite. -**Mirroring**: Gitolite can help you maintain multiple mirrors, and switch between them easily if the primary server goes down. +**镜像**: Gitolite可以帮助你维护多个镜像,如果主服务器挂掉的话在他们之间很容易切换。 ## Git 守护进程 ## From 03e8f4487db38ca5a36856291b03b071842e13ad Mon Sep 17 00:00:00 2001 From: Nilton Moura Date: Tue, 19 Nov 2013 11:39:26 -0200 Subject: [PATCH 042/862] Update 01-chapter2.markdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A regência do verbo pede uma preposição antes do pronome relativo. Por isso, inseri o pronome relativo "com": "...disponíveis COM as quais o servidor pode ser configurado...". Também faltavam duas vírgulas na frase: uma no início, e outra no final. --- pt-br/02-git-basics/01-chapter2.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pt-br/02-git-basics/01-chapter2.markdown b/pt-br/02-git-basics/01-chapter2.markdown index 8051f8914..bcf12e673 100644 --- a/pt-br/02-git-basics/01-chapter2.markdown +++ b/pt-br/02-git-basics/01-chapter2.markdown @@ -36,7 +36,7 @@ Isso cria um diretório chamado `grit`, inicializa um diretório `.git`dentro de Este comando faz exatamente a mesma coisa que o anterior, mas o diretório alvo será chamado `mygrit`. -O Git possui diversos protocolos de transferência que você pode utilizar. O exemplo anterior utiliza o protocolo `git://`, mas você também pode ver `http(s)://` ou `user@server:/path.git`, que utilizam o protocolo de transferência SSH. No *Capítulo 4* introduziremos todas as opções disponíveis as quais o servidor pode ser configurado para acessar o seu repositório Git e os prós e contras de cada uma. +O Git possui diversos protocolos de transferência que você pode utilizar. O exemplo anterior utiliza o protocolo `git://`, mas você também pode ver `http(s)://` ou `user@server:/path.git`, que utilizam o protocolo de transferência SSH. No *Capítulo 4*, introduziremos todas as opções disponíveis com as quais o servidor pode ser configurado para acessar o seu repositório Git, e os prós e contras de cada uma. ## Gravando Alterações no Repositório ## From 5cfd71ed9157cf0be638ed02580b7aab3ce653f6 Mon Sep 17 00:00:00 2001 From: "Jason St. John" Date: Tue, 19 Nov 2013 17:53:02 -0500 Subject: [PATCH 043/862] Fix typo in Chapter 5, section "Public Large Project", in `format-patch` example Fixes issue github/gitscm-next#313 Chapter 5 contains a typo (two hyphens instead of the correct three hyphens) in an example for 'format-patch' in the Public Large Project section. --- en/05-distributed-git/01-chapter5.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/05-distributed-git/01-chapter5.markdown b/en/05-distributed-git/01-chapter5.markdown index 46c1c8cc5..6bf3e1d49 100644 --- a/en/05-distributed-git/01-chapter5.markdown +++ b/en/05-distributed-git/01-chapter5.markdown @@ -517,7 +517,7 @@ The `format-patch` command prints out the names of the patch files it creates. T -- 1.6.2.rc1.20.g8c5b.dirty -You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `--` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. +You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. From 83c3ca5cb4973bd3318d41998166e2802c0c5b81 Mon Sep 17 00:00:00 2001 From: "Jason St. John" Date: Tue, 19 Nov 2013 18:06:52 -0500 Subject: [PATCH 044/862] Apply 5cfd71e to all languages Fixes issue github/gitscm-next#313 (typo in "Public Large Project" section in Chapter 5). Remove trailing whitespace from: -- /05-distributed-git/01-chapter5.markdown -- es/omegat-Benzirpi.tmx --- ar/05-distributed-git/01-chapter5.markdown | 86 +-- az/05-distributed-git/01-chapter5.markdown | 86 +-- ca/05-distributed-git/01-chapter5.markdown | 86 +-- cs/05-distributed-git/01-chapter5.markdown | 2 +- de/05-distributed-git/01-chapter5.markdown | 18 +- es-ni/05-distributed-git/01-chapter5.markdown | 86 +-- es/05-distributed-git/01-chapter5.markdown | 98 +-- es/omegat-Benzirpi.tmx | 594 +++++++++--------- fr/05-distributed-git/01-chapter5.markdown | 2 +- it/05-distributed-git/01-chapter5.markdown | 72 +-- mk/05-distributed-git/01-chapter5.markdown | 86 +-- nl/05-distributed-git/01-chapter5.markdown | 2 +- no-nb/05-distributed-git/01-chapter5.markdown | 86 +-- pt-br/05-distributed-git/01-chapter5.markdown | 2 +- ru/05-distributed-git/01-chapter5.markdown | 32 +- th/05-distributed-git/01-chapter5.markdown | 86 +-- tr/05-distributed-git/01-chapter5.markdown | 86 +-- zh-tw/05-distributed-git/01-chapter5.markdown | 86 +-- 18 files changed, 798 insertions(+), 798 deletions(-) diff --git a/ar/05-distributed-git/01-chapter5.markdown b/ar/05-distributed-git/01-chapter5.markdown index 00a222507..ff492d8d0 100644 --- a/ar/05-distributed-git/01-chapter5.markdown +++ b/ar/05-distributed-git/01-chapter5.markdown @@ -12,7 +12,7 @@ Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Gi In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). -Insert 18333fig0501.png +Insert 18333fig0501.png Figure 5-1. Centralized workflow. This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. @@ -31,7 +31,7 @@ Because Git allows you to have multiple remote repositories, it’s possible to 5. The maintainer adds the contributor’s repo as a remote and merges locally. 6. The maintainer pushes merged changes to the main repository. -Insert 18333fig0502.png +Insert 18333fig0502.png Figure 5-2. Integration-manager workflow. This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. @@ -45,7 +45,7 @@ This is a variant of a multiple-repository workflow. It’s generally used by hu 3. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 4. The dictator pushes their master to the reference repository so the other developers can rebase on it. -Insert 18333fig0503.png +Insert 18333fig0503.png Figure 5-3. Benevolent dictator workflow. This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, because as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. @@ -119,7 +119,7 @@ Let’s see what it might look like when two developers start to work together w Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) @@ -131,7 +131,7 @@ The second developer, Jessica, does the same thing — clones the repository and Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) @@ -161,7 +161,7 @@ John isn’t allowed to push because Jessica has pushed in the meantime. This is At this point, John’s local repository looks something like Figure 5-4. -Insert 18333fig0504.png +Insert 18333fig0504.png Figure 5-4. John’s initial repository. John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: @@ -173,7 +173,7 @@ John has a reference to the changes Jessica pushed up, but he has to merge them The merge goes smoothly — John’s commit history now looks like Figure 5-5. -Insert 18333fig0505.png +Insert 18333fig0505.png Figure 5-5. John’s repository after merging origin/master. Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: @@ -185,12 +185,12 @@ Now, John can test his code to make sure it still works properly, and then he ca Finally, John’s commit history looks like Figure 5-6. -Insert 18333fig0506.png +Insert 18333fig0506.png Figure 5-6. John’s history after pushing to the origin server. In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. -Insert 18333fig0507.png +Insert 18333fig0507.png Figure 5-7. Jessica’s initial commit history. Jessica wants to sync up with John, so she fetches: @@ -203,7 +203,7 @@ Jessica wants to sync up with John, so she fetches: That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. -Insert 18333fig0508.png +Insert 18333fig0508.png Figure 5-8. Jessica’s history after fetching John’s changes. Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: @@ -240,7 +240,7 @@ No problems occur; as you can see it, was a simple fast-forward. Now Jessica mer Everything merges cleanly, and Jessica’s history looks like Figure 5-9. -Insert 18333fig0509.png +Insert 18333fig0509.png Figure 5-9. Jessica’s history after merging John’s changes. Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): @@ -252,12 +252,12 @@ Now `origin/master` is reachable from Jessica’s `master` branch, so she should Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. -Insert 18333fig0510.png +Insert 18333fig0510.png Figure 5-10. Jessica’s history after pushing all changes back to the server. That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it’s ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. -Insert 18333fig0511.png +Insert 18333fig0511.png Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. ### Private Managed Team ### @@ -303,7 +303,7 @@ Now, Jessica makes a couple of commits on the `featureB` branch: Jessica’s repository looks like Figure 5-12. -Insert 18333fig0512.png +Insert 18333fig0512.png Figure 5-12. Jessica’s initial commit history. She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: @@ -368,17 +368,17 @@ Jessica wants to tweak something, so she commits again and then pushes this back Jessica’s commit history now looks something like Figure 5-13. -Insert 18333fig0513.png +Insert 18333fig0513.png Figure 5-13. Jessica’s history after committing on a feature branch. Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. -Insert 18333fig0514.png +Insert 18333fig0514.png Figure 5-14. Jessica’s history after merging both her topic branches. Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. -Insert 18333fig0515.png +Insert 18333fig0515.png Figure 5-15. Basic sequence of this managed-team workflow. ### Public Small Project ### @@ -438,7 +438,7 @@ On a project for which you’re not the maintainer, it’s generally easier to h Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. -Insert 18333fig0516.png +Insert 18333fig0516.png Figure 5-16. Initial commit history with featureB work. Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: @@ -449,7 +449,7 @@ Let’s say the project maintainer has pulled in a bunch of other patches and tr This rewrites your history to now look like Figure 5-17. -Insert 18333fig0517.png +Insert 18333fig0517.png Figure 5-17. Commit history after featureA work. Because you rebased the branch, you have to specify the `–f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). @@ -466,7 +466,7 @@ The `--squash` option takes all the work on the merged branch and squashes it in Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). -Insert 18333fig0518.png +Insert 18333fig0518.png Figure 5-18. Commit history after featureBv2 work. ### Public Large Project ### @@ -489,7 +489,7 @@ Now you have two commits that you want to send to the mailing list. You use `git The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith Date: Sun, 6 Apr 2008 10:17:23 -0700 @@ -514,10 +514,10 @@ The `format-patch` command prints out the names of the patch files it creates. T end def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty -You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `--` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. +You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. @@ -537,14 +537,14 @@ When that is set up, you can use `git send-email` to place the patch series in t $ git send-email *.patch 0001-added-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch - Who should the emails appear to be from? [Jessica Smith ] + Who should the emails appear to be from? [Jessica Smith ] Emails will be sent from: Jessica Smith Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: - (mbox) Adding cc: Jessica Smith from + (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' OK. Log says: Sendmail: /usr/sbin/sendmail -i jessica@example.com @@ -571,7 +571,7 @@ In addition to knowing how to effectively contribute to a project, you’ll like ### Working in Topic Branches ### -When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. +When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. As you’ll remember, you can create the branch based off your master branch like this: $ git branch sc/ruby_client master @@ -596,7 +596,7 @@ This modifies the files in your working directory. It’s almost identical to ru You can also use git apply to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -615,11 +615,11 @@ To apply a patch generated by `format-patch`, you use `git am`. Technically, `gi Limit log functionality to the first 20 -This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. +This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: @@ -635,11 +635,11 @@ You can see that it applied cleanly and automatically created the new commit for Limit log functionality to the first 20 -The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. +The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -651,13 +651,13 @@ But it’s possible that the patch won’t apply cleanly. Perhaps your main bran This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: $ (fix the file) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -674,7 +674,7 @@ If you’re applying a number of patches from an mbox, you can also run the `am` -------------------------- seeing if this helps the gem -------------------------- - Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all + Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. @@ -738,7 +738,7 @@ Technically, you can do that by explicitly figuring out the common ancestor and $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 - $ git diff 36c7db + $ git diff 36c7db However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: @@ -754,7 +754,7 @@ When all the work in your topic branch is ready to be integrated into a more mai One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. -Insert 18333fig0519.png +Insert 18333fig0519.png Figure 5-19. History with several topic branches. Insert 18333fig0520.png @@ -764,13 +764,13 @@ That is probably the simplest workflow, but it’s problematic if you’re deali If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). -Insert 18333fig0521.png +Insert 18333fig0521.png Figure 5-21. Before a topic branch merge. -Insert 18333fig0522.png +Insert 18333fig0522.png Figure 5-22. After a topic branch merge. -Insert 18333fig0523.png +Insert 18333fig0523.png Figure 5-23. After a topic branch release. This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. @@ -780,12 +780,12 @@ You can also continue this concept, having an integrate branch where all the wor The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. -Insert 18333fig0524.png +Insert 18333fig0524.png Figure 5-24. Managing a complex series of parallel contributed topic branches. If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). -Insert 18333fig0525.png +Insert 18333fig0525.png Figure 5-25. Merging contributed topic branches into long-term integration branches. When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. @@ -796,7 +796,7 @@ Other maintainers prefer to rebase or cherry-pick contributed work on top of the The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. -Insert 18333fig0526.png +Insert 18333fig0526.png Figure 5-26. Example history before a cherry pick. If you want to pull commit `e43a6` into your master branch, you can run @@ -808,7 +808,7 @@ If you want to pull commit `e43a6` into your master branch, you can run This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. -Insert 18333fig0527.png +Insert 18333fig0527.png Figure 5-27. History after cherry-picking a commit on a topic branch. Now you can remove your topic branch and drop the commits you didn’t want to pull in. diff --git a/az/05-distributed-git/01-chapter5.markdown b/az/05-distributed-git/01-chapter5.markdown index c34614074..f86238665 100644 --- a/az/05-distributed-git/01-chapter5.markdown +++ b/az/05-distributed-git/01-chapter5.markdown @@ -12,7 +12,7 @@ Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Gi In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). -Insert 18333fig0501.png +Insert 18333fig0501.png Figure 5-1. Centralized workflow. This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. @@ -31,7 +31,7 @@ Because Git allows you to have multiple remote repositories, it’s possible to 5. The maintainer adds the contributor’s repo as a remote and merges locally. 6. The maintainer pushes merged changes to the main repository. -Insert 18333fig0502.png +Insert 18333fig0502.png Figure 5-2. Integration-manager workflow. This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. @@ -45,7 +45,7 @@ This is a variant of a multiple-repository workflow. It’s generally used by hu 3. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 4. The dictator pushes their master to the reference repository so the other developers can rebase on it. -Insert 18333fig0503.png +Insert 18333fig0503.png Figure 5-3. Benevolent dictator workflow. This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, because as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. @@ -119,7 +119,7 @@ Let’s see what it might look like when two developers start to work together w Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) @@ -131,7 +131,7 @@ The second developer, Jessica, does the same thing — clones the repository and Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) @@ -161,7 +161,7 @@ John isn’t allowed to push because Jessica has pushed in the meantime. This is At this point, John’s local repository looks something like Figure 5-4. -Insert 18333fig0504.png +Insert 18333fig0504.png Figure 5-4. John’s initial repository. John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: @@ -173,7 +173,7 @@ John has a reference to the changes Jessica pushed up, but he has to merge them The merge goes smoothly — John’s commit history now looks like Figure 5-5. -Insert 18333fig0505.png +Insert 18333fig0505.png Figure 5-5. John’s repository after merging origin/master. Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: @@ -185,12 +185,12 @@ Now, John can test his code to make sure it still works properly, and then he ca Finally, John’s commit history looks like Figure 5-6. -Insert 18333fig0506.png +Insert 18333fig0506.png Figure 5-6. John’s history after pushing to the origin server. In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. -Insert 18333fig0507.png +Insert 18333fig0507.png Figure 5-7. Jessica’s initial commit history. Jessica wants to sync up with John, so she fetches: @@ -203,7 +203,7 @@ Jessica wants to sync up with John, so she fetches: That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. -Insert 18333fig0508.png +Insert 18333fig0508.png Figure 5-8. Jessica’s history after fetching John’s changes. Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: @@ -240,7 +240,7 @@ No problems occur; as you can see it was a simple fast-forward. Now Jessica merg Everything merges cleanly, and Jessica’s history looks like Figure 5-9. -Insert 18333fig0509.png +Insert 18333fig0509.png Figure 5-9. Jessica’s history after merging John’s changes. Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): @@ -252,12 +252,12 @@ Now `origin/master` is reachable from Jessica’s `master` branch, so she should Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. -Insert 18333fig0510.png +Insert 18333fig0510.png Figure 5-10. Jessica’s history after pushing all changes back to the server. That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it’s ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. -Insert 18333fig0511.png +Insert 18333fig0511.png Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. ### Private Managed Team ### @@ -303,7 +303,7 @@ Now, Jessica makes a couple of commits on the `featureB` branch: Jessica’s repository looks like Figure 5-12. -Insert 18333fig0512.png +Insert 18333fig0512.png Figure 5-12. Jessica’s initial commit history. She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: @@ -368,17 +368,17 @@ Jessica wants to tweak something, so she commits again and then pushes this back Jessica’s commit history now looks something like Figure 5-13. -Insert 18333fig0513.png +Insert 18333fig0513.png Figure 5-13. Jessica’s history after committing on a feature branch. Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. -Insert 18333fig0514.png +Insert 18333fig0514.png Figure 5-14. Jessica’s history after merging both her topic branches. Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. -Insert 18333fig0515.png +Insert 18333fig0515.png Figure 5-15. Basic sequence of this managed-team workflow. ### Public Small Project ### @@ -438,7 +438,7 @@ On a project for which you’re not the maintainer, it’s generally easier to h Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. -Insert 18333fig0516.png +Insert 18333fig0516.png Figure 5-16. Initial commit history with featureB work. Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: @@ -449,7 +449,7 @@ Let’s say the project maintainer has pulled in a bunch of other patches and tr This rewrites your history to now look like Figure 5-17. -Insert 18333fig0517.png +Insert 18333fig0517.png Figure 5-17. Commit history after featureA work. Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). @@ -466,7 +466,7 @@ The `--squash` option takes all the work on the merged branch and squashes it in Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). -Insert 18333fig0518.png +Insert 18333fig0518.png Figure 5-18. Commit history after featureBv2 work. ### Public Large Project ### @@ -489,7 +489,7 @@ Now you have two commits that you want to send to the mailing list. You use `git The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith Date: Sun, 6 Apr 2008 10:17:23 -0700 @@ -514,10 +514,10 @@ The `format-patch` command prints out the names of the patch files it creates. T end def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty -You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `--` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. +You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. @@ -537,14 +537,14 @@ When that is set up, you can use `git send-email` to place the patch series in t $ git send-email *.patch 0001-added-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch - Who should the emails appear to be from? [Jessica Smith ] + Who should the emails appear to be from? [Jessica Smith ] Emails will be sent from: Jessica Smith Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: - (mbox) Adding cc: Jessica Smith from + (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' OK. Log says: Sendmail: /usr/sbin/sendmail -i jessica@example.com @@ -571,7 +571,7 @@ In addition to knowing how to effectively contribute to a project, you’ll like ### Working in Topic Branches ### -When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. +When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. As you’ll remember, you can create the branch based off your master branch like this: $ git branch sc/ruby_client master @@ -596,7 +596,7 @@ This modifies the files in your working directory. It’s almost identical to ru You can also use git apply to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -615,11 +615,11 @@ To apply a patch generated by `format-patch`, you use `git am`. Technically, `gi Limit log functionality to the first 20 -This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. +This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: @@ -635,11 +635,11 @@ You can see that it applied cleanly and automatically created the new commit for Limit log functionality to the first 20 -The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. +The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -651,13 +651,13 @@ But it’s possible that the patch won’t apply cleanly. Perhaps your main bran This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: $ (fix the file) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -674,7 +674,7 @@ If you’re applying a number of patches from an mbox, you can also run the `am` -------------------------- seeing if this helps the gem -------------------------- - Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all + Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. @@ -738,7 +738,7 @@ Technically, you can do that by explicitly figuring out the common ancestor and $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 - $ git diff 36c7db + $ git diff 36c7db However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: @@ -754,7 +754,7 @@ When all the work in your topic branch is ready to be integrated into a more mai One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. -Insert 18333fig0519.png +Insert 18333fig0519.png Figure 5-19. History with several topic branches. Insert 18333fig0520.png @@ -764,13 +764,13 @@ That is probably the simplest workflow, but it’s problematic if you’re deali If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). -Insert 18333fig0521.png +Insert 18333fig0521.png Figure 5-21. Before a topic branch merge. -Insert 18333fig0522.png +Insert 18333fig0522.png Figure 5-22. After a topic branch merge. -Insert 18333fig0523.png +Insert 18333fig0523.png Figure 5-23. After a topic branch release. This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. @@ -780,12 +780,12 @@ You can also continue this concept, having an integrate branch where all the wor The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. -Insert 18333fig0524.png +Insert 18333fig0524.png Figure 5-24. Managing a complex series of parallel contributed topic branches. If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). -Insert 18333fig0525.png +Insert 18333fig0525.png Figure 5-25. Merging contributed topic branches into long-term integration branches. When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. @@ -796,7 +796,7 @@ Other maintainers prefer to rebase or cherry-pick contributed work on top of the The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. -Insert 18333fig0526.png +Insert 18333fig0526.png Figure 5-26. Example history before a cherry pick. If you want to pull commit `e43a6` into your master branch, you can run @@ -808,7 +808,7 @@ If you want to pull commit `e43a6` into your master branch, you can run This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. -Insert 18333fig0527.png +Insert 18333fig0527.png Figure 5-27. History after cherry-picking a commit on a topic branch. Now you can remove your topic branch and drop the commits you didn’t want to pull in. diff --git a/ca/05-distributed-git/01-chapter5.markdown b/ca/05-distributed-git/01-chapter5.markdown index bcf20ab5b..e72635415 100644 --- a/ca/05-distributed-git/01-chapter5.markdown +++ b/ca/05-distributed-git/01-chapter5.markdown @@ -12,7 +12,7 @@ Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Gi In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). -Insert 18333fig0501.png +Insert 18333fig0501.png Figure 5-1. Centralized workflow. This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. @@ -31,7 +31,7 @@ Because Git allows you to have multiple remote repositories, it’s possible to 5. The maintainer adds the contributor’s repo as a remote and merges locally. 6. The maintainer pushes merged changes to the main repository. -Insert 18333fig0502.png +Insert 18333fig0502.png Figure 5-2. Integration-manager workflow. This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. @@ -45,7 +45,7 @@ This is a variant of a multiple-repository workflow. It’s generally used by hu 3. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 4. The dictator pushes their master to the reference repository so the other developers can rebase on it. -Insert 18333fig0503.png +Insert 18333fig0503.png Figure 5-3. Benevolent dictator workflow. This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, because as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. @@ -119,7 +119,7 @@ Let’s see what it might look like when two developers start to work together w Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) @@ -131,7 +131,7 @@ The second developer, Jessica, does the same thing — clones the repository and Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) @@ -161,7 +161,7 @@ John isn’t allowed to push because Jessica has pushed in the meantime. This is At this point, John’s local repository looks something like Figure 5-4. -Insert 18333fig0504.png +Insert 18333fig0504.png Figure 5-4. John’s initial repository. John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: @@ -173,7 +173,7 @@ John has a reference to the changes Jessica pushed up, but he has to merge them The merge goes smoothly — John’s commit history now looks like Figure 5-5. -Insert 18333fig0505.png +Insert 18333fig0505.png Figure 5-5. John’s repository after merging origin/master. Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: @@ -185,12 +185,12 @@ Now, John can test his code to make sure it still works properly, and then he ca Finally, John’s commit history looks like Figure 5-6. -Insert 18333fig0506.png +Insert 18333fig0506.png Figure 5-6. John’s history after pushing to the origin server. In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. -Insert 18333fig0507.png +Insert 18333fig0507.png Figure 5-7. Jessica’s initial commit history. Jessica wants to sync up with John, so she fetches: @@ -203,7 +203,7 @@ Jessica wants to sync up with John, so she fetches: That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. -Insert 18333fig0508.png +Insert 18333fig0508.png Figure 5-8. Jessica’s history after fetching John’s changes. Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: @@ -240,7 +240,7 @@ No problems occur; as you can see it, was a simple fast-forward. Now Jessica mer Everything merges cleanly, and Jessica’s history looks like Figure 5-9. -Insert 18333fig0509.png +Insert 18333fig0509.png Figure 5-9. Jessica’s history after merging John’s changes. Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): @@ -252,12 +252,12 @@ Now `origin/master` is reachable from Jessica’s `master` branch, so she should Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. -Insert 18333fig0510.png +Insert 18333fig0510.png Figure 5-10. Jessica’s history after pushing all changes back to the server. That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it’s ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. -Insert 18333fig0511.png +Insert 18333fig0511.png Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. ### Private Managed Team ### @@ -303,7 +303,7 @@ Now, Jessica makes a couple of commits on the `featureB` branch: Jessica’s repository looks like Figure 5-12. -Insert 18333fig0512.png +Insert 18333fig0512.png Figure 5-12. Jessica’s initial commit history. She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: @@ -368,17 +368,17 @@ Jessica wants to tweak something, so she commits again and then pushes this back Jessica’s commit history now looks something like Figure 5-13. -Insert 18333fig0513.png +Insert 18333fig0513.png Figure 5-13. Jessica’s history after committing on a feature branch. Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. -Insert 18333fig0514.png +Insert 18333fig0514.png Figure 5-14. Jessica’s history after merging both her topic branches. Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. -Insert 18333fig0515.png +Insert 18333fig0515.png Figure 5-15. Basic sequence of this managed-team workflow. ### Public Small Project ### @@ -438,7 +438,7 @@ On a project for which you’re not the maintainer, it’s generally easier to h Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. -Insert 18333fig0516.png +Insert 18333fig0516.png Figure 5-16. Initial commit history with featureB work. Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: @@ -449,7 +449,7 @@ Let’s say the project maintainer has pulled in a bunch of other patches and tr This rewrites your history to now look like Figure 5-17. -Insert 18333fig0517.png +Insert 18333fig0517.png Figure 5-17. Commit history after featureA work. Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). @@ -466,7 +466,7 @@ The `--squash` option takes all the work on the merged branch and squashes it in Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). -Insert 18333fig0518.png +Insert 18333fig0518.png Figure 5-18. Commit history after featureBv2 work. ### Public Large Project ### @@ -489,7 +489,7 @@ Now you have two commits that you want to send to the mailing list. You use `git The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith Date: Sun, 6 Apr 2008 10:17:23 -0700 @@ -514,10 +514,10 @@ The `format-patch` command prints out the names of the patch files it creates. T end def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty -You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `--` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. +You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. @@ -537,14 +537,14 @@ When that is set up, you can use `git send-email` to place the patch series in t $ git send-email *.patch 0001-added-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch - Who should the emails appear to be from? [Jessica Smith ] + Who should the emails appear to be from? [Jessica Smith ] Emails will be sent from: Jessica Smith Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: - (mbox) Adding cc: Jessica Smith from + (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' OK. Log says: Sendmail: /usr/sbin/sendmail -i jessica@example.com @@ -571,7 +571,7 @@ In addition to knowing how to effectively contribute to a project, you’ll like ### Working in Topic Branches ### -When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. +When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. As you’ll remember, you can create the branch based off your master branch like this: $ git branch sc/ruby_client master @@ -596,7 +596,7 @@ This modifies the files in your working directory. It’s almost identical to ru You can also use git apply to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -615,11 +615,11 @@ To apply a patch generated by `format-patch`, you use `git am`. Technically, `gi Limit log functionality to the first 20 -This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. +This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: @@ -635,11 +635,11 @@ You can see that it applied cleanly and automatically created the new commit for Limit log functionality to the first 20 -The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. +The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -651,13 +651,13 @@ But it’s possible that the patch won’t apply cleanly. Perhaps your main bran This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: $ (fix the file) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -674,7 +674,7 @@ If you’re applying a number of patches from an mbox, you can also run the `am` -------------------------- seeing if this helps the gem -------------------------- - Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all + Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. @@ -738,7 +738,7 @@ Technically, you can do that by explicitly figuring out the common ancestor and $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 - $ git diff 36c7db + $ git diff 36c7db However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: @@ -754,7 +754,7 @@ When all the work in your topic branch is ready to be integrated into a more mai One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. -Insert 18333fig0519.png +Insert 18333fig0519.png Figure 5-19. History with several topic branches. Insert 18333fig0520.png @@ -764,13 +764,13 @@ That is probably the simplest workflow, but it’s problematic if you’re deali If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). -Insert 18333fig0521.png +Insert 18333fig0521.png Figure 5-21. Before a topic branch merge. -Insert 18333fig0522.png +Insert 18333fig0522.png Figure 5-22. After a topic branch merge. -Insert 18333fig0523.png +Insert 18333fig0523.png Figure 5-23. After a topic branch release. This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. @@ -780,12 +780,12 @@ You can also continue this concept, having an integrate branch where all the wor The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. -Insert 18333fig0524.png +Insert 18333fig0524.png Figure 5-24. Managing a complex series of parallel contributed topic branches. If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). -Insert 18333fig0525.png +Insert 18333fig0525.png Figure 5-25. Merging contributed topic branches into long-term integration branches. When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. @@ -796,7 +796,7 @@ Other maintainers prefer to rebase or cherry-pick contributed work on top of the The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. -Insert 18333fig0526.png +Insert 18333fig0526.png Figure 5-26. Example history before a cherry pick. If you want to pull commit `e43a6` into your master branch, you can run @@ -808,7 +808,7 @@ If you want to pull commit `e43a6` into your master branch, you can run This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. -Insert 18333fig0527.png +Insert 18333fig0527.png Figure 5-27. History after cherry-picking a commit on a topic branch. Now you can remove your topic branch and drop the commits you didn’t want to pull in. diff --git a/cs/05-distributed-git/01-chapter5.markdown b/cs/05-distributed-git/01-chapter5.markdown index 58cbe5f3e..b4be707b8 100644 --- a/cs/05-distributed-git/01-chapter5.markdown +++ b/cs/05-distributed-git/01-chapter5.markdown @@ -517,7 +517,7 @@ Příkaz `format-patch` vypíše názvy souborů záplaty, kterou vytváří. P -- 1.6.2.rc1.20.g8c5b.dirty -Tyto soubory záplaty můžete také upravit a přidat k nim další informace určené pro seznam příjemců e-mailu, u nichž nechcete, aby byly obsaženy ve zprávě k revizi. Přidáte-li text mezi řádek `--` a začátek záplaty (řádek `lib/simplegit.rb`), vývojářům se zobrazí, ale aplikace záplaty ho obsahovat nebude. +Tyto soubory záplaty můžete také upravit a přidat k nim další informace určené pro seznam příjemců e-mailu, u nichž nechcete, aby byly obsaženy ve zprávě k revizi. Přidáte-li text mezi řádek `---` a začátek záplaty (řádek `lib/simplegit.rb`), vývojářům se zobrazí, ale aplikace záplaty ho obsahovat nebude. Chcete-li e-mail odeslat do poštovní konference, můžete soubor buď vložit do svého e-mailového programu, nebo ho odeslat pomocí příkazového řádku. Vložení textu může často způsobovat problémy s formátováním, zvlášť v případě některých „chytřejších“ klientů, kteří správně nezachovávají nové řádky a jiné prázdné znaky. Git naštěstí nabízí nástroj, který vám pomůže odeslat správně formátované patche pomocí protokolu IMAP. Já budu dokumentovat odeslání záplaty na příkladu Gmailu, který používám jako svého e-mailového agenta. Podrobné instrukce pro celou řadu poštovních programů najdete na konci již dříve zmíněného souboru `Documentation/SubmittingPatches` ve zdrojovém kódu systému Git. diff --git a/de/05-distributed-git/01-chapter5.markdown b/de/05-distributed-git/01-chapter5.markdown index e350585d2..f8dbd677e 100644 --- a/de/05-distributed-git/01-chapter5.markdown +++ b/de/05-distributed-git/01-chapter5.markdown @@ -155,24 +155,24 @@ Versuche außerdem, deine Änderungen in logisch zusammenhängende Einheiten zu -Ein weitere Sache, der du ein bißchen Aufmerksamkeit schenken solltest, ist die Commit Meldung selbst. Wenn man sich angewöhnt, aussagekräftige und hochwertige Commit Meldungen zu schreiben, macht man sich selbst und anderen das Leben erheblich einfacher. Im allgemeinen sollte eine Commit Meldung mit einer einzelnen Zeile anfangen, die nicht länger als 50 Zeichen sein sollte. Dann sollte eine leere Zeile folgen und schließlich eine ausführlichere Beschreibung der Änderungen. +Ein weitere Sache, der du ein bißchen Aufmerksamkeit schenken solltest, ist die Commit Meldung selbst. Wenn man sich angewöhnt, aussagekräftige und hochwertige Commit Meldungen zu schreiben, macht man sich selbst und anderen das Leben erheblich einfacher. Im allgemeinen sollte eine Commit Meldung mit einer einzelnen Zeile anfangen, die nicht länger als 50 Zeichen sein sollte. Dann sollte eine leere Zeile folgen und schließlich eine ausführlichere Beschreibung der Änderungen. Short (50 chars or less) summary of changes - + More detailed explanatory text, if necessary. Wrap it to about 72 characters or so. In some contexts, the first line is treated as the subject of an email and the rest of the text as the body. The blank line separating the summary from the body is critical (unless you omit the body entirely); tools like rebase can get confused if you run the two together. - + Further paragraphs come after blank lines. - + - Bullet points are okay, too - + - Typically a hyphen or asterisk is used for the bullet, preceded by a single space, with blank lines in between, but conventions vary here - + Wenn du deine Commit Meldungen in dieser Weise formatierst, kannst du dir und anderen eine Menge Ärger ersparen. Das Git Projekt selbst hat wohl-formatierte Commit Meldungen. Wir empfehlen, einmal `git log --no-merges` in diesem Repository auszuführen, um einen Eindruck zu erhalten, wie eine gute Commit History eines Projektes aussehen kann. @@ -745,9 +745,9 @@ Der Befehl `git format-patch` zeigt dir die Namen der Patch Dateien an, die er e -- 1.6.2.rc1.20.g8c5b.dirty - + -Du kannst diese Patch Dateien anschließend bearbeiten, z.B. um weitere Informationen für die Mailingliste hinzuzufügen, die du nicht in der Commit Meldung haben willst. Wenn du zusätzlichen Text zwischen der `--` Zeile und dem Anfang des Patches (der Zeile `lib/simplegit.rb` in diesem Fall), dann ist er für den Leser sichtbar, aber Git wird ihn ignorieren, wenn man den Patch verwendet. +Du kannst diese Patch Dateien anschließend bearbeiten, z.B. um weitere Informationen für die Mailingliste hinzuzufügen, die du nicht in der Commit Meldung haben willst. Wenn du zusätzlichen Text zwischen der `---` Zeile und dem Anfang des Patches (der Zeile `lib/simplegit.rb` in diesem Fall), dann ist er für den Leser sichtbar, aber Git wird ihn ignorieren, wenn man den Patch verwendet. @@ -1228,7 +1228,7 @@ Wenn du `git push --tags` ausführst, wird jetzt der `maintainer-pgp-pub` Tag au $ git show maintainer-pgp-pub | gpg --import - + Dieser Schlüssel kann anschließend für alle signierten Tages verwendet werden. Zusätzlich kannst du deinen Anwendern in der Tag Meldung erklären, wie sie signierte Tags mit diesem Schlüssel verifizieren können. diff --git a/es-ni/05-distributed-git/01-chapter5.markdown b/es-ni/05-distributed-git/01-chapter5.markdown index 6d3fab55b..a8b4a8f6f 100644 --- a/es-ni/05-distributed-git/01-chapter5.markdown +++ b/es-ni/05-distributed-git/01-chapter5.markdown @@ -12,7 +12,7 @@ Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Gi In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). -Insert 18333fig0501.png +Insert 18333fig0501.png Figure 5-1. Centralized workflow This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. @@ -31,7 +31,7 @@ Because Git allows you to have multiple remote repositories, it’s possible to 5. The maintainer adds the contributor’s repo as a remote and merges locally. 6. The maintainer pushes merged changes to the main repository. -Insert 18333fig0502.png +Insert 18333fig0502.png Figure 5-2. Integration-manager workflow This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. @@ -45,7 +45,7 @@ This is a variant of a multiple-repository workflow. It’s generally used by hu 3. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 4. The dictator pushes their master to the reference repository so the other developers can rebase on it. -Insert 18333fig0503.png +Insert 18333fig0503.png Figure 5-3. Benevolent dictator workflow This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, because as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. @@ -119,7 +119,7 @@ Let’s see what it might look like when two developers start to work together w Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) @@ -131,7 +131,7 @@ The second developer, Jessica, does the same thing — clones the repository and Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) @@ -161,7 +161,7 @@ John isn’t allowed to push because Jessica has pushed in the meantime. This is At this point, John’s local repository looks something like Figure 5-4. -Insert 18333fig0504.png +Insert 18333fig0504.png Figure 5-4. John’s initial repository John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: @@ -173,7 +173,7 @@ John has a reference to the changes Jessica pushed up, but he has to merge them The merge goes smoothly — John’s commit history now looks like Figure 5-5. -Insert 18333fig0505.png +Insert 18333fig0505.png Figure 5-5. John’s repository after merging origin/master Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: @@ -185,12 +185,12 @@ Now, John can test his code to make sure it still works properly, and then he ca Finally, John’s commit history looks like Figure 5-6. -Insert 18333fig0506.png +Insert 18333fig0506.png Figure 5-6. John’s history after pushing to the origin server In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. -Insert 18333fig0507.png +Insert 18333fig0507.png Figure 5-7. Jessica’s initial commit history Jessica wants to sync up with John, so she fetches: @@ -203,7 +203,7 @@ Jessica wants to sync up with John, so she fetches: That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. -Insert 18333fig0508.png +Insert 18333fig0508.png Figure 5-8. Jessica’s history after fetching John’s changes Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: @@ -240,7 +240,7 @@ No problems occur; as you can see it, was a simple fast-forward. Now Jessica mer Everything merges cleanly, and Jessica’s history looks like Figure 5-9. -Insert 18333fig0509.png +Insert 18333fig0509.png Figure 5-9. Jessica’s history after merging John’s changes Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): @@ -252,12 +252,12 @@ Now `origin/master` is reachable from Jessica’s `master` branch, so she should Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. -Insert 18333fig0510.png +Insert 18333fig0510.png Figure 5-10. Jessica’s history after pushing all changes back to the server That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it’s ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. -Insert 18333fig0511.png +Insert 18333fig0511.png Figure 5-11. General sequence of events for a simple multiple-developer Git workflow ### Private Managed Team ### @@ -303,7 +303,7 @@ Now, Jessica makes a couple of commits on the `featureB` branch: Jessica’s repository looks like Figure 5-12. -Insert 18333fig0512.png +Insert 18333fig0512.png Figure 5-12. Jessica’s initial commit history She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: @@ -368,17 +368,17 @@ Jessica wants to tweak something, so she commits again and then pushes this back Jessica’s commit history now looks something like Figure 5-13. -Insert 18333fig0513.png +Insert 18333fig0513.png Figure 5-13. Jessica’s history after committing on a feature branch Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. -Insert 18333fig0514.png +Insert 18333fig0514.png Figure 5-14. Jessica’s history after merging both her topic branches Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. -Insert 18333fig0515.png +Insert 18333fig0515.png Figure 5-15. Basic sequence of this managed-team workflow ### Public Small Project ### @@ -438,7 +438,7 @@ On a project for which you’re not the maintainer, it’s generally easier to h Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. -Insert 18333fig0516.png +Insert 18333fig0516.png Figure 5-16. Initial commit history with featureB work Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: @@ -449,7 +449,7 @@ Let’s say the project maintainer has pulled in a bunch of other patches and tr This rewrites your history to now look like Figure 5-17. -Insert 18333fig0517.png +Insert 18333fig0517.png Figure 5-17. Commit history after featureA work Because you rebased the branch, you have to specify the `–f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). @@ -466,7 +466,7 @@ The `--squash` option takes all the work on the merged branch and squashes it in Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). -Insert 18333fig0518.png +Insert 18333fig0518.png Figure 5-18. Commit history after featureBv2 work ### Public Large Project ### @@ -489,7 +489,7 @@ Now you have two commits that you want to send to the mailing list. You use `git The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith Date: Sun, 6 Apr 2008 10:17:23 -0700 @@ -514,10 +514,10 @@ The `format-patch` command prints out the names of the patch files it creates. T end def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty -You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `--` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. +You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. @@ -537,14 +537,14 @@ When that is set up, you can use `git send-email` to place the patch series in t $ git send-email *.patch 0001-added-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch - Who should the emails appear to be from? [Jessica Smith ] + Who should the emails appear to be from? [Jessica Smith ] Emails will be sent from: Jessica Smith Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: - (mbox) Adding cc: Jessica Smith from + (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' OK. Log says: Sendmail: /usr/sbin/sendmail -i jessica@example.com @@ -571,7 +571,7 @@ In addition to knowing how to effectively contribute to a project, you’ll like ### Working in Topic Branches ### -When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. +When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. As you’ll remember, you can create the branch based off your master branch like this: $ git branch sc/ruby_client master @@ -596,7 +596,7 @@ This modifies the files in your working directory. It’s almost identical to ru You can also use git apply to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -615,11 +615,11 @@ To apply a patch generated by `format-patch`, you use `git am`. Technically, `gi Limit log functionality to the first 20 -This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. +This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: @@ -635,11 +635,11 @@ You can see that it applied cleanly and automatically created the new commit for Limit log functionality to the first 20 -The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. +The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -651,13 +651,13 @@ But it’s possible that the patch won’t apply cleanly. Perhaps your main bran This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: $ (fix the file) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -674,7 +674,7 @@ If you’re applying a number of patches from an mbox, you can also run the `am` -------------------------- seeing if this helps the gem -------------------------- - Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all + Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. @@ -738,7 +738,7 @@ Technically, you can do that by explicitly figuring out the common ancestor and $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 - $ git diff 36c7db + $ git diff 36c7db However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: @@ -754,7 +754,7 @@ When all the work in your topic branch is ready to be integrated into a more mai One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. -Insert 18333fig0519.png +Insert 18333fig0519.png Figure 5-19. History with several topic branches Insert 18333fig0520.png @@ -764,13 +764,13 @@ That is probably the simplest workflow, but it’s problematic if you’re deali If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). -Insert 18333fig0521.png +Insert 18333fig0521.png Figure 5-21. Before a topic branch merge -Insert 18333fig0522.png +Insert 18333fig0522.png Figure 5-22. After a topic branch merge -Insert 18333fig0523.png +Insert 18333fig0523.png Figure 5-23. After a topic branch release This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. @@ -780,12 +780,12 @@ You can also continue this concept, having an integrate branch where all the wor The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. -Insert 18333fig0524.png +Insert 18333fig0524.png Figure 5-24. Managing a complex series of parallel contributed topic branches If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). -Insert 18333fig0525.png +Insert 18333fig0525.png Figure 5-25. Merging contributed topic branches into long-term integration branches When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. @@ -796,7 +796,7 @@ Other maintainers prefer to rebase or cherry-pick contributed work on top of the The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. -Insert 18333fig0526.png +Insert 18333fig0526.png Figure 5-26. Example history before a cherry pick If you want to pull commit `e43a6` into your master branch, you can run @@ -808,7 +808,7 @@ If you want to pull commit `e43a6` into your master branch, you can run This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. -Insert 18333fig0527.png +Insert 18333fig0527.png Figure 5-27. History after cherry-picking a commit on a topic branch Now you can remove your topic branch and drop the commits you didn’t want to pull in. diff --git a/es/05-distributed-git/01-chapter5.markdown b/es/05-distributed-git/01-chapter5.markdown index 2b15cbefa..2f4f74e7e 100644 --- a/es/05-distributed-git/01-chapter5.markdown +++ b/es/05-distributed-git/01-chapter5.markdown @@ -12,7 +12,7 @@ Al contrario de otros Sistemas Centralizados de Control de Versiones, (CVCSs, Ce En los sistemas centralizados, tenemos una única forma de trabajar. Un repositorio o punto central guarda el código fuente; y todo el mundo sincroniza su trabajo con él. Unos cuantos desarrolladores son nodos de trabajo --consumidores de dicho repositorio-- y se sincronizan con dicho punto central. (ver Figura 5-1). -Insert 18333fig0501.png +Insert 18333fig0501.png Figura 5-1. Flujo de trabajo centralizado. Esto significa que, si dos desarrolladores clonan desde el punto central, y ambos hacen cambios; tan solo el primero de ellos en enviar sus cambios de vuelta lo podrá hacer limpiamente. El segundo desarrollador deberá fusionar previamente su trabajo con el del primero, antes de enviarlo, para evitar el sobreescribir los cambios del primero. Este concepto es también válido en Git, tanto como en Subversion (o cualquier otro CVCS), y puede ser perfectamente utilizado en Git. @@ -31,7 +31,7 @@ Al permitir multiples repositorios remotos, en Git es posible tener un flujo de 5. La gestora añade como remoto el repositorio de la colaboradora y fusiona (merge) los cambios localmente. 6. La gestora envia (push) los cambios fusionados al repositorio principal. -Insert 18333fig0502.png +Insert 18333fig0502.png Figura 5-2. Flujo de trabajo Gestor-de-Integración. Esta es una forma de trabajo muy común en sitios tales como GitHub, donde es sencillo bifurcar (fork) un proyecto y enviar tus cambios a tu copia, donde cualquiera puede verlos. La principal ventaja de esta forma de trabajar es que puedes continuar trabajando, y la persona gestora del repositorio principal podrá recuperar (pull) tus cambios en cualquier momento. Las personas colaboradoras no tienen por qué esperar a que sus cambios sean incorporados al proyecto, --cada cual puede trabajar a su propio ritmo--. @@ -45,7 +45,7 @@ Es una variante del flujo de trabajo con multiples repositorios. Se utiliza gene 3. El dictador fusiona las ramas master de los tenientes en su propia rama master. 4. El dictador envia (push) su rama master al repositorio de referencia, para permitir que los desarrolladores reorganicen (rebase) desde ella. -Insert 18333fig0503.png +Insert 18333fig0503.png Figura 5-3. Fujo de trabajo del dictador benevolente. Esta manera de trabajar no es muy habitual, pero es muy util en proyectos muy grandes o en organizaciónes fuertemente jerarquizadas. Permite al lider o a la lider del proyecto (el/la dictador/a) delegar gran parte del trabajo; recolectando el fruto de multiples puntos de trabajo antes de integrarlo en el proyecto. @@ -58,7 +58,7 @@ En estos momentos conoces las diferentes formas de trabajar, y tienes ya un gene El mayor problema al intentar describir este proceso es el gran número de variaciones que se pueden presentar. Por la gran flexibilidad de Git, la gente lo suele utilizar de multiples maneras; siendo problemático intentar describir la forma en que deberías contribuir a un proyecto --cada proyecto tiene sus peculiaridades--. Algunas de las variables a considerar son: la cantidad de colaboradores activos, la forma de trabajo escogida, el nivel de acceso que tengas, y, posiblemente, el sistema de colaboración externa implantado. -La primera variable es el número de colaboradores activos. ¿Cuántos usuarios están enviando activamente código a este proyecto?, y ¿con qué frecuencia?. En muchas ocasiones, tendrás dos o tres desarrolladores, con tan solo unas pocas confirmaciones de cambios (commits) diarias; e incluso menos en algunos proyectos durmientes. En proyectos o empresas verdaderamente grandes puedes tener cientos de desarrolladores, con docenas o incluso cientos de parches llegando cada día. Esto es importante, ya que cuantos más desarrolladores haya, mayores serán los problemas para asegurarte de que tu código se integre limpiamente. Los cambios que envies pueden quedar obsoletos o severamente afectados por otros trabajos que han sido integrados previamente mientras tú estabas trabajando o mientras tus cambios aguardaban a ser aprobados para su integración. ¿Cómo puedes mantener consistentemente actualizado tu código, y asegurarte así de que tus parches son válidos? +La primera variable es el número de colaboradores activos. ¿Cuántos usuarios están enviando activamente código a este proyecto?, y ¿con qué frecuencia?. En muchas ocasiones, tendrás dos o tres desarrolladores, con tan solo unas pocas confirmaciones de cambios (commits) diarias; e incluso menos en algunos proyectos durmientes. En proyectos o empresas verdaderamente grandes puedes tener cientos de desarrolladores, con docenas o incluso cientos de parches llegando cada día. Esto es importante, ya que cuantos más desarrolladores haya, mayores serán los problemas para asegurarte de que tu código se integre limpiamente. Los cambios que envies pueden quedar obsoletos o severamente afectados por otros trabajos que han sido integrados previamente mientras tú estabas trabajando o mientras tus cambios aguardaban a ser aprobados para su integración. ¿Cómo puedes mantener consistentemente actualizado tu código, y asegurarte así de que tus parches son válidos? La segunda variable es la forma de trabajo que se utilice para el proyecto. ¿Es centralizado, con iguales derechos de acceso en escritura para cada desarrollador?. ¿Tiene un gestor de integraciones que comprueba todos los parches?. ¿Se revisan y aprueban los parches entre los propios desarrolladores?. ¿Participas en ese proceso de aprobación?. ¿Existe un sistema de tenientes, a los que has de enviar tu trabajo en primer lugar?. @@ -112,7 +112,7 @@ Vamos a ver como actuarian dos desarrolladores trabajando conjuntamente en un re Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) @@ -124,7 +124,7 @@ La segunda desarrolladora, Jessica, hace lo mismo: clona el repositorio y confir Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) @@ -154,7 +154,7 @@ John no puede enviar porque Jessica ha enviado previamente. Entender bien esto e En este punto, el repositorio local de John será algo parecido a la Figura 5-4. -Insert 18333fig0504.png +Insert 18333fig0504.png Figura 5-4. El repositorio inicial de John. John tiene una referencia a los cambios enviados por Jessica, pero ha de fusionarlos en su propio trabajo antes de que se le permita enviar: @@ -166,7 +166,7 @@ John tiene una referencia a los cambios enviados por Jessica, pero ha de fusiona Si la fusión se realiza sin problemas, el historial de John será algo parecido a la Figura 5-5. -Insert 18333fig0505.png +Insert 18333fig0505.png Figura 5-5. El repositorio de John tras fusionar origin/master. En este momento, John puede comprobar su código para verificar que sigue funcionando correctamente, y luego puede enviar su trabajo al servidor: @@ -178,12 +178,12 @@ En este momento, John puede comprobar su código para verificar que sigue funcio Finalmente, el historial de John es algo parecido a la Figura 5-6. -Insert 18333fig0506.png +Insert 18333fig0506.png Figura 5-6. El historial de John tras enviar al servidor origen. Mientras tanto, jessica ha seguido trabajando en una rama puntual (topic branch). Ha creado una rama puntual denominada 'issue54' y ha realizado tres confirmaciones de cambios (commit) en dicha rama. Como todavia no ha recuperado los cambios de John, su historial es como se muestra en la Figura 5-7. -Insert 18333fig0507.png +Insert 18333fig0507.png Figura 5-7. Historial inicial de Jessica. Jessica desea sincronizarse con John, para lo cual: @@ -196,7 +196,7 @@ Jessica desea sincronizarse con John, para lo cual: Esto recupera el trabajo enviado por John durante el tiempo en que Jessica estaba trabajando. El historial de Jessica es en estos momentos como se muestra en la figura 5-8. -Insert 18333fig0508.png +Insert 18333fig0508.png Figura 5-8. El historial de Jessica tras recuperar los cambios de John. Jessica considera su rama puntual terminada, pero quiere saber lo que debe integrar con su trabajo antes de poder enviarla. Lo comprueba con el comando 'git log': @@ -233,7 +233,7 @@ No hay ningún problema; como puedes observar, es un simple avance rápido (fast Todo se integra limpiamente, y el historial de Jessica queda como en la Figura 5-9. -Insert 18333fig0509.png +Insert 18333fig0509.png Figura 5-9. El historial de Jessica tras fusionar los cambios de John. En este punto, la rama 'origin/master' es alcanzable desde la rama 'master' de Jessica, permitiendole enviar (push) --asumiendo que John no haya enviado nada más durante ese tiempo--: @@ -245,12 +245,12 @@ En este punto, la rama 'origin/master' es alcanzable desde la rama 'master' de J Cada desarrollador ha confirmado algunos cambios y ambos han fusionado sus trabajos correctamente; ver Figura 5-10. -Insert 18333fig0510.png +Insert 18333fig0510.png Figura 5-10. El historial de Jessica tras enviar de vuelta todos los cambios al servidor. Este es uno de los flujos de trabajo más simples. Trabajas un rato, normalmente en una rama puntual de un asunto concreto, y la fusionas con tu rama principal cuando la tienes lista para integrar. Cuando deseas compartir ese trabajo, lo fusionas (merge) en tu propia rama 'master'; luego recuperas (fetch) y fusionas (merge) la rama 'origin/master', por si hubiera cambiado; y finalmente envias (push) la rama 'master' de vuelta al servidor. La secuencia general es algo así como la mostrada en la Figura 5-11. -Insert 18333fig0511.png +Insert 18333fig0511.png Figura 5-11. Secuencia general de eventos en un flujo de trabajo multidesarrollador simple. ### Grupo Privado Gestionado ### @@ -296,10 +296,10 @@ Y realiza un par de confirmaciones de cambios (commits) en la rama 'featureB': Quedando su repositorio como se muestra en la Figura 5-12 -Insert 18333fig0512.png +Insert 18333fig0512.png Figura 5-12. Historial inicial de Jessica. -Cuando está preparada para enviar (push) su trabajo, recibe un correo-e de Josie de que ha puesto en el servidor una rama denominada 'featureBee', con algo de trabajo. Jessica necesita fusionar (merge) dichos cambios con los suyos antes de poder enviarlos al servidor. Por tanto, recupera (fetch) los cambios de Josie: +Cuando está preparada para enviar (push) su trabajo, recibe un correo-e de Josie de que ha puesto en el servidor una rama denominada 'featureBee', con algo de trabajo. Jessica necesita fusionar (merge) dichos cambios con los suyos antes de poder enviarlos al servidor. Por tanto, recupera (fetch) los cambios de Josie: $ git fetch origin ... @@ -361,17 +361,17 @@ Jessica realiza algunos ajustes, los confirma (commit) y los envia (push) de vue Quedando su historial como se muestra en la Figura 5-13. -Insert 18333fig0513.png +Insert 18333fig0513.png Figura 5-13. El historial de Jessica después de confirmar cambios en una rama puntual. Jessica, Josie y John informan a los integradores de que las ramas 'featureA' y 'featureBee' del servidor están preparadas para su integración con la línea principal del programa. Despues de que dichas ramas sean integradas en la línea principal, una recuperación (fetch) traerá de vuelta las confirmaciones de cambios de las integraciones (merge commits), dejando un historial como el mostrado en la Figura 5-14. -Insert 18333fig0514.png +Insert 18333fig0514.png Figura 5-14. El historial de Jessica tras fusionar sus dos ramas puntuales. Muchos grupos se están pasando a trabajar con Git, debido a su habilidad para mantener multiples equipos trabajando en paralelo, fusionando posteriormente las diferentes líneas de trabajo. La habilidad para que pequeños subgrupos de un equipo colaboren a través de ramas remotas, sin necesidad de tener en cuenta o de perturbar el equipo completo, es un gran beneficio de trabajar con Git. La secuencia del flujo de trabajo que hemos visto es algo así como lo mostrado en la Figura 5-15. -Insert 18333fig0515.png +Insert 18333fig0515.png Figura 5-15. Secuencia básica de este flujo de trabajo en equipo gestionado. ### Pequeño Proyecto Público ### @@ -420,7 +420,7 @@ Este comando 'request-pull' compara la rama base donde deseas que se integre tu Esta salida puede ser enviada al gestor del proyecto, --le indica el punto donde se ramificó, resume las confirmaciones de cambio, y le dice desde dónde recuperar estos cambios--. -En un proyecto del que no seas gestor, suele ser más sencillo tener una rama tal como 'master' siguiendo siempre a la rama 'origin/master'; mientras realizas todo tu trabajo en otras ramas puntuales, que podrás descartar facilmente en caso de que alguna de ellas sea rechazada. Manteniendo el trabajo de distintos temas aislados en sus respectivas ramas puntuales, te facilitas también el poder reorganizar tu trabajo si la cabeza del repositorio principal se mueve mientras tanto y tus confirmaciones de cambio (commits) ya no se pueden integrar limpiamente. Por ejemplo, si deseas contribuir al proyecto en un segundo tema, no continues trabajando sobre la rama puntual que acabas de enviar; comienza una nueva rama puntual desde la rama 'master' del repositorio principal: +En un proyecto del que no seas gestor, suele ser más sencillo tener una rama tal como 'master' siguiendo siempre a la rama 'origin/master'; mientras realizas todo tu trabajo en otras ramas puntuales, que podrás descartar facilmente en caso de que alguna de ellas sea rechazada. Manteniendo el trabajo de distintos temas aislados en sus respectivas ramas puntuales, te facilitas también el poder reorganizar tu trabajo si la cabeza del repositorio principal se mueve mientras tanto y tus confirmaciones de cambio (commits) ya no se pueden integrar limpiamente. Por ejemplo, si deseas contribuir al proyecto en un segundo tema, no continues trabajando sobre la rama puntual que acabas de enviar; comienza una nueva rama puntual desde la rama 'master' del repositorio principal: $ git checkout -b featureB origin/master $ (work) @@ -431,7 +431,7 @@ En un proyecto del que no seas gestor, suele ser más sencillo tener una rama ta De esta forma, cada uno de los temas está aislado dentro de un silo, --similar a una cola de parches--; permitiendote reescribir, reorganizar y modificar cada uno de ellos sin interferir ni crear interdependencias entre ellos. -Insert 18333fig0516.png +Insert 18333fig0516.png Figura 5-16. Historial inicial con el trabajo de la funcionalidad B. Supongamos que el gestor del proyecto ha recuperado e integrado un grupo de otros parches y después lo intenta con tu primer parche, viendo que no se integra limpiamente. En este caso, puedes intentar reorganizar (rebase) tu parche sobre 'origin/master', arreglar los conflictos y volver a enviar tus cambios: @@ -442,7 +442,7 @@ Supongamos que el gestor del proyecto ha recuperado e integrado un grupo de otro Esto reescribe tu historial, quedando como se vé en la Figura 5-17. -Insert 18333fig0517.png +Insert 18333fig0517.png Figura 5-17. Historial tras el trabajo en la funcionalidad A. Debido a que has reorganizado (rebase) tu rama de trabajo, tienes que indicar la opción '-f' en tu comando de envio (push), para permitir que la rama 'featureA' del servidor sea reemplazada por una confirmación de cambios (commit) que no es hija suya. Una alternativa podría ser el enviar (push) este nuevo trabajo a una rama diferente del servidor (por ejemplo a 'featureAv2'). @@ -459,7 +459,7 @@ La opción '--squash' coge todo el trabajo en la rama fusionada y lo aplica, en En estos momentos, puedes notificar al gestor del proyecto que has realizado todos los cambios solicitados y que los puede encontrar en tu rama 'featureBv2' (ver Figura 5-18). -Insert 18333fig0518.png +Insert 18333fig0518.png Figura 5-18. Historial tras el trabajo en la versión 2 de la funcionalidad B. ### Proyecto Público Grande ### @@ -482,7 +482,7 @@ Tienes dos confirmaciones de cambios (commits) a enviar a la lista de correo. Ut El comando `format-patch` lista los nombres de los archivos de parche que crea. La opción `-M` indica a Git que ha de mirar por si hay algo renombrado. Los archivos serán algo como: - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith Date: Sun, 6 Apr 2008 10:17:23 -0700 @@ -507,10 +507,10 @@ El comando `format-patch` lista los nombres de los archivos de parche que crea. end def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty -Puedes incluso editar esos archivos de parche, para añadirles más información , específica para la lista de correo, y que no desees mostrar en el propio mensaje de la confirmación de cambios. Si añades texto entre la línea que comienza por `--` y el comienzo del parche (la línea `lib/simplegit.rb`). Los desarrolladores de la lista de correo podrán leerlo. Pero será ignorado al aplicar el parche al proyecto. +Puedes incluso editar esos archivos de parche, para añadirles más información , específica para la lista de correo, y que no desees mostrar en el propio mensaje de la confirmación de cambios. Si añades texto entre la línea que comienza por `---` y el comienzo del parche (la línea `lib/simplegit.rb`). Los desarrolladores de la lista de correo podrán leerlo. Pero será ignorado al aplicar el parche al proyecto. Para enviar estos archivos a la lista de correo,puedes tanto pegar directamente el archivo en tu programa de correo electrónico, como enviarlo a través de algún programa basado en línea de comandos. Pegar el texto directamente suele causar problemas de formato. Especialmente con los clientes de correo más "inteligentes", que no preservan adecuadamente los saltos de línea y otros espaciados. Afortunadamente, Git suministra una herramienta que nos puede ser de gran ayuda para enviar parches correctamente formateados a través de protocolo IMAP, facilitandonos así las cosas. Voy a indicar cómo enviar un parche usando Gmail, que da la casualidad de que es el agente de correo utilizado por mí. En el final del anteriormente citado documento, `Documentation/SubmittingPatches`, puedes leer instrucciones detalladas para otros agentes de correo. @@ -530,14 +530,14 @@ Cuando tengas esto ajustado, podrás utilizar el comando `git send-email` para p $ git send-email *.patch 0001-added-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch - Who should the emails appear to be from? [Jessica Smith ] + Who should the emails appear to be from? [Jessica Smith ] Emails will be sent from: Jessica Smith Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y Tras esto, Git escupirá una serie de información de registro, con pinta más o menos como esta: - (mbox) Adding cc: Jessica Smith from + (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' OK. Log says: Sendmail: /usr/sbin/sendmail -i jessica@example.com @@ -564,7 +564,7 @@ Además de conocer cómo contribuir de forma efectiva a un proyecto, es posible ### Trabajando con Ramas Puntuales ### -Cuando estás pensando en integrar nuevo trabajo, suele ser buena idea utilizar una rama puntual para cada tema concreto --una rama temporal creada específicamente para trabajar dicho tema-- De esta forma, es sencillo tratar cada parche de forma individualizada y poder "aparcar" uno concreto cuando no trabajamos en él, hasta cuando volvamos a tener tiempo para retomarlo. Si creas los nombres de ramas basandolos en el tema sobre el que vas a trabajar, por ejemplo 'ruby client' o algo así de descriptivo, podrás recordar de qué iba cada rama en caso de que la abandones por un tiempo y la retomes más tarde. La persona gestora del proyecto Git suele tender a nombrar cada rama de foma parecida --por ejemplo 'sc/ruby client', donde sc es la abreviatura para la persona que ha contribuido con ese trabajo--. +Cuando estás pensando en integrar nuevo trabajo, suele ser buena idea utilizar una rama puntual para cada tema concreto --una rama temporal creada específicamente para trabajar dicho tema-- De esta forma, es sencillo tratar cada parche de forma individualizada y poder "aparcar" uno concreto cuando no trabajamos en él, hasta cuando volvamos a tener tiempo para retomarlo. Si creas los nombres de ramas basandolos en el tema sobre el que vas a trabajar, por ejemplo 'ruby client' o algo así de descriptivo, podrás recordar de qué iba cada rama en caso de que la abandones por un tiempo y la retomes más tarde. La persona gestora del proyecto Git suele tender a nombrar cada rama de foma parecida --por ejemplo 'sc/ruby client', donde sc es la abreviatura para la persona que ha contribuido con ese trabajo--. Como recordarás, la forma de crear una rama basandola en tu rama master es: $ git branch sc/ruby_client master @@ -589,7 +589,7 @@ Esto modificará los archivos en tu carpeta de trabajo. Es prácticamente idént Tambien puedes utilizar 'git apply' para comprobar si un parche se puede incorporar limpiamente; antes de intentar incorporarlo. Puedes lanzar el comando 'git apply --check': - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -608,11 +608,11 @@ Para incorporar un parche generado con 'format-patch', utilizarás el comando 'g Limit log functionality to the first 20Limit log functionality to the first 20Limit log functionality to the first 20 -Esto es el comienzo de la salida del comando format-patch visto en la sección anterior. Es también un formato válido para un mbox. Si alguien te ha enviado correctamente un parche utilizando 'git send-email', y te lo has descargado a un formato mbox; podrás indicar dicho archivo mbox al comando 'git am', y este comenzará a incorporar todos los parches que encuentre dentro. Si tienes un cliente de correo electrónico capaz de guardar varios mensajes en formato mbox, podrás guardar series completas de parches en un mismo archivo; y luego usar 'git am' para irlos incorporando secuencialmente. +Esto es el comienzo de la salida del comando format-patch visto en la sección anterior. Es también un formato válido para un mbox. Si alguien te ha enviado correctamente un parche utilizando 'git send-email', y te lo has descargado a un formato mbox; podrás indicar dicho archivo mbox al comando 'git am', y este comenzará a incorporar todos los parches que encuentre dentro. Si tienes un cliente de correo electrónico capaz de guardar varios mensajes en formato mbox, podrás guardar series completas de parches en un mismo archivo; y luego usar 'git am' para irlos incorporando secuencialmente. Sin embargo, si alguien sube su archivo de parche a un sistema de gestión de peticiones de servicio o similar; tendrás que descargartelo a un archivo local en tu disco y luego indicar ese archivo local al comando 'git am': - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function Observarás que, tras incorporarlo limpiamente, crea automáticamente una nueva confirmación de cambios (commit). La información sobre el autor o autora la recoge de las cabeceras 'From' (Remitente) y 'Date' (Fecha). Y el mensaje para la confirmación (commit) lo recoge de 'Subject' (Asunto) y del cuerpo del correo electrónico. Por ejemplo, si consideramos el parche incorporado desde el mbox del ejemplo que acabamos de mostrar; la confirmación de camios (commit) generada será algo como: @@ -628,11 +628,11 @@ Observarás que, tras incorporarlo limpiamente, crea automáticamente una nueva Limit log functionality to the first 20Limit log functionality to the first 20Limit log functionality to the first 20 -El campo 'Commit' muestra la persona que ha incorporado el parche y cuándo lo ha incorporado. El campo 'Author' muestra la persona que ha creado originalmente el parche y cuándo fue creado este. +El campo 'Commit' muestra la persona que ha incorporado el parche y cuándo lo ha incorporado. El campo 'Author' muestra la persona que ha creado originalmente el parche y cuándo fue creado este. Pero también podría suceder que el parche no se pudiera incorporar limpiamente. Es posible que tu rama principal diverja demasiado respecto de la rama sobre la que se construyó el parche; o que el parche tenga dependencias respecto de algún otro parche anterior que aún no hayas incorporado. En ese caso, el proceso 'git am' fallará y te preguntará qué deseas hacer: - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -644,13 +644,13 @@ Pero también podría suceder que el parche no se pudiera incorporar limpiamente Este comando pondrá marcadores de conflicto en cualquier archivo con problemas, de forma similar a como lo haría una operación de fusión (merge) o de reorganización (rebase). Y resolverás los problemas de la misma manera: editar el archivo para resolver los conflictos, prepararlo (stage), y lanzar 'git am --resolved' para continuar con el siguiente parche: $ (fix the file) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem Si deseas más inteligencia por parte de Git al resolver conflictos, puedes pasarle la opción '-3', para que intente una fusión a tres bandas (three-way merge). Esta opción no se usa por defecto, porque no funcionará en caso de que la confirmación de cambios en que el parche dice estar basado no esté presente en tu repositorio. Sin embargo, si tienes dicha confirmación de cambios (commit), --si el parche está basado en una confirmación pública--, entonces la opción '-3' suele ser mucho más avispada cuando incorporas un parche conflictivo: - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -667,7 +667,7 @@ Al aplicar varios parches desde un mbox, puedes lanzar el comando 'am' en modo i -------------------------- seeing if this helps the gem -------------------------- - Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all + Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all Es una utilidad interesante si tienes tienes almacenados unos cuantos parches, porque puedes ir revisando previamente cada parche y aplicarlos selectivamente. @@ -687,7 +687,7 @@ Si más tarde vuelva a enviarte otro correo-e avisandote de otra gran funcionali Es muy util cuando trabajas regularmente con una persona. En cambio, si alguien tiene un solo parche para enviarte, una sola vez, puede ser más efectivo aceptarlo directamente por correo-e; en lugar de pedir a todo el mundo que tenga cada uno su propio servidor y tener nosotros que estar continuamente añadiendo y quitando remotos para cada parche. También es muy posible que no quieras tener cientos de remotos, cada uno contribuyendo tan solo con un parche o dos. De todas formas, los scripts y los servicios albergados pueden hacerte la vida más facil en esto, --todo depende de cómo desarrolles tú y de como desarrollan las personas que colaboran contigo--. -Otra ventaja de esta forma de trabajar es que recibes también el histórico de confirmaciones de cambio (commits). A pesar de poder seguir teniendo los habituales problemas con la fusión, por lo menos conoces en qué punto de tu historial han basado su trabajo. Por defecto, se aplicará una genuina fusión a tres bandas, en lugar de tener que poner un '-3' y esperar que el parche haya sido generado a partir de una confirmación de cambios (commit) pública a la que tengas tú también acceso. +Otra ventaja de esta forma de trabajar es que recibes también el histórico de confirmaciones de cambio (commits). A pesar de poder seguir teniendo los habituales problemas con la fusión, por lo menos conoces en qué punto de tu historial han basado su trabajo. Por defecto, se aplicará una genuina fusión a tres bandas, en lugar de tener que poner un '-3' y esperar que el parche haya sido generado a partir de una confirmación de cambios (commit) pública a la que tengas tú también acceso. Si no trabajas habitualmente con una persona, pero deseas recuperar de ella por esta vía, puedes indicar directamente el URL del repositorio remoto en el comando 'git pull'. Esto efectua una recuperación (pull) puntual y no conserva la URL como una referencia remota: @@ -731,7 +731,7 @@ Técnicamente, lo puedes hacer descubriendo tu mismo dicho ancestro común y lan $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 - $ git diff 36c7db + $ git diff 36c7db Pero esto no es lo más conveniente. De ahí que Git suministre otro atajo para hacerlo: la sintaxis del triple-punto. Estando en el contexto del comando 'diff', puedes indicar tres puntos entre los nombres de las dos ramas; para comparar entre la última confirmación de cambios de la rama donde estás y la respectiva confirmación común con la otra rama: @@ -747,7 +747,7 @@ Cuando todo el trabajo presente en tu rama puntual esté listo para ser integrad Una forma simple de trabajar es fusionandolo todo en tu rama 'master'. En este escenario, tienes una rama 'master' que contiene, principalmente, código estable. Cuando en una rama puntual tienes trabajo ya terminado o contribuciones ya verificadas de terceros, los fusionas en tu rama 'master', borras la rama puntual, y continuas trabajando en otra/s rama/s. Si, tal y como se muestra en la Figura 5-19, tenemos un repositorio con trabajos en dos ramas, denominadas 'ruby client' y 'php client'; y fusionamos primero la rama 'ruby client' y luego la 'php client', obtendremos un historial similar al de la Figura 5-20. -Insert 18333fig0519.png +Insert 18333fig0519.png Figura 5-19. Historial con varias ramas puntuales. Insert 18333fig0520.png @@ -755,15 +755,15 @@ Figura 5-20. Tras fusionar una rama puntual. Este es probablemente el flujo de trabajo más sencillo. Pero puede dar problemas cuando estás tratando con grandes repositorios o grandes proyectos. -Teniendo muchos desarrolladores o proyectos muy grandes, muy posiblemente desees utilizar un ciclo con por lo menos dos fases. En este escenario, se dispone de dos ramas de largo recorrido: 'master' y 'develop'. La primera de ellas, 'master', será actualizada únicamente por los lanzamientos de código muy estable. La segunda rama, 'develop', es donde iremos integrando todo el código nuevo. Ambas ramas se enviarán periodicamente al repositorio público. Cada vez que tengas una nueva rama puntual lista para integrar (Figura 5-21), la fusionarás en la rama 'develop'. Y cuando marques el lanzamiento de una versión estable, avanzarás la rama 'master' hasta el punto donde la rama 'develop' se encuentre en ese momento (Figura 5-23). +Teniendo muchos desarrolladores o proyectos muy grandes, muy posiblemente desees utilizar un ciclo con por lo menos dos fases. En este escenario, se dispone de dos ramas de largo recorrido: 'master' y 'develop'. La primera de ellas, 'master', será actualizada únicamente por los lanzamientos de código muy estable. La segunda rama, 'develop', es donde iremos integrando todo el código nuevo. Ambas ramas se enviarán periodicamente al repositorio público. Cada vez que tengas una nueva rama puntual lista para integrar (Figura 5-21), la fusionarás en la rama 'develop'. Y cuando marques el lanzamiento de una versión estable, avanzarás la rama 'master' hasta el punto donde la rama 'develop' se encuentre en ese momento (Figura 5-23). -Insert 18333fig0521.png +Insert 18333fig0521.png Figura 5-21. Antes de fusionar una rama puntual. -Insert 18333fig0522.png +Insert 18333fig0522.png Figura 5-22. Tras fusionar una rama puntual. -Insert 18333fig0523.png +Insert 18333fig0523.png Figura 5-23. Tras un lanzamiento puntual. De esta forma, cuando alguien clone el repositorio de tu proyecto, podrá recuperar (checkout) y mantener actualizadas tanto la última version estable como la versión con el material más avanzado; en las ramas 'master' y 'develop', respectivamente. @@ -773,12 +773,12 @@ Puedes continuar ampliando este concepto, disponiendo de una rama 'integrate' do El proyecto Git tiene cuatro ramas de largo recorrido: 'master', 'next', 'pu' (proposed updates) para el trabajo nuevo, y 'maint' (maintenance) para trabajos de mantenimiento de versiones previas. A medida que vamos introduciendo nuevos trabajos de las personas colaboradoras, estos se van recolectando en ramas puntuales en el repositorio de una persona gestora; de forma similar a como se ha ido describiendo (ver Figura 5-24). En un momento dado, las funcionalidades introducidas se evaluan; comprobando si son seguras y si están preparadas para los consumidores; o si, por el contrario, necesitan dedicarles más trabajo. Las funcionalidades que resultan ser seguras y estar preparadas se fusionan (merge) en la rama 'next'; y esta es enviada (push) al repositorio público, para que cualquiera pueda probarlas. -Insert 18333fig0524.png +Insert 18333fig0524.png Figura 5-24. Gestionando complejas series de ramas puntuales paralelas con funcionalidades varias. Si las funcionalidades necesitan ser más trabajadas, se fusionan (merge) en la rama 'pu'. Y cuando las funcionalidades permanecen totalmente estables, se refusionan en la rama 'master'; componiendolas desde las funcionalidades en la rama 'next' aún sin promocionar a 'master'. Esto significa que 'master' prácticamente siempre avanza; 'next' se reorganiza (rebase) de vez en cuando; y 'pu' es reorganizada con más frecuencia (ver Figura 5-25). -Insert 18333fig0525.png +Insert 18333fig0525.png Figura 5-25. Fusionando aportaciones de ramas puntuales en ramas de más largo recorrido. Una rama puntual se borra del repositorio cuando, finalmente, es fusionada en la rama 'master'. El proyecto Git dispone también de una rama 'maint' que se bifurca (fork) a partir de la última versión ya lanzada; para trabajar en parches, en caso de necesitarse alguna versión intermedia de mantenimiento. Así, cuando clonas el repositorio de Git, obtienes cuatro ramas que puedes recuperar (checkout); pudiendo evaluar el proyecto en distintos estadios de desarrollo, dependiendo de cuán avanzado desees estar o cómo desees contribuir. Y así, los gestores de mantenimiento disponen de un flujo de trabajo estructurado, para ayudarles en el procesado e incorporación de nuevas contribuciones. @@ -789,7 +789,7 @@ Otros gestores de mantenimiento, al procesar el trabajo recibido de las persona El otro camino para introducir trabajo de una rama en otra, es entresacarlo. Entresacar (cherry-pick) en Git es como reorganizar (rebase) una sola confirmación de cambios (commit). Se trata de coger el parche introducido por una determinada confirmación de cambios e intentar reaplicarlo sobre la rama donde te encuentres en ese momento. Puede ser util si tienes varias confirmaciones de cambios en una rama puntual, y tan solo deseas integar una de ellas; o si tienes una única confirmación de cambios en una rama puntual, y prefieres entresacarla en lugar de reorganizar. Por ejemplo, suponiendo que tienes un proyecto parecido al ilustrado en la Figura 5-26. -Insert 18333fig0526.png +Insert 18333fig0526.png Figura 5-26. Historial de ejemplo, antes de entresacar. Si deseas integar únicamente la confirmación 'e43a6' en tu rama 'master', puedes lanzar: @@ -801,7 +801,7 @@ Si deseas integar únicamente la confirmación 'e43a6' en tu rama 'master', pued Esto introduce exactamente el mismo cambio introducido por 'e43a6', pero con un nuevo valor SHA-1 de confirmación; ya que es diferente la fecha en que ha sido aplicado. Tu historial quedará tal como ilustra la Figura 5-27. -Insert 18333fig0527.png +Insert 18333fig0527.png Figura 5-27. Historial tras entresacar una confirmación de cambios de una rama puntual. Ahora, ya puedes borrar la rama puntual y descartar las confirmaciones de cambios que no deseas integrar. @@ -833,7 +833,7 @@ Una vez tengas el contenido de tu clave guardado en Git, puedes crear una etiqut $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92 -Si lanzas el comando 'git push --tags', la etiqueta 'maintainer-pgp-pub' será compartida por todos. Cualquiera que desee verificar la autenticidad de una etiqueta, no tiene más que importar tu clave PGP, sacando el objecto directamente de la base de datos e importandolo en GPG:, +Si lanzas el comando 'git push --tags', la etiqueta 'maintainer-pgp-pub' será compartida por todos. Cualquiera que desee verificar la autenticidad de una etiqueta, no tiene más que importar tu clave PGP, sacando el objecto directamente de la base de datos e importandolo en GPG:, $ git show maintainer-pgp-pub | gpg --import diff --git a/es/omegat-Benzirpi.tmx b/es/omegat-Benzirpi.tmx index 082bb354f..f2e101c15 100644 --- a/es/omegat-Benzirpi.tmx +++ b/es/omegat-Benzirpi.tmx @@ -182,11 +182,11 @@ - Insert 18333fig0504.png + Insert 18333fig0504.png Figure 5-4. - Insert 18333fig0504.png + Insert 18333fig0504.png Figura 5-4. @@ -256,12 +256,12 @@ Figura 5-4. - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -394,14 +394,14 @@ Figura 5-4. - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith <jessica@example.com> Date: Sun, 6 Apr 2008 10:17:23 -0700 Subject: [PATCH 1/2] add limit to log function - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith <jessica@example.com> Date: Sun, 6 Apr 2008 10:17:23 -0700 @@ -647,7 +647,7 @@ Figura 5-4. Or you can use the shorter scp-like syntax for SSH protocol: - + $ git clone user@server:project.git @@ -730,11 +730,11 @@ Figura 5-4. - Insert 18333fig0511.png + Insert 18333fig0511.png Figure 5-11. - Insert 18333fig0511.png + Insert 18333fig0511.png Figura 5-11. @@ -764,11 +764,11 @@ Figura 5-11. - Insert 18333fig0315.png + Insert 18333fig0315.png Figure 3-15. - Insert 18333fig0315.png + Insert 18333fig0315.png Figura 3-15. @@ -868,11 +868,11 @@ Figura 3-15. - Insert 18333fig0401.png + Insert 18333fig0401.png Figure 4-1. - Insert 18333fig0401.png + Insert 18333fig0401.png Figura 4-1. @@ -970,7 +970,7 @@ Figura 4-1. - # enforces fast-forward only pushes + # enforces fast-forward only pushes def check_fast_forward missed_refs = `git rev-list #{$newrev}..#{$oldrev}` missed_ref_count = missed_refs.split("\n").size @@ -981,7 +981,7 @@ Figura 4-1. end - # enforces fast-forward only pushes + # enforces fast-forward only pushes def check_fast_forward missed_refs = `git rev-list #{$newrev}..#{$oldrev}` missed_ref_count = missed_refs.split("\n").size @@ -1141,11 +1141,11 @@ Here is a template originally written by Tim Pope at tpope.net: - Insert 18333fig0334.png + Insert 18333fig0334.png Figure 3-34. - Insert 18333fig0334.png + Insert 18333fig0334.png Figura 3-34. @@ -1402,12 +1402,12 @@ Figura 3-6. $ echo 'version 2' > test.txt - $ git hash-object -w test.txt + $ git hash-object -w test.txt 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a $ echo 'version 2' > test.txt - $ git hash-object -w test.txt + $ git hash-object -w test.txt 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a @@ -1437,11 +1437,11 @@ Figura 3-6. - Insert 18333fig0409.png + Insert 18333fig0409.png Figure 4-9. - Insert 18333fig0409.png + Insert 18333fig0409.png Figura 4-9. @@ -1537,7 +1537,7 @@ Figura 4-9. - $ cat ~/.ssh/id_rsa.pub + $ cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3 Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA @@ -1546,7 +1546,7 @@ Figura 4-9. NrRFi9wrf+M7Q== schacon@agadorlaptop.local - $ cat ~/.ssh/id_rsa.pub + $ cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3 Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA @@ -2061,7 +2061,7 @@ Figura 4-9. access[$user].each do |access_path| if !access_path || # user has access to everything (path.index(access_path) == 0) # access to this path - has_file_access = true + has_file_access = true end end if !has_file_access @@ -2069,7 +2069,7 @@ Figura 4-9. exit 1 end end - end + end end @@ -2083,7 +2083,7 @@ Figura 4-9. access[$user].each do |access_path| if !access_path || # user has access to everything (path.index(access_path) == 0) # access to this path - has_file_access = true + has_file_access = true end end if !has_file_access @@ -2091,7 +2091,7 @@ Figura 4-9. exit 1 end end - end + end end @@ -2113,11 +2113,11 @@ Figura 4-9. - Insert 18333fig0305.png + Insert 18333fig0305.png Figure 3-5. - Insert 18333fig0305.png + Insert 18333fig0305.png Figura 3-5. @@ -2351,11 +2351,11 @@ Figura 3-5. - Insert 18333fig0336.png + Insert 18333fig0336.png Figure 3-36. - Insert 18333fig0336.png + Insert 18333fig0336.png Figura 3-36. @@ -2605,11 +2605,11 @@ Figura 3-36. - Insert 18333fig0408.png + Insert 18333fig0408.png Figure 4-8. - Insert 18333fig0408.png + Insert 18333fig0408.png Figura 4-8. @@ -2639,11 +2639,11 @@ Figura 4-8. - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function @@ -2967,11 +2967,11 @@ Figura 4-8. - $ cat .git/refs/remotes/origin/master + $ cat .git/refs/remotes/origin/master ca82a6dff817ec66f44342007202690a93763949 - $ cat .git/refs/remotes/origin/master + $ cat .git/refs/remotes/origin/master ca82a6dff817ec66f44342007202690a93763949 @@ -3281,11 +3281,11 @@ Figura 4-8. - Insert 18333fig0303.png + Insert 18333fig0303.png Figure 3-3. - Insert 18333fig0303.png + Insert 18333fig0303.png Figura 3-3. @@ -3313,11 +3313,11 @@ Figura 3-3. - Insert 18333fig0902.png + Insert 18333fig0902.png Figure 9-2. - Insert 18333fig0902.png + Insert 18333fig0902.png Figura 9-2. @@ -3379,11 +3379,11 @@ Figura 9-2. - Insert 18333fig0507.png + Insert 18333fig0507.png Figure 5-7. - Insert 18333fig0507.png + Insert 18333fig0507.png Figura 5-7. @@ -3503,11 +3503,11 @@ Figura 5-7. - $ cat .git/HEAD + $ cat .git/HEAD ref: refs/heads/master - $ cat .git/HEAD + $ cat .git/HEAD ref: refs/heads/master @@ -3563,11 +3563,11 @@ Figura 5-7. - Insert 18333fig0403.png + Insert 18333fig0403.png Figure 4-3. - Insert 18333fig0403.png + Insert 18333fig0403.png Figura 4-3. @@ -3699,11 +3699,11 @@ Figura 4-3. - Insert 18333fig0330.png + Insert 18333fig0330.png Figure 3-30. - Insert 18333fig0330.png + Insert 18333fig0330.png Figura 3-30. @@ -4059,11 +4059,11 @@ Figura 3-30. - Insert 18333fig0701.png + Insert 18333fig0701.png Figure 7-1. - Insert 18333fig0701.png + Insert 18333fig0701.png Figura 7-1. @@ -4123,7 +4123,7 @@ Figura 7-1. $ git clone git@gitserver:gitosis-admin.git - a tu ordenador personal-- + a tu ordenador personal-- $ git clone git@gitserver:gitosis-admin.git @@ -4393,11 +4393,11 @@ Figura 7-1. - Insert 18333fig0302.png + Insert 18333fig0302.png Figure 3-2. - Insert 18333fig0302.png + Insert 18333fig0302.png Figura 3-2. @@ -4503,11 +4503,11 @@ Figura 3-2. - Insert 18333fig0904.png + Insert 18333fig0904.png Figure 9-4. - Insert 18333fig0904.png + Insert 18333fig0904.png Figura 9-4. @@ -4577,12 +4577,12 @@ Figura 9-4. - $ cat /usr/local/bin/extDiff + $ cat /usr/local/bin/extDiff #!/bin/sh [ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5" - $ cat /usr/local/bin/extDiff + $ cat /usr/local/bin/extDiff #!/bin/sh [ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5" @@ -4597,13 +4597,13 @@ Figura 9-4. - $ git diff + $ git diff diff --git a/chapter1.doc b/chapter1.doc index 88839c4..4afcb7c 100644 Binary files a/chapter1.doc and b/chapter1.doc differ - $ git diff + $ git diff diff --git a/chapter1.doc b/chapter1.doc index 88839c4..4afcb7c 100644 Binary files a/chapter1.doc and b/chapter1.doc differ @@ -4659,11 +4659,11 @@ Figura 9-4. - Insert 18333fig0316.png + Insert 18333fig0316.png Figure 3-16. - Insert 18333fig0316.png + Insert 18333fig0316.png Figura 3-16. @@ -4813,11 +4813,11 @@ Figura 3-16. - Insert 18333fig0522.png + Insert 18333fig0522.png Figure 5-22. - Insert 18333fig0522.png + Insert 18333fig0522.png Figura 5-22. @@ -4935,15 +4935,15 @@ Figura 5-22. - Enter file in which to save the key (/Users/schacon/.ssh/id_rsa): - Enter passphrase (empty for no passphrase): - Enter same passphrase again: + Enter file in which to save the key (/Users/schacon/.ssh/id_rsa): + Enter passphrase (empty for no passphrase): + Enter same passphrase again: Your identification has been saved in /Users/schacon/.ssh/id_rsa. - Enter file in which to save the key (/Users/schacon/.ssh/id_rsa): - Enter passphrase (empty for no passphrase): - Enter same passphrase again: + Enter file in which to save the key (/Users/schacon/.ssh/id_rsa): + Enter passphrase (empty for no passphrase): + Enter same passphrase again: Your identification has been saved in /Users/schacon/.ssh/id_rsa. @@ -4973,11 +4973,11 @@ Figura 5-22. - If the book spontaneously + If the book spontaneously +Let's see if this works. - If the book spontaneously + If the book spontaneously +Let's see if this works. @@ -5337,11 +5337,11 @@ Figura 5-22. - Insert 18333fig0323.png + Insert 18333fig0323.png Figure 3-23. - Insert 18333fig0323.png + Insert 18333fig0323.png Figura 3-23. @@ -5413,11 +5413,11 @@ Figura 4-2. - Insert 18333fig0318.png + Insert 18333fig0318.png Figure 3-18. - Insert 18333fig0318.png + Insert 18333fig0318.png Figura 3-18. @@ -5563,14 +5563,14 @@ Figura 3-18. - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply Patch failed at 0001. - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -5587,11 +5587,11 @@ Figura 3-18. - Insert 18333fig0518.png + Insert 18333fig0518.png Figure 5-18. - Insert 18333fig0518.png + Insert 18333fig0518.png Figura 5-18. @@ -5640,7 +5640,7 @@ Figura 5-18. Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) @@ -5651,7 +5651,7 @@ Figura 5-18. Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) @@ -5936,7 +5936,7 @@ Figura 5-18. $ curl http://github.com/mojombo/grit/raw/master/lib/grit/repo.rb > repo.rb - $ git add repo.rb + $ git add repo.rb $ git commit -m 'added repo.rb' [master 484a592] added repo.rb 3 files changed, 459 insertions(+), 2 deletions(-) @@ -5946,7 +5946,7 @@ Figura 5-18. $ curl http://github.com/mojombo/grit/raw/master/lib/grit/repo.rb > repo.rb - $ git add repo.rb + $ git add repo.rb $ git commit -m 'added repo.rb' [master 484a592] added repo.rb 3 files changed, 459 insertions(+), 2 deletions(-) @@ -6091,11 +6091,11 @@ Figura 5-18. - Insert 18333fig0601.png + Insert 18333fig0601.png Figure 6-1. - Insert 18333fig0601.png + Insert 18333fig0601.png Figura 6-1. @@ -6133,11 +6133,11 @@ Figura 6-1. - Insert 18333fig0322.png + Insert 18333fig0322.png Figure 3-22. - Insert 18333fig0322.png + Insert 18333fig0322.png Figura 3-22. @@ -6397,11 +6397,11 @@ Figura 3-22. - Insert 18333fig0404.png + Insert 18333fig0404.png Figure 4-4. - Insert 18333fig0404.png + Insert 18333fig0404.png Figura 4-4. @@ -6483,7 +6483,7 @@ Figura 4-4. - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -6492,7 +6492,7 @@ Figura 4-4. No changes -- Patch already applied. - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -6511,11 +6511,11 @@ Figura 4-4. - Insert 18333fig0311.png + Insert 18333fig0311.png Figure 3-11. - Insert 18333fig0311.png + Insert 18333fig0311.png Figura 3-11. @@ -6723,11 +6723,11 @@ Figura 3-11. - Insert 18333fig0325.png + Insert 18333fig0325.png Figure 3-25. - Insert 18333fig0325.png + Insert 18333fig0325.png Figura 3-25. @@ -7075,11 +7075,11 @@ Figura 3-25. - Insert 18333fig0502.png + Insert 18333fig0502.png Figure 5-2. - Insert 18333fig0502.png + Insert 18333fig0502.png Figura 5-2. @@ -7289,11 +7289,11 @@ Figura 5-2. - Insert 18333fig0338.png + Insert 18333fig0338.png Figure 3-38. - Insert 18333fig0338.png + Insert 18333fig0338.png Figura 3-38. @@ -7509,11 +7509,11 @@ Figura 3-38. - Insert 18333fig0328.png + Insert 18333fig0328.png Figure 3-28. - Insert 18333fig0328.png + Insert 18333fig0328.png Figura 3-28. @@ -7640,11 +7640,11 @@ Figura 3-28. - $ sudo chmod +x /usr/local/bin/extMerge + $ sudo chmod +x /usr/local/bin/extMerge $ sudo chmod +x /usr/local/bin/extDiff - $ sudo chmod +x /usr/local/bin/extMerge + $ sudo chmod +x /usr/local/bin/extMerge $ sudo chmod +x /usr/local/bin/extDiff @@ -8002,7 +8002,7 @@ Figura 3-28. - $ git rm git.tbz2 + $ git rm git.tbz2 rm 'git.tbz2' $ git commit -m 'oops - removed large tarball' [master da3f30d] oops - removed large tarball @@ -8010,7 +8010,7 @@ Figura 3-28. delete mode 100644 git.tbz2 - $ git rm git.tbz2 + $ git rm git.tbz2 rm 'git.tbz2' $ git commit -m 'oops - removed large tarball' [master da3f30d] oops - removed large tarball @@ -8214,11 +8214,11 @@ Figura 3-28. - Insert 18333fig0414.png + Insert 18333fig0414.png Figure 4-14. - Insert 18333fig0414.png + Insert 18333fig0414.png Figura 4-14. @@ -8273,12 +8273,12 @@ Figura 4-14. $ echo 'version 1' > test.txt - $ git hash-object -w test.txt + $ git hash-object -w test.txt 83baae61804e65cc73a7201a7252750c76066a30 $ echo 'version 1' > test.txt - $ git hash-object -w test.txt + $ git hash-object -w test.txt 83baae61804e65cc73a7201a7252750c76066a30 @@ -8386,11 +8386,11 @@ Figura 4-14. - Insert 18333fig0314.png + Insert 18333fig0314.png Figure 3-14. - Insert 18333fig0314.png + Insert 18333fig0314.png Figura 3-14. @@ -8448,11 +8448,11 @@ Figura 3-14. - Insert 18333fig0512.png + Insert 18333fig0512.png Figure 5-12. - Insert 18333fig0512.png + Insert 18333fig0512.png Figura 5-12. @@ -8616,12 +8616,12 @@ Figura 5-12. - $ cat .git/hooks/post-update + $ cat .git/hooks/post-update #!/bin/sh exec git-update-server-info - $ cat .git/hooks/post-update + $ cat .git/hooks/post-update #!/bin/sh exec git-update-server-info @@ -8636,11 +8636,11 @@ Figura 5-12. - Insert 18333fig0327.png + Insert 18333fig0327.png Figure 3-27. - Insert 18333fig0327.png + Insert 18333fig0327.png Figura 3-27. @@ -9049,12 +9049,12 @@ Figura 3-27. $ git symbolic-ref HEAD refs/heads/test - $ cat .git/HEAD + $ cat .git/HEAD ref: refs/heads/test $ git symbolic-ref HEAD refs/heads/test - $ cat .git/HEAD + $ cat .git/HEAD ref: refs/heads/test @@ -9188,7 +9188,7 @@ Figura 3-27. - Enforcing Policies... + Enforcing Policies... (refs/heads/master) (8338c5) (c5b616) [POLICY] Cannot push a non-fast-forward reference error: hooks/update exited with error code 1 @@ -9197,7 +9197,7 @@ Figura 3-27. ! - Enforcing Policies... + Enforcing Policies... (refs/heads/master) (8338c5) (c5b616) [POLICY] Cannot push a non-fast-forward reference error: hooks/update exited with error code 1 @@ -9493,11 +9493,11 @@ Figura 3-27. - Insert 18333fig0517.png + Insert 18333fig0517.png Figure 5-17. - Insert 18333fig0517.png + Insert 18333fig0517.png Figura 5-17. @@ -9597,11 +9597,11 @@ Figura 5-17. - Insert 18333fig0519.png + Insert 18333fig0519.png Figure 5-19. - Insert 18333fig0519.png + Insert 18333fig0519.png Figura 5-19. @@ -10323,11 +10323,11 @@ Figura 5-19. - Insert 18333fig0501.png + Insert 18333fig0501.png Figure 5-1. - Insert 18333fig0501.png + Insert 18333fig0501.png Figura 5-1. @@ -10393,12 +10393,12 @@ Figura 5-1. - (mbox) Adding cc: Jessica Smith <jessica@example.com> from + (mbox) Adding cc: Jessica Smith <jessica@example.com> from \line 'From: Jessica Smith <jessica@example.com>' OK. - (mbox) Adding cc: Jessica Smith <jessica@example.com> from + (mbox) Adding cc: Jessica Smith <jessica@example.com> from \line 'From: Jessica Smith <jessica@example.com>' OK. @@ -10437,8 +10437,8 @@ Figura 5-1. - $ git blame -C -L 141,153 GITPackUpload.m - f344f58d GITServerHandler.m (Scott 2009-01-04 141) + $ git blame -C -L 141,153 GITPackUpload.m + f344f58d GITServerHandler.m (Scott 2009-01-04 141) f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC f344f58d GITServerHandler.m (Scott 2009-01-04 143) { 70befddd GITServerHandler.m (Scott 2009-03-22 144) //NSLog(@"GATHER COMMI @@ -10453,8 +10453,8 @@ Figura 5-1. 56ef2caf GITServerHandler.m (Scott 2009-01-05 153) - $ git blame -C -L 141,153 GITPackUpload.m - f344f58d GITServerHandler.m (Scott 2009-01-04 141) + $ git blame -C -L 141,153 GITPackUpload.m + f344f58d GITServerHandler.m (Scott 2009-01-04 141) f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC f344f58d GITServerHandler.m (Scott 2009-01-04 143) { 70befddd GITServerHandler.m (Scott 2009-03-22 144) //NSLog(@"GATHER COMMI @@ -11055,11 +11055,11 @@ Figura 5-1. - Insert 18333fig0410.png + Insert 18333fig0410.png Figure 4-10. - Insert 18333fig0410.png + Insert 18333fig0410.png Figura 4-10. @@ -11089,11 +11089,11 @@ Figura 4-10. - Insert 18333fig0407.png + Insert 18333fig0407.png Figure 4-7. - Insert 18333fig0407.png + Insert 18333fig0407.png Figura 4-7. @@ -11189,11 +11189,11 @@ Figura 4-7. - Insert 18333fig0309.png + Insert 18333fig0309.png Figure 3-9. - Insert 18333fig0309.png + Insert 18333fig0309.png Figura 3-9. @@ -11295,11 +11295,11 @@ Figura 3-9. - Insert 18333fig0324.png + Insert 18333fig0324.png Figure 3-24. - Insert 18333fig0324.png + Insert 18333fig0324.png Figura 3-24. @@ -11329,11 +11329,11 @@ Figura 3-24. - Insert 18333fig0505.png + Insert 18333fig0505.png Figure 5-5. - Insert 18333fig0505.png + Insert 18333fig0505.png Figura 5-5. @@ -12149,11 +12149,11 @@ Figura 5-5. - Insert 18333fig0513.png + Insert 18333fig0513.png Figure 5-13. - Insert 18333fig0513.png + Insert 18333fig0513.png Figura 5-13. @@ -12735,11 +12735,11 @@ Figura 5-20. - Insert 18333fig0903.png + Insert 18333fig0903.png Figure 9-3. - Insert 18333fig0903.png + Insert 18333fig0903.png Figura 9-3. @@ -12811,11 +12811,11 @@ Figura 9-3. - Insert 18333fig0525.png + Insert 18333fig0525.png Figure 5-25. - Insert 18333fig0525.png + Insert 18333fig0525.png Figura 5-25. @@ -13379,11 +13379,11 @@ Figura 5-25. - Insert 18333fig0313.png + Insert 18333fig0313.png Figure 3-13. - Insert 18333fig0313.png + Insert 18333fig0313.png Figura 3-13. @@ -13413,11 +13413,11 @@ Figura 3-13. - Insert 18333fig0702.png + Insert 18333fig0702.png Figure 7-2. - Insert 18333fig0702.png + Insert 18333fig0702.png Figura 7-2. @@ -13475,11 +13475,11 @@ Figura 7-2. - Insert 18333fig0508.png + Insert 18333fig0508.png Figure 5-8. - Insert 18333fig0508.png + Insert 18333fig0508.png Figura 5-8. @@ -13567,11 +13567,11 @@ Figura 5-8. - Insert 18333fig0337.png + Insert 18333fig0337.png Figure 3-37. - Insert 18333fig0337.png + Insert 18333fig0337.png Figura 3-37. @@ -13869,11 +13869,11 @@ Figura 3-37. - Insert 18333fig0524.png + Insert 18333fig0524.png Figure 5-24. - Insert 18333fig0524.png + Insert 18333fig0524.png Figura 5-24. @@ -14537,13 +14537,13 @@ Figura 5-24. - $ git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30 > test.txt - $ cat test.txt + $ git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30 > test.txt + $ cat test.txt version 1 - $ git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30 > test.txt - $ cat test.txt + $ git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30 > test.txt + $ cat test.txt version 1 @@ -14749,11 +14749,11 @@ Figura 5-24. - Insert 18333fig0506.png + Insert 18333fig0506.png Figure 5-6. - Insert 18333fig0506.png + Insert 18333fig0506.png Figura 5-6. @@ -15059,10 +15059,10 @@ Figura 5-6. - If you add text between the `--` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. + If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. - Si añades texto entre la línea que comienza por `--` y el comienzo del parche (la línea `lib/simplegit.rb). Los desarrolladores de la lista de correo podrán leerlo. Pero será ignorado al aplicar el parche al proyecto. + Si añades texto entre la línea que comienza por `---` y el comienzo del parche (la línea `lib/simplegit.rb). Los desarrolladores de la lista de correo podrán leerlo. Pero será ignorado al aplicar el parche al proyecto. @@ -15395,7 +15395,7 @@ Figura 5-6. - $ ls + $ ls HEAD branches/ config @@ -15407,7 +15407,7 @@ Figura 5-6. refs/ - $ ls + $ ls HEAD branches/ config @@ -15715,11 +15715,11 @@ Figura 5-6. - Insert 18333fig0310.png + Insert 18333fig0310.png Figure 3-10. - Insert 18333fig0310.png + Insert 18333fig0310.png Figura 3-10. @@ -15903,11 +15903,11 @@ Figura 3-10. - Insert 18333fig0509.png + Insert 18333fig0509.png Figure 5-9. - Insert 18333fig0509.png + Insert 18333fig0509.png Figura 5-9. @@ -15937,7 +15937,7 @@ Figura 5-9. - $ git blame -L 12,22 simplegit.rb + $ git blame -L 12,22 simplegit.rb ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 12) def show(tree = 'master') ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 13) command("git show #{tree}") ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 14) end @@ -15945,13 +15945,13 @@ Figura 5-9. 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 16) def log(tree = 'master') 79eaf55d (Scott Chacon 2008-04-06 10:15:08 -0700 17) command("git log #{tree}") 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 18) end - 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 19) + 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 19) 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20) def blame(path) 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21) command("git blame #{path}") 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22) end - $ git blame -L 12,22 simplegit.rb + $ git blame -L 12,22 simplegit.rb ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 12) def show(tree = 'master') ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 13) command("git show #{tree}") ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 14) end @@ -15959,7 +15959,7 @@ Figura 5-9. 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 16) def log(tree = 'master') 79eaf55d (Scott Chacon 2008-04-06 10:15:08 -0700 17) command("git log #{tree}") 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 18) end - 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 19) + 9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 19) 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20) def blame(path) 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21) command("git blame #{path}") 42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22) end @@ -16039,11 +16039,11 @@ Figura 5-9. - Insert 18333fig0307.png + Insert 18333fig0307.png Figure 3-7. - Insert 18333fig0307.png + Insert 18333fig0307.png Figura 3-7. @@ -16103,13 +16103,13 @@ Figura 3-7. - $ find .git/objects -type f + $ find .git/objects -type f .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a .git/objects/83/baae61804e65cc73a7201a7252750c76066a30 .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 - $ find .git/objects -type f + $ find .git/objects -type f .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a .git/objects/83/baae61804e65cc73a7201a7252750c76066a30 .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 @@ -16387,11 +16387,11 @@ Figura 3-7. - Insert 18333fig0503.png + Insert 18333fig0503.png Figure 5-3. - Insert 18333fig0503.png + Insert 18333fig0503.png Figura 5-3. @@ -16701,11 +16701,11 @@ Figura 5-3. - Insert 18333fig0411.png + Insert 18333fig0411.png Figure 4-11. - Insert 18333fig0411.png + Insert 18333fig0411.png Figura 4-11. @@ -17149,11 +17149,11 @@ Figura 4-11. - Insert 18333fig0901.png + Insert 18333fig0901.png Figure 9-1. - Insert 18333fig0901.png + Insert 18333fig0901.png Figura 9-1. @@ -17231,11 +17231,11 @@ Figura 9-1. - Enforcing Policies... + Enforcing Policies... (refs/heads/master) (fb8c72) (c56860) - Enforcing Policies... + Enforcing Policies... (refs/heads/master) (fb8c72) (c56860) @@ -17730,11 +17730,11 @@ Figura 9-1. - Insert 18333fig0406.png + Insert 18333fig0406.png Figure 4-6. - Insert 18333fig0406.png + Insert 18333fig0406.png Figura 4-6. @@ -18336,11 +18336,11 @@ Figura 4-6. - $ cat .git/HEAD + $ cat .git/HEAD ref: refs/heads/test - $ cat .git/HEAD + $ cat .git/HEAD ref: refs/heads/test @@ -18531,12 +18531,12 @@ Figura 4-6. $ cat /usr/local/bin/extMerge - #!/bin/sh + #!/bin/sh /Applications/kdiff3.app/Contents/MacOS/kdiff3 $* $ cat /usr/local/bin/extMerge - #!/bin/sh + #!/bin/sh /Applications/kdiff3.app/Contents/MacOS/kdiff3 $* @@ -18964,11 +18964,11 @@ Figura 4-6. - Insert 18333fig0516.png + Insert 18333fig0516.png Figure 5-16. - Insert 18333fig0516.png + Insert 18333fig0516.png Figura 5-16. @@ -19086,11 +19086,11 @@ Figura 5-16. - If the book spontaneously + If the book spontaneously +s going on, modify stuff and contribute changes. - If the book spontaneously + If the book spontaneously +s going on, modify stuff and contribute changes. @@ -19141,12 +19141,12 @@ Figura 5-16. def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty @@ -19184,11 +19184,11 @@ Figura 5-16. - Insert 18333fig0321.png + Insert 18333fig0321.png Figure 3-21. - Insert 18333fig0321.png + Insert 18333fig0321.png Figura 3-21. @@ -19360,11 +19360,11 @@ Figura 3-21. - Insert 18333fig0515.png + Insert 18333fig0515.png Figure 5-15. - Insert 18333fig0515.png + Insert 18333fig0515.png Figura 5-15. @@ -19750,11 +19750,11 @@ Figura 5-15. - Insert 18333fig0304.png + Insert 18333fig0304.png Figure 3-4. - Insert 18333fig0304.png + Insert 18333fig0304.png Figura 3-4. @@ -20064,13 +20064,13 @@ Figura 3-4. - $ echo '# testing' >> repo.rb + $ echo '# testing' >> repo.rb $ git commit -am 'modified repo a bit' [master ab1afef] modified repo a bit 1 files changed, 1 insertions(+), 0 deletions(-) - $ echo '# testing' >> repo.rb + $ echo '# testing' >> repo.rb $ git commit -am 'modified repo a bit' [master ab1afef] modified repo a bit 1 files changed, 1 insertions(+), 0 deletions(-) @@ -20091,10 +20091,10 @@ Figura 3-4. $ git log --pretty=format:'%h %s' --graph * 734713b fixed refs handling, added gc auto, updated tests * d921970 Merge commit 'phedders/rdocs' - |\ + |\ | * 35cfb2b Some rdoc changes * | 1c002dd added some blame and merge stuff - |/ + |/ * 1c36188 ignore *.gem * 9b29157 add open3_detach to gemspec file list @@ -20102,10 +20102,10 @@ Figura 3-4. $ git log --pretty=format:'%h %s' --graph * 734713b fixed refs handling, added gc auto, updated tests * d921970 Merge commit 'phedders/rdocs' - |\ + |\ | * 35cfb2b Some rdoc changes * | 1c002dd added some blame and merge stuff - |/ + |/ * 1c36188 ignore *.gem * 9b29157 add open3_detach to gemspec file list @@ -20670,13 +20670,13 @@ Figura 3-4. $ rm text.txt $ git checkout -- text.txt - $ cat test.txt + $ cat test.txt $Id: 42812b7653c7b88933f8a9d6cad0ca16714b9bb3 $ $ rm text.txt $ git checkout -- text.txt - $ cat test.txt + $ cat test.txt $Id: 42812b7653c7b88933f8a9d6cad0ca16714b9bb3 $ @@ -20860,11 +20860,11 @@ Figura 3-4. - Insert 18333fig0703.png + Insert 18333fig0703.png Figure 7-3. - Insert 18333fig0703.png + Insert 18333fig0703.png Figura 7-3. @@ -20952,11 +20952,11 @@ Figura 7-3. - Insert 18333fig0523.png + Insert 18333fig0523.png Figure 5-23. - Insert 18333fig0523.png + Insert 18333fig0523.png Figura 5-23. @@ -21044,11 +21044,11 @@ Figura 5-23. - Insert 18333fig0333.png + Insert 18333fig0333.png Figure 3-33. - Insert 18333fig0333.png + Insert 18333fig0333.png Figura 3-33. @@ -21192,11 +21192,11 @@ Figura 3-33. - Insert 18333fig0326.png + Insert 18333fig0326.png Figure 3-26. - Insert 18333fig0326.png + Insert 18333fig0326.png Figura 3-26. @@ -21378,11 +21378,11 @@ Figura 3-26. - $ find .git/objects -type f + $ find .git/objects -type f .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 - $ find .git/objects -type f + $ find .git/objects -type f .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 @@ -21420,18 +21420,18 @@ Figura 3-26. - Insert 18333fig0332.png + Insert 18333fig0332.png Figure 3-32. - Insert 18333fig0332.png + Insert 18333fig0332.png Figura 3-32. After all this is set, if you run diff commands such as this: - + $ git diff 32d1776b1^ 32d1776b1 @@ -21464,11 +21464,11 @@ Figura 3-32. - Insert 18333fig0319.png + Insert 18333fig0319.png Figure 3-19. - Insert 18333fig0319.png + Insert 18333fig0319.png Figura 3-19. @@ -21482,11 +21482,11 @@ Figura 3-19. - Insert 18333fig0510.png + Insert 18333fig0510.png Figure 5-10. - Insert 18333fig0510.png + Insert 18333fig0510.png Figura 5-10. @@ -21562,11 +21562,11 @@ Figura 5-10. - Insert 18333fig0526.png + Insert 18333fig0526.png Figure 5-26. - Insert 18333fig0526.png + Insert 18333fig0526.png Figura 5-26. @@ -21907,11 +21907,11 @@ Figura 5-26. - In Chapter Two we will go over basic Git usage - how to use Git for the 80% + In Chapter Two we will go over basic Git usage - how to use Git for the 80% -s going on, modify stuff and contribute changes. - In Chapter Two we will go over basic Git usage - how to use Git for the 80% + In Chapter Two we will go over basic Git usage - how to use Git for the 80% -s going on, modify stuff and contribute changes. @@ -22235,11 +22235,11 @@ Figura 5-26. - Insert 18333fig0301.png + Insert 18333fig0301.png Figure 3-1. - Insert 18333fig0301.png + Insert 18333fig0301.png Figura 3-1. @@ -22264,7 +22264,7 @@ Figura 3-1. $ git log -g master commit 734713bc047d87bf7eac9674765ae793478c50d3 Reflog: master@{0} (Scott Chacon <schacon@gmail.com>) - Reflog message: commit: fixed refs handling, added gc auto, updated + Reflog message: commit: fixed refs handling, added gc auto, updated Author: Scott Chacon <schacon@gmail.com> Date: Fri Jan 2 18:32:33 2009 -0800 @@ -22272,7 +22272,7 @@ Figura 3-1. $ git log -g master commit 734713bc047d87bf7eac9674765ae793478c50d3 Reflog: master@{0} (Scott Chacon <schacon@gmail.com>) - Reflog message: commit: fixed refs handling, added gc auto, updated + Reflog message: commit: fixed refs handling, added gc auto, updated Author: Scott Chacon <schacon@gmail.com> Date: Fri Jan 2 18:32:33 2009 -0800 @@ -22360,13 +22360,13 @@ Figura 3-1. $ (fix the file) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem $ (fix the file) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem @@ -23076,11 +23076,11 @@ Figura 3-1. - Insert 18333fig0317.png + Insert 18333fig0317.png Figure 3-17. - Insert 18333fig0317.png + Insert 18333fig0317.png Figura 3-17. @@ -23490,11 +23490,11 @@ Figura 3-17. - Insert 18333fig0405.png + Insert 18333fig0405.png Figure 4-5. - Insert 18333fig0405.png + Insert 18333fig0405.png Figura 4-5. @@ -23540,11 +23540,11 @@ Figura 4-5. - Insert 18333fig0335.png + Insert 18333fig0335.png Figure 3-35. - Insert 18333fig0335.png + Insert 18333fig0335.png Figura 3-35. @@ -23574,11 +23574,11 @@ Figura 3-35. - Insert 18333fig0339.png + Insert 18333fig0339.png Figure 3-39. - Insert 18333fig0339.png + Insert 18333fig0339.png Figura 3-39. @@ -23600,11 +23600,11 @@ Figura 3-39. - Insert 18333fig0412.png + Insert 18333fig0412.png Figure 4-12. - Insert 18333fig0412.png + Insert 18333fig0412.png Figura 4-12. @@ -24114,11 +24114,11 @@ Figura 4-12. - $ cat gitosis.conf + $ cat gitosis.conf [gitosis] - $ cat gitosis.conf + $ cat gitosis.conf [gitosis] @@ -24326,11 +24326,11 @@ Figura 4-12. - Insert 18333fig0415.png + Insert 18333fig0415.png Figure 4-15. - Insert 18333fig0415.png + Insert 18333fig0415.png Figura 4-15. @@ -24688,11 +24688,11 @@ Figura 4-15. - Insert 18333fig0308.png + Insert 18333fig0308.png Figure 3-8. - Insert 18333fig0308.png + Insert 18333fig0308.png Figura 3-8. @@ -24932,13 +24932,13 @@ Figura 3-8. - $ git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > test.txt - $ cat test.txt + $ git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > test.txt + $ cat test.txt version 2 - $ git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > test.txt - $ cat test.txt + $ git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > test.txt + $ cat test.txt version 2 @@ -25570,11 +25570,11 @@ Figura 3-8. - Insert 18333fig0312.png + Insert 18333fig0312.png Figure 3-12. - Insert 18333fig0312.png + Insert 18333fig0312.png Figura 3-12. @@ -25782,11 +25782,11 @@ Figura 3-12. - Insert 18333fig0413.png + Insert 18333fig0413.png Figure 4-13. - Insert 18333fig0413.png + Insert 18333fig0413.png Figura 4-13. @@ -26039,12 +26039,12 @@ Figura 4-13. $ echo 'new file' > new.txt - $ git update-index test.txt + $ git update-index test.txt $ git update-index --add new.txt $ echo 'new file' > new.txt - $ git update-index test.txt + $ git update-index test.txt $ git update-index --add new.txt @@ -26134,11 +26134,11 @@ Figura 4-13. - Insert 18333fig0329.png + Insert 18333fig0329.png Figure 3-29. - Insert 18333fig0329.png + Insert 18333fig0329.png Figura 3-29. @@ -26835,11 +26835,11 @@ Figura 3-29. - Insert 18333fig0331.png + Insert 18333fig0331.png Figure 3-31. - Insert 18333fig0331.png + Insert 18333fig0331.png Figura 3-31. @@ -26853,11 +26853,11 @@ Figura 3-31. - Insert 18333fig0527.png + Insert 18333fig0527.png Figure 5-27. - Insert 18333fig0527.png + Insert 18333fig0527.png Figura 5-27. @@ -27007,13 +27007,13 @@ Figura 5-27. - $ cat .gitmodules + $ cat .gitmodules [submodule "rack"] path = rack url = git://github.com/chneukirchen/rack.git - $ cat .gitmodules + $ cat .gitmodules [submodule "rack"] path = rack url = git://github.com/chneukirchen/rack.git @@ -27021,11 +27021,11 @@ Figura 5-27. - Update>> + Update>> updated 2 paths - Update>> + Update>> updated 2 paths @@ -27121,11 +27121,11 @@ Figura 5-27. - $ cat .git/refs/tags/v1.1 + $ cat .git/refs/tags/v1.1 9585191f37f7b0fb9444f35a9bf50de191beadc2 - $ cat .git/refs/tags/v1.1 + $ cat .git/refs/tags/v1.1 9585191f37f7b0fb9444f35a9bf50de191beadc2 @@ -27147,11 +27147,11 @@ Figura 5-27. - Insert 18333fig0514.png + Insert 18333fig0514.png Figure 5-14. - Insert 18333fig0514.png + Insert 18333fig0514.png Figura 5-14. @@ -27519,8 +27519,8 @@ Figura 5-14. - $ cat .git/packed-refs - # pack-refs with: peeled + $ cat .git/packed-refs + # pack-refs with: peeled cac0cab538b970a37ea1e769cbbde608743bc96d refs/heads/experiment ab1afef80fac8e34258ff41fc1b867c702daa24b refs/heads/master cac0cab538b970a37ea1e769cbbde608743bc96d refs/tags/v1.0 @@ -27528,8 +27528,8 @@ Figura 5-14. ^1a410efbd13591db07496601ebc7a059dd55cfe9 - $ cat .git/packed-refs - # pack-refs with: peeled + $ cat .git/packed-refs + # pack-refs with: peeled cac0cab538b970a37ea1e769cbbde608743bc96d refs/heads/experiment ab1afef80fac8e34258ff41fc1b867c702daa24b refs/heads/master cac0cab538b970a37ea1e769cbbde608743bc96d refs/tags/v1.0 @@ -27687,11 +27687,11 @@ Figura 5-14. - $ ssh-keygen + $ ssh-keygen Generating public/private rsa key pair. - $ ssh-keygen + $ ssh-keygen Generating public/private rsa key pair. @@ -27745,11 +27745,11 @@ Figura 5-14. - Insert 18333fig0320.png + Insert 18333fig0320.png Figure 3-20. - Insert 18333fig0320.png + Insert 18333fig0320.png Figura 3-20. @@ -28105,12 +28105,12 @@ Figura 3-20. - [Jessica Smith <jessica@example.com>] + [Jessica Smith <jessica@example.com>] Emails will be sent from: Jessica Smith <jessica@example.com> Who should the emails be sent to? - [Jessica Smith <jessica@example.com>] + [Jessica Smith <jessica@example.com>] Emails will be sent from: Jessica Smith <jessica@example.com> Who should the emails be sent to? @@ -28165,11 +28165,11 @@ Figura 3-20. - Insert 18333fig0521.png + Insert 18333fig0521.png Figure 5-21. - Insert 18333fig0521.png + Insert 18333fig0521.png Figura 5-21. @@ -28908,7 +28908,7 @@ Figura 5-21. Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) @@ -28919,7 +28919,7 @@ Figura 5-21. Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/fr/05-distributed-git/01-chapter5.markdown b/fr/05-distributed-git/01-chapter5.markdown index 8457ee105..19716edfd 100644 --- a/fr/05-distributed-git/01-chapter5.markdown +++ b/fr/05-distributed-git/01-chapter5.markdown @@ -658,7 +658,7 @@ Le contenu des fichiers ressemble à ceci : 1.6.2.rc1.20.g8c5b.dirty Vous pouvez maintenant éditer ces fichiers de patch pour ajouter plus d'informations à destination de la liste de diffusion mais que vous ne souhaitez pas voir apparaître dans le message de validation. -Si vous ajoutez du texte entre la ligne `--` et le début du patch (la ligne `lib/simplegit.rb`), les développeurs peuvent le lire mais l'application du patch ne le prend pas en compte. +Si vous ajoutez du texte entre la ligne `---` et le début du patch (la ligne `lib/simplegit.rb`), les développeurs peuvent le lire mais l'application du patch ne le prend pas en compte. Pour envoyer par e-mail ces fichiers, vous pouvez soit copier leur contenu dans votre application d'e-mail, soit l'envoyer via une ligne de commande. Le copier-coller cause souvent des problèmes de formatage, spécialement avec les applications « intelligentes » qui ne préservent pas les retours à la ligne et les types d'espace. diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 44f156607..07a3b7ffc 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -12,7 +12,7 @@ A differenza dei gestori di versione centralizzati (CVCSs), la natura distribuit Nei sistemi centralizzati, generalmente c'è un modo solo di collaborare. Un fulcro centrale, o repository, può accettare il codice e tutti sincronizzano il lavoro con questo. Un numero di sviluppatori sono nodi - rispetto al fulcro - e restano sincronizzati rispetto ad un luogo centrale (vedi Figura 5-1). -Insert 18333fig0501.png +Insert 18333fig0501.png Figura 5-1. Worlflow centralizzato Questo significa che se due sviluppatori clonano dal fulcro ed entrambi fanno dei cambiamenti, il primo sviluppatore che eseguirà un push verso il fulcro non avrà problemi. Il secondo invece, dovrà unire al proprio il lavoro effettuato dal primo, prima di fare un push dei cambiamenti, per non sovrascrivere il lavoro del primo. Questo accade in Git come in Subversion (o un altro CVCS), e funziona tranquillamente in Git. @@ -31,7 +31,7 @@ Dato che Git ti consente di avere multipli repositories, è possibile avere un w 5. Il mantenitore aggiunge il repository del contributore come remoto e fa un merge in locale dei cambiamenti. 6. Il mantenitore fa un push dei cambiamenti (compresi quelli aggiunti dal contributore) verso il repository principale. -Insert 18333fig0502.png +Insert 18333fig0502.png Figura 5-2. Workflow con manager d'integrazione Questo è un workflow comune con siti come GitHub, dove è facile eseguire un fork di un progetto e fare un push dei propri cambiamenti dentro al proprio fork, in modo che tutti possano accedere. Uno dei maggiori vantaggi di questo approccio è che puoi continuare il tuo lavoro, ed il mantenitore del repository principale può eseguire un pull dei tuoi cambiamenti in qualsiasi momento. I contributori non devono aspettare che il progetto incorpori i propri camiamenti, ed ognuno può lavorare per conto suo. @@ -45,7 +45,7 @@ Questa è una variante del workflow con multipli repository. E' generalmente usa 3. Il dittatore esegue l'unione dei rami master dei tenenti nel proprio ramo master. 4. Il dittatore esegue un push del proprio ramo master nel repository di riferimento, cosicché gli sviluppatori possano accedervi. -Insert 18333fig0503.png +Insert 18333fig0503.png Figura 5.3. Workflow con dittatore benevolo. Questo tipo di workflow non è comune ma può essere utile in progetti davvero grandi, o in ambienti con una stretta gerarchia, perché consente al leader del progetto (il dittatore) di delegare molto del lavoro e raccogliere vasti sottoinsiemi di codice in momenti diversi prima di integrarli. @@ -121,7 +121,7 @@ Vediamo come potrebbe essere la situazione quando due sviluppatori iniziano a la Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'rimosso valore di default non valido' [master 738ee87] rimosso valore di default non valido 1 files changed, 1 insertions(+), 1 deletions(-) @@ -133,7 +133,7 @@ Il secondo sviluppatore, Jessica, fa la stessa cosa - clona il repository ed ese Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'aggiunto il processo di reset' [master fbff5bc] aggiunto il processo di reset 1 files changed, 1 insertions(+), 0 deletions(-) @@ -163,7 +163,7 @@ A John non è consentito eseguire un push perché Jessica ha fatto lo stesso nel A questo punto, il repository locale di John somiglia a quello di figura 5-4. -Insert 18333fig0504.png +Insert 18333fig0504.png Figura 5-4. Il repository iniziale di John. John ha a disposizione i cambiamenti che Jessica ha eseguito, ma deve unirli ai suoi prima di avere la possibilità di eseguire un push: @@ -175,7 +175,7 @@ John ha a disposizione i cambiamenti che Jessica ha eseguito, ma deve unirli ai L'unione fila liscia - ora la cronologia dei commit di John sarà come quella di Figura 5-5. -Insert 18333fig0505.png +Insert 18333fig0505.png Figura 5-5. Il repository di John dopo aver unito origin/master. Ora, John può testare il suo codice per essere sicuro che funzioni anche correttamente e può eseguire il push del tutto verso il server: @@ -187,12 +187,12 @@ Ora, John può testare il suo codice per essere sicuro che funzioni anche corret Infine, la cronologia dei commit di John somiglierà a quella di figura 5-6. -Insert 18333fig0506.png +Insert 18333fig0506.png Figura 5-6. La cronologia di John dopo avere eseguito il push verso il server. Nel frattempo, Jessica sta lavorando su un altro ramo. Ha creato un ramo chiamato `problema54` ed ha eseguito tre commit su quel ramo. Non ha ancora recuperato i cambiamenti di John, per cui la sua cronologia di commit è quella di Figura 5-7. -Insert 18333fig0507.png +Insert 18333fig0507.png Figura 5-7. La cronologia iniziale di Jessica. Jessica vuole sincronizzarsi con John, così recupera: @@ -205,7 +205,7 @@ Jessica vuole sincronizzarsi con John, così recupera: Questo recupera il lavoro che John ha eseguito nel frattempo. La cronologia di Jessica ora è quella di Figura 5-8. -Insert 18333fig0508.png +Insert 18333fig0508.png Figura 5-8. La cronologia di Jessica dopo aver recuperato i cambiamenti di John. Jessica pensa che il suo ramo sia pronto, però vuole sapere con cosa deve unire il suo lavoro prima di eseguire il push. Esegue `git log` per scoprirlo: @@ -242,7 +242,7 @@ Non ci sono problemi; come puoi vederem è stato tutto semplice. Ora Jessica uni Tutto viene unito correttamente, e la cronologia di Jessica è come quella di Figura 5-9. -Insert 18333fig0509.png +Insert 18333fig0509.png Figura 5-9. La cronologia di Jessica dopo aver unito i cambiamenti di John. Ora `origin/master` è raggiungibile dal ramo `master` di Jessica, cosicché lei sia capace di eseguire dei push successivamente (assumento che John non abbia fatto lo stesso nel frattempo): @@ -305,7 +305,7 @@ Ora, Jessica esegue un paio di commit sul ramo `funzionalitaB`: Il repository di Jessica è come quello di Figura 5-12. -Insert 18333fig0512.png +Insert 18333fig0512.png Figura 5.12. La cronologia iniziale dei commit di Jessica Figure 5-12. Jessica’s initial commit history. @@ -371,7 +371,7 @@ Jessica vuole aggiustare qualcosa, così esegue un altro commit ed un push verso Ora la cronologia dei commit di Jessica sarà come quella di Figura 5-13. -Insert 18333fig0513.png +Insert 18333fig0513.png Figura 5-13. La cronologia di Jessica dopo aver eseguito il commit sul ramo. Jessica, Josie e John informano gli integratori che i rami `funzionalitaA` e `funzionalitaB` sono sul server e pronti per l'integrazione nel ramo `master`. Dopo l'integrazione di questi rami nel `master`, un recupero del ramo principale aggiungerà anche i nuovi commit, rendendo la cronologia dei commit come quella di figura 5.14. @@ -441,7 +441,7 @@ Su un progetto dove non sei il mantenitore, è generalmente comune avere un ramo Ora, ognuno dei tuoi lavori è separato, simile ad una coda di modifiche. Puoi riscrivere, modificare o effettuare un rebase, senza che i rami interferiscano o dipendano l'uno dall'altro, come in Figura 5-16. -Insert 18333fig0516.png +Insert 18333fig0516.png Figura 5-16. Conologia iniziale dei commit con del lavoro su funzionalitaB. Diciamo che il mantenitore del progetto ha eseguito il pull, una manciata di altre modifiche e provato il tuo primo ramo ma non riesce più ad applicare tali modifiche in maniera pulita. In questo caso, puoi provare ad effettuare un rebase di quel ramo basandoti sul nuovo `origin/master`, risolvere i conflitti e poi inviare di nuovo i tuoi cambiamenti: @@ -492,7 +492,7 @@ Ora hai due commit che vuoi inviare alla mailing list. Usi `git format-patch` pe Il comando `format-patch` visualizza i nomi dei file patch che vengono creati. Il parametro `-M` indica a Git di tener traccia dei file rinominati. I file infine hanno questo aspetto: - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith Date: Sun, 6 Apr 2008 10:17:23 -0700 @@ -517,10 +517,10 @@ Il comando `format-patch` visualizza i nomi dei file patch che vengono creati. I end def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty -Puoi anche modificare questi file patch per aggiungere maggiori informazioni per la mailing list che non vuoi vengano visualizzate all'interno del messaggio del commit. Se aggiungi del testo tra le righe contrassegnate da `--` e l'inizio della patch (ad esempio la riga `lib/simplegit.rb`), gli sviluppatori possono leggerlo ma esso verrà escluso dal messaggio del commit con il quale la patch verrà applicata. +Puoi anche modificare questi file patch per aggiungere maggiori informazioni per la mailing list che non vuoi vengano visualizzate all'interno del messaggio del commit. Se aggiungi del testo tra le righe contrassegnate da `---` e l'inizio della patch (ad esempio la riga `lib/simplegit.rb`), gli sviluppatori possono leggerlo ma esso verrà escluso dal messaggio del commit con il quale la patch verrà applicata. Per inviare le patch alla mailing list, puoi copiare ed incollare il file nel tuo programma di posta o inviare il tutto tramite un programma a linea di comando. Incollando il testo spesso si hanno dei problemi di formattazione, sopratutto con client di posta "intelligenti" che non preservano i caratteri di acapo e altri caratteri di spaziatura. Fortunatamente, Git fornisce uno strumento per aiutarti ad inviare le patch in modo corretto tramite IMAP, il che potrebbe risultare più semplice. Ti mostrerò come inviare una patch via Gmail, che è il client di posta che utilizzo io; puoi trovare le istruzioni dettagliate per diversi client di posta alla fine del documento `Documention/SubmittingPatches` presente nel codice sorgente di Git. @@ -539,14 +539,14 @@ Se il tuo server IMAP non usa SSL, le ultime due righe probabilmente non ti sara $ git send-email *.patch 0001-added-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch - Who should the emails appear to be from? [Jessica Smith ] + Who should the emails appear to be from? [Jessica Smith ] Emails will be sent from: Jessica Smith Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y Poi, Git produce alcune informazioni di log che figureranno più o meno così per ogni patch che stai inviando: - (mbox) Adding cc: Jessica Smith from + (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' OK. Log says: Sendmail: /usr/sbin/sendmail -i jessica@example.com @@ -597,7 +597,7 @@ Ciò modifica i file nella tua directory corrente. E' quasi uguale ad eseguire i Puoi usare `git apply` anche per vedere se una patch può essere applicata in maniera pulita prima di applicarla veramente. Puoi eseguire `git apply --check` sulla patch: - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -616,11 +616,11 @@ To apply a patch generated by `format-patch`, you use `git am`. Technically, `gi Limit log functionality to the first 20 -This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. +This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: @@ -636,11 +636,11 @@ You can see that it applied cleanly and automatically created the new commit for Limit log functionality to the first 20 -The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. +The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -652,13 +652,13 @@ But it’s possible that the patch won’t apply cleanly. Perhaps your main bran This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: $ (fix the file) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -675,7 +675,7 @@ If you’re applying a number of patches from an mbox, you can also run the `am` -------------------------- seeing if this helps the gem -------------------------- - Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all + Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. @@ -739,7 +739,7 @@ Technically, you can do that by explicitly figuring out the common ancestor and $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 - $ git diff 36c7db + $ git diff 36c7db However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: @@ -755,7 +755,7 @@ When all the work in your topic branch is ready to be integrated into a more mai One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. -Insert 18333fig0519.png +Insert 18333fig0519.png Figure 5-19. History with several topic branches. Insert 18333fig0520.png @@ -765,13 +765,13 @@ That is probably the simplest workflow, but it’s problematic if you’re deali If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). -Insert 18333fig0521.png +Insert 18333fig0521.png Figure 5-21. Before a topic branch merge. -Insert 18333fig0522.png +Insert 18333fig0522.png Figure 5-22. After a topic branch merge. -Insert 18333fig0523.png +Insert 18333fig0523.png Figure 5-23. After a topic branch release. This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. @@ -781,12 +781,12 @@ You can also continue this concept, having an integrate branch where all the wor The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. -Insert 18333fig0524.png +Insert 18333fig0524.png Figure 5-24. Managing a complex series of parallel contributed topic branches. If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). -Insert 18333fig0525.png +Insert 18333fig0525.png Figure 5-25. Merging contributed topic branches into long-term integration branches. When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. @@ -797,7 +797,7 @@ Other maintainers prefer to rebase or cherry-pick contributed work on top of the The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. -Insert 18333fig0526.png +Insert 18333fig0526.png Figure 5-26. Example history before a cherry pick. If you want to pull commit `e43a6` into your master branch, you can run @@ -809,7 +809,7 @@ If you want to pull commit `e43a6` into your master branch, you can run This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. -Insert 18333fig0527.png +Insert 18333fig0527.png Figure 5-27. History after cherry-picking a commit on a topic branch. Now you can remove your topic branch and drop the commits you didn’t want to pull in. diff --git a/mk/05-distributed-git/01-chapter5.markdown b/mk/05-distributed-git/01-chapter5.markdown index 00c54ab83..8b631a7a9 100644 --- a/mk/05-distributed-git/01-chapter5.markdown +++ b/mk/05-distributed-git/01-chapter5.markdown @@ -12,7 +12,7 @@ Кај централизираните системи, генерално постои еден колаборациски модел - централи-зиран начин на работа. Една централна осовина (hub), или репозитори кое што може да прифаќа изворен код, и сите ја синхронизираат својата работа во однос на тоа репозитори. Девелоперите се јазли(nodes) - конзументи на таа осовина - и ја синхронизираат својата работа кон тоа едно место (види слика 5-1). -Insert 18333fig0501.png +Insert 18333fig0501.png Слика 5-1. Централизиран начин на работа. Тоа значи дека ако два девелопери клонираат од тој хаб и двајцата направат промена, првиот девелопер кој што ќе ги уфрли(push) неговите измени во хабот - тоа ќе го направи без проблем. Вториот девелопер мора да ги спои (merge) неговите измени со измените од првиот девелопер пред да ги уфрли во заедничкото репозитори, за да не бидат пребришани измените од првиот девелопер. Овој коцепт важи и кај Git како што важи и во Subversion (или било кој CVCS), и одлично работи во Git. @@ -31,7 +31,7 @@ Insert 18333fig0501.png 5. Одржувачот го додава репозиторито на учесникот како оддалечено и ги спојува изме-ните локално. 6. Одржувачот ги уфрла(push) споените измени во главното репозитори. -Insert 18333fig0502.png +Insert 18333fig0502.png Слика 5-2. Начин на работа на Менаџер за Интеграција. Ова е вообичаен начин на работа кај сајтовите како GitHub, каде што е многу лесно да направите нова гранка од проектот (fork), и да ги уфрлате вашите измени во вашата гранка за да може сите да ги видат. Една од главните предности на овој пристап е тоа што може да си продолжите со работа, а одржувачот на проектот може да ги повлече вашите измени во било кое време. Учесниците не мора да чекаат нивните измени да бидат вклучени во проектот - секој може да си работи според свое темпо. @@ -45,7 +45,7 @@ This is a variant of a multiple-repository workflow. It’s generally used by hu 3. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 4. The dictator pushes their master to the reference repository so the other developers can rebase on it. -Insert 18333fig0503.png +Insert 18333fig0503.png Figure 5-3. Benevolent dictator workflow. This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, because as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. @@ -119,7 +119,7 @@ Let’s see what it might look like when two developers start to work together w Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) @@ -131,7 +131,7 @@ The second developer, Jessica, does the same thing — clones the repository and Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) @@ -161,7 +161,7 @@ John isn’t allowed to push because Jessica has pushed in the meantime. This is At this point, John’s local repository looks something like Figure 5-4. -Insert 18333fig0504.png +Insert 18333fig0504.png Figure 5-4. John’s initial repository. John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: @@ -173,7 +173,7 @@ John has a reference to the changes Jessica pushed up, but he has to merge them The merge goes smoothly — John’s commit history now looks like Figure 5-5. -Insert 18333fig0505.png +Insert 18333fig0505.png Figure 5-5. John’s repository after merging origin/master. Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: @@ -185,12 +185,12 @@ Now, John can test his code to make sure it still works properly, and then he ca Finally, John’s commit history looks like Figure 5-6. -Insert 18333fig0506.png +Insert 18333fig0506.png Figure 5-6. John’s history after pushing to the origin server. In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. -Insert 18333fig0507.png +Insert 18333fig0507.png Figure 5-7. Jessica’s initial commit history. Jessica wants to sync up with John, so she fetches: @@ -203,7 +203,7 @@ Jessica wants to sync up with John, so she fetches: That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. -Insert 18333fig0508.png +Insert 18333fig0508.png Figure 5-8. Jessica’s history after fetching John’s changes. Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: @@ -240,7 +240,7 @@ No problems occur; as you can see it, was a simple fast-forward. Now Jessica mer Everything merges cleanly, and Jessica’s history looks like Figure 5-9. -Insert 18333fig0509.png +Insert 18333fig0509.png Figure 5-9. Jessica’s history after merging John’s changes. Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): @@ -252,12 +252,12 @@ Now `origin/master` is reachable from Jessica’s `master` branch, so she should Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. -Insert 18333fig0510.png +Insert 18333fig0510.png Figure 5-10. Jessica’s history after pushing all changes back to the server. That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it’s ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. -Insert 18333fig0511.png +Insert 18333fig0511.png Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. ### Private Managed Team ### @@ -303,7 +303,7 @@ Now, Jessica makes a couple of commits on the `featureB` branch: Jessica’s repository looks like Figure 5-12. -Insert 18333fig0512.png +Insert 18333fig0512.png Figure 5-12. Jessica’s initial commit history. She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: @@ -368,17 +368,17 @@ Jessica wants to tweak something, so she commits again and then pushes this back Jessica’s commit history now looks something like Figure 5-13. -Insert 18333fig0513.png +Insert 18333fig0513.png Figure 5-13. Jessica’s history after committing on a feature branch. Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. -Insert 18333fig0514.png +Insert 18333fig0514.png Figure 5-14. Jessica’s history after merging both her topic branches. Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. -Insert 18333fig0515.png +Insert 18333fig0515.png Figure 5-15. Basic sequence of this managed-team workflow. ### Public Small Project ### @@ -438,7 +438,7 @@ On a project for which you’re not the maintainer, it’s generally easier to h Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. -Insert 18333fig0516.png +Insert 18333fig0516.png Figure 5-16. Initial commit history with featureB work. Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: @@ -449,7 +449,7 @@ Let’s say the project maintainer has pulled in a bunch of other patches and tr This rewrites your history to now look like Figure 5-17. -Insert 18333fig0517.png +Insert 18333fig0517.png Figure 5-17. Commit history after featureA work. Because you rebased the branch, you have to specify the `–f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). @@ -466,7 +466,7 @@ The `--squash` option takes all the work on the merged branch and squashes it in Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). -Insert 18333fig0518.png +Insert 18333fig0518.png Figure 5-18. Commit history after featureBv2 work. ### Public Large Project ### @@ -489,7 +489,7 @@ Now you have two commits that you want to send to the mailing list. You use `git The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith Date: Sun, 6 Apr 2008 10:17:23 -0700 @@ -514,10 +514,10 @@ The `format-patch` command prints out the names of the patch files it creates. T end def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty -You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `--` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. +You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. @@ -537,14 +537,14 @@ When that is set up, you can use `git send-email` to place the patch series in t $ git send-email *.patch 0001-added-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch - Who should the emails appear to be from? [Jessica Smith ] + Who should the emails appear to be from? [Jessica Smith ] Emails will be sent from: Jessica Smith Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: - (mbox) Adding cc: Jessica Smith from + (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' OK. Log says: Sendmail: /usr/sbin/sendmail -i jessica@example.com @@ -571,7 +571,7 @@ In addition to knowing how to effectively contribute to a project, you’ll like ### Working in Topic Branches ### -When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. +When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. As you’ll remember, you can create the branch based off your master branch like this: $ git branch sc/ruby_client master @@ -596,7 +596,7 @@ This modifies the files in your working directory. It’s almost identical to ru You can also use git apply to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -615,11 +615,11 @@ To apply a patch generated by `format-patch`, you use `git am`. Technically, `gi Limit log functionality to the first 20 -This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. +This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: @@ -635,11 +635,11 @@ You can see that it applied cleanly and automatically created the new commit for Limit log functionality to the first 20 -The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. +The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -651,13 +651,13 @@ But it’s possible that the patch won’t apply cleanly. Perhaps your main bran This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: $ (fix the file) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -674,7 +674,7 @@ If you’re applying a number of patches from an mbox, you can also run the `am` -------------------------- seeing if this helps the gem -------------------------- - Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all + Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. @@ -738,7 +738,7 @@ Technically, you can do that by explicitly figuring out the common ancestor and $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 - $ git diff 36c7db + $ git diff 36c7db However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: @@ -754,7 +754,7 @@ When all the work in your topic branch is ready to be integrated into a more mai One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. -Insert 18333fig0519.png +Insert 18333fig0519.png Figure 5-19. History with several topic branches. Insert 18333fig0520.png @@ -764,13 +764,13 @@ That is probably the simplest workflow, but it’s problematic if you’re deali If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). -Insert 18333fig0521.png +Insert 18333fig0521.png Figure 5-21. Before a topic branch merge. -Insert 18333fig0522.png +Insert 18333fig0522.png Figure 5-22. After a topic branch merge. -Insert 18333fig0523.png +Insert 18333fig0523.png Figure 5-23. After a topic branch release. This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. @@ -780,12 +780,12 @@ You can also continue this concept, having an integrate branch where all the wor The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. -Insert 18333fig0524.png +Insert 18333fig0524.png Figure 5-24. Managing a complex series of parallel contributed topic branches. If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). -Insert 18333fig0525.png +Insert 18333fig0525.png Figure 5-25. Merging contributed topic branches into long-term integration branches. When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. @@ -796,7 +796,7 @@ Other maintainers prefer to rebase or cherry-pick contributed work on top of the The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. -Insert 18333fig0526.png +Insert 18333fig0526.png Figure 5-26. Example history before a cherry pick. If you want to pull commit `e43a6` into your master branch, you can run @@ -808,7 +808,7 @@ If you want to pull commit `e43a6` into your master branch, you can run This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. -Insert 18333fig0527.png +Insert 18333fig0527.png Figure 5-27. History after cherry-picking a commit on a topic branch. Now you can remove your topic branch and drop the commits you didn’t want to pull in. diff --git a/nl/05-distributed-git/01-chapter5.markdown b/nl/05-distributed-git/01-chapter5.markdown index f76d03200..b3404380a 100644 --- a/nl/05-distributed-git/01-chapter5.markdown +++ b/nl/05-distributed-git/01-chapter5.markdown @@ -519,7 +519,7 @@ Het `format-patch` commando voert de namen uit van de patch bestanden die het ma -- 1.6.2.rc1.20.g8c5b.dirty -Je kunt deze patch bestanden ook aanpassen om meer informatie voor de maillijst toe te voegen, die je niet in het commit bericht wil laten zien. Als je tekst toevoegt tussen de `--` regel en het begin van de patch (de `lib/simplegit.rb` regel), dan kunnen ontwikkelaars dit lezen; maar tijdens het toepassen van de patch wordt dit weggelaten. +Je kunt deze patch bestanden ook aanpassen om meer informatie voor de maillijst toe te voegen, die je niet in het commit bericht wil laten zien. Als je tekst toevoegt tussen de `---` regel en het begin van de patch (de `lib/simplegit.rb` regel), dan kunnen ontwikkelaars dit lezen; maar tijdens het toepassen van de patch wordt dit weggelaten. Om dit te e-mailen naar een maillijst, kun je het bestand in je e-mail applicatie plakken of het sturen via een commandoregel programma. Het plakken van de tekst veroorzaakt vaak formaat problemen, in het bijzonder bij "slimmere" clients die geen harde returns en andere witruimte juist behouden. Gelukkig levert Git een applicatie die je helpt om juist geformatteerde patches via IMAP te versturen, wat makkelijker voor je kan zijn. Ik zal demonstreren hoe je een patch via Gmail stuurt, wat de e-mail applicatie is die ik gebruik; je kunt gedetailleerde instructies voor een aantal mail programma's vinden aan het eind van het voornoemde `Documentation/SubmittingPatches` bestand in de Git broncode. diff --git a/no-nb/05-distributed-git/01-chapter5.markdown b/no-nb/05-distributed-git/01-chapter5.markdown index bcf20ab5b..e72635415 100644 --- a/no-nb/05-distributed-git/01-chapter5.markdown +++ b/no-nb/05-distributed-git/01-chapter5.markdown @@ -12,7 +12,7 @@ Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Gi In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). -Insert 18333fig0501.png +Insert 18333fig0501.png Figure 5-1. Centralized workflow. This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. @@ -31,7 +31,7 @@ Because Git allows you to have multiple remote repositories, it’s possible to 5. The maintainer adds the contributor’s repo as a remote and merges locally. 6. The maintainer pushes merged changes to the main repository. -Insert 18333fig0502.png +Insert 18333fig0502.png Figure 5-2. Integration-manager workflow. This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. @@ -45,7 +45,7 @@ This is a variant of a multiple-repository workflow. It’s generally used by hu 3. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 4. The dictator pushes their master to the reference repository so the other developers can rebase on it. -Insert 18333fig0503.png +Insert 18333fig0503.png Figure 5-3. Benevolent dictator workflow. This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, because as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. @@ -119,7 +119,7 @@ Let’s see what it might look like when two developers start to work together w Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) @@ -131,7 +131,7 @@ The second developer, Jessica, does the same thing — clones the repository and Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) @@ -161,7 +161,7 @@ John isn’t allowed to push because Jessica has pushed in the meantime. This is At this point, John’s local repository looks something like Figure 5-4. -Insert 18333fig0504.png +Insert 18333fig0504.png Figure 5-4. John’s initial repository. John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: @@ -173,7 +173,7 @@ John has a reference to the changes Jessica pushed up, but he has to merge them The merge goes smoothly — John’s commit history now looks like Figure 5-5. -Insert 18333fig0505.png +Insert 18333fig0505.png Figure 5-5. John’s repository after merging origin/master. Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: @@ -185,12 +185,12 @@ Now, John can test his code to make sure it still works properly, and then he ca Finally, John’s commit history looks like Figure 5-6. -Insert 18333fig0506.png +Insert 18333fig0506.png Figure 5-6. John’s history after pushing to the origin server. In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. -Insert 18333fig0507.png +Insert 18333fig0507.png Figure 5-7. Jessica’s initial commit history. Jessica wants to sync up with John, so she fetches: @@ -203,7 +203,7 @@ Jessica wants to sync up with John, so she fetches: That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. -Insert 18333fig0508.png +Insert 18333fig0508.png Figure 5-8. Jessica’s history after fetching John’s changes. Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: @@ -240,7 +240,7 @@ No problems occur; as you can see it, was a simple fast-forward. Now Jessica mer Everything merges cleanly, and Jessica’s history looks like Figure 5-9. -Insert 18333fig0509.png +Insert 18333fig0509.png Figure 5-9. Jessica’s history after merging John’s changes. Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): @@ -252,12 +252,12 @@ Now `origin/master` is reachable from Jessica’s `master` branch, so she should Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. -Insert 18333fig0510.png +Insert 18333fig0510.png Figure 5-10. Jessica’s history after pushing all changes back to the server. That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it’s ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. -Insert 18333fig0511.png +Insert 18333fig0511.png Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. ### Private Managed Team ### @@ -303,7 +303,7 @@ Now, Jessica makes a couple of commits on the `featureB` branch: Jessica’s repository looks like Figure 5-12. -Insert 18333fig0512.png +Insert 18333fig0512.png Figure 5-12. Jessica’s initial commit history. She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: @@ -368,17 +368,17 @@ Jessica wants to tweak something, so she commits again and then pushes this back Jessica’s commit history now looks something like Figure 5-13. -Insert 18333fig0513.png +Insert 18333fig0513.png Figure 5-13. Jessica’s history after committing on a feature branch. Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. -Insert 18333fig0514.png +Insert 18333fig0514.png Figure 5-14. Jessica’s history after merging both her topic branches. Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. -Insert 18333fig0515.png +Insert 18333fig0515.png Figure 5-15. Basic sequence of this managed-team workflow. ### Public Small Project ### @@ -438,7 +438,7 @@ On a project for which you’re not the maintainer, it’s generally easier to h Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. -Insert 18333fig0516.png +Insert 18333fig0516.png Figure 5-16. Initial commit history with featureB work. Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: @@ -449,7 +449,7 @@ Let’s say the project maintainer has pulled in a bunch of other patches and tr This rewrites your history to now look like Figure 5-17. -Insert 18333fig0517.png +Insert 18333fig0517.png Figure 5-17. Commit history after featureA work. Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). @@ -466,7 +466,7 @@ The `--squash` option takes all the work on the merged branch and squashes it in Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). -Insert 18333fig0518.png +Insert 18333fig0518.png Figure 5-18. Commit history after featureBv2 work. ### Public Large Project ### @@ -489,7 +489,7 @@ Now you have two commits that you want to send to the mailing list. You use `git The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith Date: Sun, 6 Apr 2008 10:17:23 -0700 @@ -514,10 +514,10 @@ The `format-patch` command prints out the names of the patch files it creates. T end def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty -You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `--` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. +You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. @@ -537,14 +537,14 @@ When that is set up, you can use `git send-email` to place the patch series in t $ git send-email *.patch 0001-added-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch - Who should the emails appear to be from? [Jessica Smith ] + Who should the emails appear to be from? [Jessica Smith ] Emails will be sent from: Jessica Smith Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: - (mbox) Adding cc: Jessica Smith from + (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' OK. Log says: Sendmail: /usr/sbin/sendmail -i jessica@example.com @@ -571,7 +571,7 @@ In addition to knowing how to effectively contribute to a project, you’ll like ### Working in Topic Branches ### -When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. +When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. As you’ll remember, you can create the branch based off your master branch like this: $ git branch sc/ruby_client master @@ -596,7 +596,7 @@ This modifies the files in your working directory. It’s almost identical to ru You can also use git apply to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -615,11 +615,11 @@ To apply a patch generated by `format-patch`, you use `git am`. Technically, `gi Limit log functionality to the first 20 -This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. +This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: @@ -635,11 +635,11 @@ You can see that it applied cleanly and automatically created the new commit for Limit log functionality to the first 20 -The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. +The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -651,13 +651,13 @@ But it’s possible that the patch won’t apply cleanly. Perhaps your main bran This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: $ (fix the file) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -674,7 +674,7 @@ If you’re applying a number of patches from an mbox, you can also run the `am` -------------------------- seeing if this helps the gem -------------------------- - Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all + Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. @@ -738,7 +738,7 @@ Technically, you can do that by explicitly figuring out the common ancestor and $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 - $ git diff 36c7db + $ git diff 36c7db However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: @@ -754,7 +754,7 @@ When all the work in your topic branch is ready to be integrated into a more mai One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. -Insert 18333fig0519.png +Insert 18333fig0519.png Figure 5-19. History with several topic branches. Insert 18333fig0520.png @@ -764,13 +764,13 @@ That is probably the simplest workflow, but it’s problematic if you’re deali If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). -Insert 18333fig0521.png +Insert 18333fig0521.png Figure 5-21. Before a topic branch merge. -Insert 18333fig0522.png +Insert 18333fig0522.png Figure 5-22. After a topic branch merge. -Insert 18333fig0523.png +Insert 18333fig0523.png Figure 5-23. After a topic branch release. This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. @@ -780,12 +780,12 @@ You can also continue this concept, having an integrate branch where all the wor The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. -Insert 18333fig0524.png +Insert 18333fig0524.png Figure 5-24. Managing a complex series of parallel contributed topic branches. If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). -Insert 18333fig0525.png +Insert 18333fig0525.png Figure 5-25. Merging contributed topic branches into long-term integration branches. When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. @@ -796,7 +796,7 @@ Other maintainers prefer to rebase or cherry-pick contributed work on top of the The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. -Insert 18333fig0526.png +Insert 18333fig0526.png Figure 5-26. Example history before a cherry pick. If you want to pull commit `e43a6` into your master branch, you can run @@ -808,7 +808,7 @@ If you want to pull commit `e43a6` into your master branch, you can run This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. -Insert 18333fig0527.png +Insert 18333fig0527.png Figure 5-27. History after cherry-picking a commit on a topic branch. Now you can remove your topic branch and drop the commits you didn’t want to pull in. diff --git a/pt-br/05-distributed-git/01-chapter5.markdown b/pt-br/05-distributed-git/01-chapter5.markdown index ce078641c..33f4967a4 100644 --- a/pt-br/05-distributed-git/01-chapter5.markdown +++ b/pt-br/05-distributed-git/01-chapter5.markdown @@ -516,7 +516,7 @@ O comando `format-patch` imprime o nome dos arquivos patch que ele cria. A opç -- 1.6.2.rc1.20.g8c5b.dirty -Você pode também editar esses arquivos de patch para adicionar mais informação para a lista de e-mail que você não quer que apareça na mensagem do commit. Se você adicionar o texto entre a linha com `--` e o início do patch (a linha `lib/simplegit.rb`), então desenvolvedores podem lê-la; mas aplicar o patch a exclui. +Você pode também editar esses arquivos de patch para adicionar mais informação para a lista de e-mail que você não quer que apareça na mensagem do commit. Se você adicionar o texto entre a linha com `---` e o início do patch (a linha `lib/simplegit.rb`), então desenvolvedores podem lê-la; mas aplicar o patch a exclui. Para enviar por e-mail a uma lista de discussão, você pode ou colar o arquivo em seu programa de e-mails ou enviar por um programa em linha de comando. Colando o texto geralmente causa problemas de formatação, especialmente com clientes "expertos" que não preservam linhas em branco e espaços em branco de forma apropriada. Por sorte, Git fornece uma ferramenta que lhe ajuda a enviar um patch via Gmail, que por acaso é o agente de e-mail que eu uso; você pode ler instruções detalhadas para vários programas de e-mail no final do arquivo previamente mencionado `Documentation/SubmittingPatched` no código fonte do Git. diff --git a/ru/05-distributed-git/01-chapter5.markdown b/ru/05-distributed-git/01-chapter5.markdown index 1ea5e3f30..438102c9f 100644 --- a/ru/05-distributed-git/01-chapter5.markdown +++ b/ru/05-distributed-git/01-chapter5.markdown @@ -30,7 +30,7 @@ Insert 18333fig0501.png 5. Владелец проекта добавляет репозиторий участника как удалённый и локально выполняет слияние. 6. Владелец отправляет слитые изменения в основной репозиторий. -Insert 18333fig0502.png +Insert 18333fig0502.png Рисунок 5-2. Рабочий процесс с менеджером по интеграции. Это очень распространённый тип рабочего процесса для сайтов вроде GitHub, где можно легко форкнуть проект и выложить свои изменения на всеобщее обозрение в собственную копию. Одно из главных преимуществ такого подхода — возможность продолжать работать, в то время как владелец основного репозитория может включить себе ваши изменения, когда ему угодно. Участникам проекта не придётся ждать включения своих изменений в проект — каждый может работать в своём собственном ритме. @@ -119,7 +119,7 @@ Insert 18333fig0503.png Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) @@ -131,7 +131,7 @@ Insert 18333fig0503.png Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) @@ -185,7 +185,7 @@ Insert 18333fig0505.png В результате история коммитов Джона выглядит, как показано на рисунке 5-6. -Insert 18333fig0506.png +Insert 18333fig0506.png Рисунок 5-6. История коммитов Джона после отправки изменений на сервер. Тем временем, Джессика работала над тематической веткой. Она создала тематическую ветку с названием `issue54` и сделала три коммита в этой ветке. Она ещё не извлекала изменения Джона, так что её история коммитов выглядит, как показано на рисунке 5-7. @@ -489,7 +489,7 @@ Insert 18333fig0518.png Команда `format-patch` создаёт файлы с патчами и выводит их названия. Опция `-M` сообщает Git'у о необходимости отслеживания переименований файлов. Итоговые патчи выглядят так: - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith Date: Sun, 6 Apr 2008 10:17:23 -0700 @@ -514,10 +514,10 @@ Insert 18333fig0518.png end def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty -Вы также можете отредактировать эти файлы с патчами, чтобы добавить в электронное письмо какую-то информацию, которую вы не хотите показывать в сообщении коммита. Если вы добавите текст между строкой `--` и началом патча (строка `lib/simplegit.rb`), то разработчик сможет его прочитать, а при применении патча он будет выброшен. +Вы также можете отредактировать эти файлы с патчами, чтобы добавить в электронное письмо какую-то информацию, которую вы не хотите показывать в сообщении коммита. Если вы добавите текст между строкой `---` и началом патча (строка `lib/simplegit.rb`), то разработчик сможет его прочитать, а при применении патча он будет выброшен. Чтобы отправить эти файлы в список рассылки, вы можете либо вставить файл в своём почтовом клиенте, либо отправить его через специальную программу из командной строки. Вставка текста часто приводит к ошибкам форматирования, особенно в "умных" клиентах, которые не сохраняют символы перевода строки и пробельные символы в исходном виде. К счастью, Git предоставляет инструмент, позволяющий вам передавать через IMAP правильно отформатированные патчи. Для вас применение этого инструмента может оказаться более простым. Я покажу, как отсылать патчи через Gmail, так как именно этот агент я и использую; вы можете прочесть подробные инструкции для множества почтовых программ в вышеупомянутом файле `Documentation/SubmittingPatches`, находящемся в исходном коде Git'а. @@ -537,14 +537,14 @@ Insert 18333fig0518.png $ git send-email *.patch 0001-added-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch - Who should the emails appear to be from? [Jessica Smith ] + Who should the emails appear to be from? [Jessica Smith ] Emails will be sent from: Jessica Smith Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y Затем Git выдаёт кучу служебных сообщений, которые для каждого отсылаемого патча выглядят следующим образом: - (mbox) Adding cc: Jessica Smith from + (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' OK. Log says: Sendmail: /usr/sbin/sendmail -i jessica@example.com @@ -596,7 +596,7 @@ Insert 18333fig0518.png Кроме того, вы можете использоваться `git apply`, чтобы узнать, чисто ли накладывается патч, ещё до того, как вы будете применять его на самом деле — для этого выполните `git apply --check`, указав нужный патч: - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -619,7 +619,7 @@ Insert 18333fig0518.png Однако, если кто-нибудь загрузил патч, созданный через `format-patch`, в тикет-систему или что-либо подобное, вы можете сохранить файл локально и затем передать его команде `git am`, чтобы его наложить: - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function Как видите, патч был применён без ошибок, и за вас автоматически был создан новый коммит. Информация об авторе берётся из полей `From` и `Date` письма, а сообщение коммита извлекается из поля `Subject` и тела (до начала самого патча) электронного письма. Например, если применить патч из mbox-файла приведённого выше примера, то созданный для него коммит будет выглядеть следующим образом: @@ -639,7 +639,7 @@ Insert 18333fig0518.png Однако возможна ситуация, когда патч не наложится без ошибок. Возможно, ваша основная ветка слишком далеко ушла вперёд относительно той, на которой патч был основан, или этот патч зависит от другого патча, который вы ещё не применили. В этом случае выполнение команды `git am` будет приостановлено, а у вас спросят, что вы хотите сделать: - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -651,13 +651,13 @@ Insert 18333fig0518.png Эта команда выставляет отметки о конфликтах в каждый файл, с которым возникают проблемы, точно так же, как это происходит при операции слияния или перемещения с конфликтами. И разрешается данная ситуация тем же способом — отредактируйте файл, чтобы разрешить конфликт, добавьте новый файл в индекс, а затем выполните команду `git am --resolved`, чтобы перейти к следующему патчу: $ (исправление файла) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem Если вы хотите, чтобы Git постарался разрешить конфликт более умно, воспользуйтесь опцией `-3`, при использовании которой Git попытается выполнить трёхходовую операцию слияния. Эта опция не включена по умолчанию, так как она не работает в случае, если коммита, на котором был основан патч, нет в вашем репозитории. Если этот коммит всё же у вас есть — в случае когда патч был основан на публичном коммите — то опция `-3`, как правило, гораздо умнее в наложении конфликтных патчей: - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -674,7 +674,7 @@ Insert 18333fig0518.png -------------------------- seeing if this helps the gem -------------------------- - Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all + Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all Это удобно, если у вас накопилось множество патчей, так как вы сможете сначала просмотреть патч, если вы забыли, что он из себя представляет, или отказаться применять патч, если он уже применён. @@ -738,7 +738,7 @@ Insert 18333fig0518.png $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 - $ git diff 36c7db + $ git diff 36c7db Однако это не очень удобно, так что в Git'е есть отдельное сокращённое обозначение для выполнения того же самого — запись с тремя точками. В контексте команды `diff`, вы можете поставить три точки после названия одной из веток, чтобы увидеть дельту между последним коммитом ветки, на которой вы находитесь, и их общим предком с другой веткой: diff --git a/th/05-distributed-git/01-chapter5.markdown b/th/05-distributed-git/01-chapter5.markdown index 00a222507..ff492d8d0 100644 --- a/th/05-distributed-git/01-chapter5.markdown +++ b/th/05-distributed-git/01-chapter5.markdown @@ -12,7 +12,7 @@ Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Gi In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). -Insert 18333fig0501.png +Insert 18333fig0501.png Figure 5-1. Centralized workflow. This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. @@ -31,7 +31,7 @@ Because Git allows you to have multiple remote repositories, it’s possible to 5. The maintainer adds the contributor’s repo as a remote and merges locally. 6. The maintainer pushes merged changes to the main repository. -Insert 18333fig0502.png +Insert 18333fig0502.png Figure 5-2. Integration-manager workflow. This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. @@ -45,7 +45,7 @@ This is a variant of a multiple-repository workflow. It’s generally used by hu 3. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 4. The dictator pushes their master to the reference repository so the other developers can rebase on it. -Insert 18333fig0503.png +Insert 18333fig0503.png Figure 5-3. Benevolent dictator workflow. This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, because as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. @@ -119,7 +119,7 @@ Let’s see what it might look like when two developers start to work together w Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) @@ -131,7 +131,7 @@ The second developer, Jessica, does the same thing — clones the repository and Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) @@ -161,7 +161,7 @@ John isn’t allowed to push because Jessica has pushed in the meantime. This is At this point, John’s local repository looks something like Figure 5-4. -Insert 18333fig0504.png +Insert 18333fig0504.png Figure 5-4. John’s initial repository. John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: @@ -173,7 +173,7 @@ John has a reference to the changes Jessica pushed up, but he has to merge them The merge goes smoothly — John’s commit history now looks like Figure 5-5. -Insert 18333fig0505.png +Insert 18333fig0505.png Figure 5-5. John’s repository after merging origin/master. Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: @@ -185,12 +185,12 @@ Now, John can test his code to make sure it still works properly, and then he ca Finally, John’s commit history looks like Figure 5-6. -Insert 18333fig0506.png +Insert 18333fig0506.png Figure 5-6. John’s history after pushing to the origin server. In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. -Insert 18333fig0507.png +Insert 18333fig0507.png Figure 5-7. Jessica’s initial commit history. Jessica wants to sync up with John, so she fetches: @@ -203,7 +203,7 @@ Jessica wants to sync up with John, so she fetches: That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. -Insert 18333fig0508.png +Insert 18333fig0508.png Figure 5-8. Jessica’s history after fetching John’s changes. Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: @@ -240,7 +240,7 @@ No problems occur; as you can see it, was a simple fast-forward. Now Jessica mer Everything merges cleanly, and Jessica’s history looks like Figure 5-9. -Insert 18333fig0509.png +Insert 18333fig0509.png Figure 5-9. Jessica’s history after merging John’s changes. Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): @@ -252,12 +252,12 @@ Now `origin/master` is reachable from Jessica’s `master` branch, so she should Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. -Insert 18333fig0510.png +Insert 18333fig0510.png Figure 5-10. Jessica’s history after pushing all changes back to the server. That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it’s ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. -Insert 18333fig0511.png +Insert 18333fig0511.png Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. ### Private Managed Team ### @@ -303,7 +303,7 @@ Now, Jessica makes a couple of commits on the `featureB` branch: Jessica’s repository looks like Figure 5-12. -Insert 18333fig0512.png +Insert 18333fig0512.png Figure 5-12. Jessica’s initial commit history. She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: @@ -368,17 +368,17 @@ Jessica wants to tweak something, so she commits again and then pushes this back Jessica’s commit history now looks something like Figure 5-13. -Insert 18333fig0513.png +Insert 18333fig0513.png Figure 5-13. Jessica’s history after committing on a feature branch. Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. -Insert 18333fig0514.png +Insert 18333fig0514.png Figure 5-14. Jessica’s history after merging both her topic branches. Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. -Insert 18333fig0515.png +Insert 18333fig0515.png Figure 5-15. Basic sequence of this managed-team workflow. ### Public Small Project ### @@ -438,7 +438,7 @@ On a project for which you’re not the maintainer, it’s generally easier to h Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. -Insert 18333fig0516.png +Insert 18333fig0516.png Figure 5-16. Initial commit history with featureB work. Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: @@ -449,7 +449,7 @@ Let’s say the project maintainer has pulled in a bunch of other patches and tr This rewrites your history to now look like Figure 5-17. -Insert 18333fig0517.png +Insert 18333fig0517.png Figure 5-17. Commit history after featureA work. Because you rebased the branch, you have to specify the `–f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). @@ -466,7 +466,7 @@ The `--squash` option takes all the work on the merged branch and squashes it in Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). -Insert 18333fig0518.png +Insert 18333fig0518.png Figure 5-18. Commit history after featureBv2 work. ### Public Large Project ### @@ -489,7 +489,7 @@ Now you have two commits that you want to send to the mailing list. You use `git The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith Date: Sun, 6 Apr 2008 10:17:23 -0700 @@ -514,10 +514,10 @@ The `format-patch` command prints out the names of the patch files it creates. T end def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty -You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `--` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. +You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. @@ -537,14 +537,14 @@ When that is set up, you can use `git send-email` to place the patch series in t $ git send-email *.patch 0001-added-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch - Who should the emails appear to be from? [Jessica Smith ] + Who should the emails appear to be from? [Jessica Smith ] Emails will be sent from: Jessica Smith Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: - (mbox) Adding cc: Jessica Smith from + (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' OK. Log says: Sendmail: /usr/sbin/sendmail -i jessica@example.com @@ -571,7 +571,7 @@ In addition to knowing how to effectively contribute to a project, you’ll like ### Working in Topic Branches ### -When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. +When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. As you’ll remember, you can create the branch based off your master branch like this: $ git branch sc/ruby_client master @@ -596,7 +596,7 @@ This modifies the files in your working directory. It’s almost identical to ru You can also use git apply to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -615,11 +615,11 @@ To apply a patch generated by `format-patch`, you use `git am`. Technically, `gi Limit log functionality to the first 20 -This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. +This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: @@ -635,11 +635,11 @@ You can see that it applied cleanly and automatically created the new commit for Limit log functionality to the first 20 -The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. +The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -651,13 +651,13 @@ But it’s possible that the patch won’t apply cleanly. Perhaps your main bran This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: $ (fix the file) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -674,7 +674,7 @@ If you’re applying a number of patches from an mbox, you can also run the `am` -------------------------- seeing if this helps the gem -------------------------- - Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all + Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. @@ -738,7 +738,7 @@ Technically, you can do that by explicitly figuring out the common ancestor and $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 - $ git diff 36c7db + $ git diff 36c7db However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: @@ -754,7 +754,7 @@ When all the work in your topic branch is ready to be integrated into a more mai One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. -Insert 18333fig0519.png +Insert 18333fig0519.png Figure 5-19. History with several topic branches. Insert 18333fig0520.png @@ -764,13 +764,13 @@ That is probably the simplest workflow, but it’s problematic if you’re deali If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). -Insert 18333fig0521.png +Insert 18333fig0521.png Figure 5-21. Before a topic branch merge. -Insert 18333fig0522.png +Insert 18333fig0522.png Figure 5-22. After a topic branch merge. -Insert 18333fig0523.png +Insert 18333fig0523.png Figure 5-23. After a topic branch release. This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. @@ -780,12 +780,12 @@ You can also continue this concept, having an integrate branch where all the wor The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. -Insert 18333fig0524.png +Insert 18333fig0524.png Figure 5-24. Managing a complex series of parallel contributed topic branches. If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). -Insert 18333fig0525.png +Insert 18333fig0525.png Figure 5-25. Merging contributed topic branches into long-term integration branches. When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. @@ -796,7 +796,7 @@ Other maintainers prefer to rebase or cherry-pick contributed work on top of the The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. -Insert 18333fig0526.png +Insert 18333fig0526.png Figure 5-26. Example history before a cherry pick. If you want to pull commit `e43a6` into your master branch, you can run @@ -808,7 +808,7 @@ If you want to pull commit `e43a6` into your master branch, you can run This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. -Insert 18333fig0527.png +Insert 18333fig0527.png Figure 5-27. History after cherry-picking a commit on a topic branch. Now you can remove your topic branch and drop the commits you didn’t want to pull in. diff --git a/tr/05-distributed-git/01-chapter5.markdown b/tr/05-distributed-git/01-chapter5.markdown index bcf20ab5b..e72635415 100644 --- a/tr/05-distributed-git/01-chapter5.markdown +++ b/tr/05-distributed-git/01-chapter5.markdown @@ -12,7 +12,7 @@ Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Gi In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). -Insert 18333fig0501.png +Insert 18333fig0501.png Figure 5-1. Centralized workflow. This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. @@ -31,7 +31,7 @@ Because Git allows you to have multiple remote repositories, it’s possible to 5. The maintainer adds the contributor’s repo as a remote and merges locally. 6. The maintainer pushes merged changes to the main repository. -Insert 18333fig0502.png +Insert 18333fig0502.png Figure 5-2. Integration-manager workflow. This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. @@ -45,7 +45,7 @@ This is a variant of a multiple-repository workflow. It’s generally used by hu 3. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 4. The dictator pushes their master to the reference repository so the other developers can rebase on it. -Insert 18333fig0503.png +Insert 18333fig0503.png Figure 5-3. Benevolent dictator workflow. This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, because as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. @@ -119,7 +119,7 @@ Let’s see what it might look like when two developers start to work together w Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) @@ -131,7 +131,7 @@ The second developer, Jessica, does the same thing — clones the repository and Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) @@ -161,7 +161,7 @@ John isn’t allowed to push because Jessica has pushed in the meantime. This is At this point, John’s local repository looks something like Figure 5-4. -Insert 18333fig0504.png +Insert 18333fig0504.png Figure 5-4. John’s initial repository. John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: @@ -173,7 +173,7 @@ John has a reference to the changes Jessica pushed up, but he has to merge them The merge goes smoothly — John’s commit history now looks like Figure 5-5. -Insert 18333fig0505.png +Insert 18333fig0505.png Figure 5-5. John’s repository after merging origin/master. Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: @@ -185,12 +185,12 @@ Now, John can test his code to make sure it still works properly, and then he ca Finally, John’s commit history looks like Figure 5-6. -Insert 18333fig0506.png +Insert 18333fig0506.png Figure 5-6. John’s history after pushing to the origin server. In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. -Insert 18333fig0507.png +Insert 18333fig0507.png Figure 5-7. Jessica’s initial commit history. Jessica wants to sync up with John, so she fetches: @@ -203,7 +203,7 @@ Jessica wants to sync up with John, so she fetches: That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. -Insert 18333fig0508.png +Insert 18333fig0508.png Figure 5-8. Jessica’s history after fetching John’s changes. Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: @@ -240,7 +240,7 @@ No problems occur; as you can see it, was a simple fast-forward. Now Jessica mer Everything merges cleanly, and Jessica’s history looks like Figure 5-9. -Insert 18333fig0509.png +Insert 18333fig0509.png Figure 5-9. Jessica’s history after merging John’s changes. Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): @@ -252,12 +252,12 @@ Now `origin/master` is reachable from Jessica’s `master` branch, so she should Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. -Insert 18333fig0510.png +Insert 18333fig0510.png Figure 5-10. Jessica’s history after pushing all changes back to the server. That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it’s ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. -Insert 18333fig0511.png +Insert 18333fig0511.png Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. ### Private Managed Team ### @@ -303,7 +303,7 @@ Now, Jessica makes a couple of commits on the `featureB` branch: Jessica’s repository looks like Figure 5-12. -Insert 18333fig0512.png +Insert 18333fig0512.png Figure 5-12. Jessica’s initial commit history. She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: @@ -368,17 +368,17 @@ Jessica wants to tweak something, so she commits again and then pushes this back Jessica’s commit history now looks something like Figure 5-13. -Insert 18333fig0513.png +Insert 18333fig0513.png Figure 5-13. Jessica’s history after committing on a feature branch. Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. -Insert 18333fig0514.png +Insert 18333fig0514.png Figure 5-14. Jessica’s history after merging both her topic branches. Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. -Insert 18333fig0515.png +Insert 18333fig0515.png Figure 5-15. Basic sequence of this managed-team workflow. ### Public Small Project ### @@ -438,7 +438,7 @@ On a project for which you’re not the maintainer, it’s generally easier to h Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. -Insert 18333fig0516.png +Insert 18333fig0516.png Figure 5-16. Initial commit history with featureB work. Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: @@ -449,7 +449,7 @@ Let’s say the project maintainer has pulled in a bunch of other patches and tr This rewrites your history to now look like Figure 5-17. -Insert 18333fig0517.png +Insert 18333fig0517.png Figure 5-17. Commit history after featureA work. Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). @@ -466,7 +466,7 @@ The `--squash` option takes all the work on the merged branch and squashes it in Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). -Insert 18333fig0518.png +Insert 18333fig0518.png Figure 5-18. Commit history after featureBv2 work. ### Public Large Project ### @@ -489,7 +489,7 @@ Now you have two commits that you want to send to the mailing list. You use `git The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith Date: Sun, 6 Apr 2008 10:17:23 -0700 @@ -514,10 +514,10 @@ The `format-patch` command prints out the names of the patch files it creates. T end def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty -You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `--` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. +You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. @@ -537,14 +537,14 @@ When that is set up, you can use `git send-email` to place the patch series in t $ git send-email *.patch 0001-added-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch - Who should the emails appear to be from? [Jessica Smith ] + Who should the emails appear to be from? [Jessica Smith ] Emails will be sent from: Jessica Smith Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: - (mbox) Adding cc: Jessica Smith from + (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' OK. Log says: Sendmail: /usr/sbin/sendmail -i jessica@example.com @@ -571,7 +571,7 @@ In addition to knowing how to effectively contribute to a project, you’ll like ### Working in Topic Branches ### -When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. +When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. As you’ll remember, you can create the branch based off your master branch like this: $ git branch sc/ruby_client master @@ -596,7 +596,7 @@ This modifies the files in your working directory. It’s almost identical to ru You can also use git apply to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -615,11 +615,11 @@ To apply a patch generated by `format-patch`, you use `git am`. Technically, `gi Limit log functionality to the first 20 -This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. +This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: @@ -635,11 +635,11 @@ You can see that it applied cleanly and automatically created the new commit for Limit log functionality to the first 20 -The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. +The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -651,13 +651,13 @@ But it’s possible that the patch won’t apply cleanly. Perhaps your main bran This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: $ (fix the file) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -674,7 +674,7 @@ If you’re applying a number of patches from an mbox, you can also run the `am` -------------------------- seeing if this helps the gem -------------------------- - Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all + Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. @@ -738,7 +738,7 @@ Technically, you can do that by explicitly figuring out the common ancestor and $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 - $ git diff 36c7db + $ git diff 36c7db However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: @@ -754,7 +754,7 @@ When all the work in your topic branch is ready to be integrated into a more mai One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. -Insert 18333fig0519.png +Insert 18333fig0519.png Figure 5-19. History with several topic branches. Insert 18333fig0520.png @@ -764,13 +764,13 @@ That is probably the simplest workflow, but it’s problematic if you’re deali If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). -Insert 18333fig0521.png +Insert 18333fig0521.png Figure 5-21. Before a topic branch merge. -Insert 18333fig0522.png +Insert 18333fig0522.png Figure 5-22. After a topic branch merge. -Insert 18333fig0523.png +Insert 18333fig0523.png Figure 5-23. After a topic branch release. This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. @@ -780,12 +780,12 @@ You can also continue this concept, having an integrate branch where all the wor The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. -Insert 18333fig0524.png +Insert 18333fig0524.png Figure 5-24. Managing a complex series of parallel contributed topic branches. If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). -Insert 18333fig0525.png +Insert 18333fig0525.png Figure 5-25. Merging contributed topic branches into long-term integration branches. When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. @@ -796,7 +796,7 @@ Other maintainers prefer to rebase or cherry-pick contributed work on top of the The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. -Insert 18333fig0526.png +Insert 18333fig0526.png Figure 5-26. Example history before a cherry pick. If you want to pull commit `e43a6` into your master branch, you can run @@ -808,7 +808,7 @@ If you want to pull commit `e43a6` into your master branch, you can run This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. -Insert 18333fig0527.png +Insert 18333fig0527.png Figure 5-27. History after cherry-picking a commit on a topic branch. Now you can remove your topic branch and drop the commits you didn’t want to pull in. diff --git a/zh-tw/05-distributed-git/01-chapter5.markdown b/zh-tw/05-distributed-git/01-chapter5.markdown index 00a222507..ff492d8d0 100644 --- a/zh-tw/05-distributed-git/01-chapter5.markdown +++ b/zh-tw/05-distributed-git/01-chapter5.markdown @@ -12,7 +12,7 @@ Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Gi In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). -Insert 18333fig0501.png +Insert 18333fig0501.png Figure 5-1. Centralized workflow. This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. @@ -31,7 +31,7 @@ Because Git allows you to have multiple remote repositories, it’s possible to 5. The maintainer adds the contributor’s repo as a remote and merges locally. 6. The maintainer pushes merged changes to the main repository. -Insert 18333fig0502.png +Insert 18333fig0502.png Figure 5-2. Integration-manager workflow. This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. @@ -45,7 +45,7 @@ This is a variant of a multiple-repository workflow. It’s generally used by hu 3. The dictator merges the lieutenants’ master branches into the dictator’s master branch. 4. The dictator pushes their master to the reference repository so the other developers can rebase on it. -Insert 18333fig0503.png +Insert 18333fig0503.png Figure 5-3. Benevolent dictator workflow. This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, because as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. @@ -119,7 +119,7 @@ Let’s see what it might look like when two developers start to work together w Initialized empty Git repository in /home/john/simplegit/.git/ ... $ cd simplegit/ - $ vim lib/simplegit.rb + $ vim lib/simplegit.rb $ git commit -am 'removed invalid default value' [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) @@ -131,7 +131,7 @@ The second developer, Jessica, does the same thing — clones the repository and Initialized empty Git repository in /home/jessica/simplegit/.git/ ... $ cd simplegit/ - $ vim TODO + $ vim TODO $ git commit -am 'add reset task' [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) @@ -161,7 +161,7 @@ John isn’t allowed to push because Jessica has pushed in the meantime. This is At this point, John’s local repository looks something like Figure 5-4. -Insert 18333fig0504.png +Insert 18333fig0504.png Figure 5-4. John’s initial repository. John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: @@ -173,7 +173,7 @@ John has a reference to the changes Jessica pushed up, but he has to merge them The merge goes smoothly — John’s commit history now looks like Figure 5-5. -Insert 18333fig0505.png +Insert 18333fig0505.png Figure 5-5. John’s repository after merging origin/master. Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: @@ -185,12 +185,12 @@ Now, John can test his code to make sure it still works properly, and then he ca Finally, John’s commit history looks like Figure 5-6. -Insert 18333fig0506.png +Insert 18333fig0506.png Figure 5-6. John’s history after pushing to the origin server. In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. -Insert 18333fig0507.png +Insert 18333fig0507.png Figure 5-7. Jessica’s initial commit history. Jessica wants to sync up with John, so she fetches: @@ -203,7 +203,7 @@ Jessica wants to sync up with John, so she fetches: That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. -Insert 18333fig0508.png +Insert 18333fig0508.png Figure 5-8. Jessica’s history after fetching John’s changes. Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: @@ -240,7 +240,7 @@ No problems occur; as you can see it, was a simple fast-forward. Now Jessica mer Everything merges cleanly, and Jessica’s history looks like Figure 5-9. -Insert 18333fig0509.png +Insert 18333fig0509.png Figure 5-9. Jessica’s history after merging John’s changes. Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): @@ -252,12 +252,12 @@ Now `origin/master` is reachable from Jessica’s `master` branch, so she should Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. -Insert 18333fig0510.png +Insert 18333fig0510.png Figure 5-10. Jessica’s history after pushing all changes back to the server. That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it’s ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. -Insert 18333fig0511.png +Insert 18333fig0511.png Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. ### Private Managed Team ### @@ -303,7 +303,7 @@ Now, Jessica makes a couple of commits on the `featureB` branch: Jessica’s repository looks like Figure 5-12. -Insert 18333fig0512.png +Insert 18333fig0512.png Figure 5-12. Jessica’s initial commit history. She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: @@ -368,17 +368,17 @@ Jessica wants to tweak something, so she commits again and then pushes this back Jessica’s commit history now looks something like Figure 5-13. -Insert 18333fig0513.png +Insert 18333fig0513.png Figure 5-13. Jessica’s history after committing on a feature branch. Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. -Insert 18333fig0514.png +Insert 18333fig0514.png Figure 5-14. Jessica’s history after merging both her topic branches. Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. -Insert 18333fig0515.png +Insert 18333fig0515.png Figure 5-15. Basic sequence of this managed-team workflow. ### Public Small Project ### @@ -438,7 +438,7 @@ On a project for which you’re not the maintainer, it’s generally easier to h Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. -Insert 18333fig0516.png +Insert 18333fig0516.png Figure 5-16. Initial commit history with featureB work. Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: @@ -449,7 +449,7 @@ Let’s say the project maintainer has pulled in a bunch of other patches and tr This rewrites your history to now look like Figure 5-17. -Insert 18333fig0517.png +Insert 18333fig0517.png Figure 5-17. Commit history after featureA work. Because you rebased the branch, you have to specify the `–f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). @@ -466,7 +466,7 @@ The `--squash` option takes all the work on the merged branch and squashes it in Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). -Insert 18333fig0518.png +Insert 18333fig0518.png Figure 5-18. Commit history after featureBv2 work. ### Public Large Project ### @@ -489,7 +489,7 @@ Now you have two commits that you want to send to the mailing list. You use `git The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: - $ cat 0001-add-limit-to-log-function.patch + $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith Date: Sun, 6 Apr 2008 10:17:23 -0700 @@ -514,10 +514,10 @@ The `format-patch` command prints out the names of the patch files it creates. T end def ls_tree(treeish = 'master') - -- + -- 1.6.2.rc1.20.g8c5b.dirty -You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `--` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. +You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. @@ -537,14 +537,14 @@ When that is set up, you can use `git send-email` to place the patch series in t $ git send-email *.patch 0001-added-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch - Who should the emails appear to be from? [Jessica Smith ] + Who should the emails appear to be from? [Jessica Smith ] Emails will be sent from: Jessica Smith Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: - (mbox) Adding cc: Jessica Smith from + (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' OK. Log says: Sendmail: /usr/sbin/sendmail -i jessica@example.com @@ -571,7 +571,7 @@ In addition to knowing how to effectively contribute to a project, you’ll like ### Working in Topic Branches ### -When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. +When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. As you’ll remember, you can create the branch based off your master branch like this: $ git branch sc/ruby_client master @@ -596,7 +596,7 @@ This modifies the files in your working directory. It’s almost identical to ru You can also use git apply to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: - $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -615,11 +615,11 @@ To apply a patch generated by `format-patch`, you use `git am`. Technically, `gi Limit log functionality to the first 20 -This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. +This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: - $ git am 0001-limit-log-function.patch + $ git am 0001-limit-log-function.patch Applying: add limit to log function You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: @@ -635,11 +635,11 @@ You can see that it applied cleanly and automatically created the new commit for Limit log functionality to the first 20 -The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. +The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: - $ git am 0001-seeing-if-this-helps-the-gem.patch + $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -651,13 +651,13 @@ But it’s possible that the patch won’t apply cleanly. Perhaps your main bran This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: $ (fix the file) - $ git add ticgit.gemspec + $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: - $ git am -3 0001-seeing-if-this-helps-the-gem.patch + $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply @@ -674,7 +674,7 @@ If you’re applying a number of patches from an mbox, you can also run the `am` -------------------------- seeing if this helps the gem -------------------------- - Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all + Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. @@ -738,7 +738,7 @@ Technically, you can do that by explicitly figuring out the common ancestor and $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 - $ git diff 36c7db + $ git diff 36c7db However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: @@ -754,7 +754,7 @@ When all the work in your topic branch is ready to be integrated into a more mai One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. -Insert 18333fig0519.png +Insert 18333fig0519.png Figure 5-19. History with several topic branches. Insert 18333fig0520.png @@ -764,13 +764,13 @@ That is probably the simplest workflow, but it’s problematic if you’re deali If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). -Insert 18333fig0521.png +Insert 18333fig0521.png Figure 5-21. Before a topic branch merge. -Insert 18333fig0522.png +Insert 18333fig0522.png Figure 5-22. After a topic branch merge. -Insert 18333fig0523.png +Insert 18333fig0523.png Figure 5-23. After a topic branch release. This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. @@ -780,12 +780,12 @@ You can also continue this concept, having an integrate branch where all the wor The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. -Insert 18333fig0524.png +Insert 18333fig0524.png Figure 5-24. Managing a complex series of parallel contributed topic branches. If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). -Insert 18333fig0525.png +Insert 18333fig0525.png Figure 5-25. Merging contributed topic branches into long-term integration branches. When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. @@ -796,7 +796,7 @@ Other maintainers prefer to rebase or cherry-pick contributed work on top of the The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. -Insert 18333fig0526.png +Insert 18333fig0526.png Figure 5-26. Example history before a cherry pick. If you want to pull commit `e43a6` into your master branch, you can run @@ -808,7 +808,7 @@ If you want to pull commit `e43a6` into your master branch, you can run This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. -Insert 18333fig0527.png +Insert 18333fig0527.png Figure 5-27. History after cherry-picking a commit on a topic branch. Now you can remove your topic branch and drop the commits you didn’t want to pull in. From 8326adae62b1aee04a310feba94ebcd7db1d8a4a Mon Sep 17 00:00:00 2001 From: "Jason St. John" Date: Tue, 19 Nov 2013 22:06:25 -0500 Subject: [PATCH 045/862] Apply 5cfd71e to ja/, ko/, and pl/ translations Plus, ko/: add missing backticks around "---" and "lib/simplegit.rb" ko/: fix typo in word "Documentation" (extra letter "e") pl/: fix typo in "lib/simplegit.rb" (lin -> lib) pl/: remove trailing whitespace --- ja/05-distributed-git/01-chapter5.markdown | 2 +- ko/05-distributed-git/01-chapter5.markdown | 4 +-- pl/05-distributed-git/01-chapter5.markdown | 32 +++++++++++----------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/ja/05-distributed-git/01-chapter5.markdown b/ja/05-distributed-git/01-chapter5.markdown index d3e4687c5..21d250d28 100644 --- a/ja/05-distributed-git/01-chapter5.markdown +++ b/ja/05-distributed-git/01-chapter5.markdown @@ -514,7 +514,7 @@ Insert 18333fig0518.png -- 1.6.2.rc1.20.g8c5b.dirty -このファイルを編集して、コミットメッセージには書けなかったような情報をメーリングリスト用に追加することもできます。`--` の行とパッチの開始位置 (`lib/simplegit.rb` の行) の間にメッセージを書くと、メールを受信した人はそれを読むことができますが、パッチからは除外されます。 +このファイルを編集して、コミットメッセージには書けなかったような情報をメーリングリスト用に追加することもできます。`---` の行とパッチの開始位置 (`lib/simplegit.rb` の行) の間にメッセージを書くと、メールを受信した人はそれを読むことができますが、パッチからは除外されます。 これをメーリングリストに投稿するには、メールソフトにファイルの内容を貼り付けるか、あるいはコマンドラインのプログラムを使います。ファイルの内容をコピーして貼り付けると「かしこい」メールソフトが勝手に改行の位置を変えてしまうなどの問題が起こりがちです。ありがたいことに Git には、きちんとしたフォーマットのパッチを IMAP で送ることを支援するツールが用意されています。これを使うと便利です。ここでは、パッチを Gmail で送る方法を説明しましょう。というのも、たまたま私が使ってるメールソフトが Gmail だからです。さまざまなメールソフトでの詳細なメール送信方法が、Git ソースコードにある `Documentation/SubmittingPatches` の最後に載っています。 diff --git a/ko/05-distributed-git/01-chapter5.markdown b/ko/05-distributed-git/01-chapter5.markdown index 5bf630702..d8f7dda7c 100644 --- a/ko/05-distributed-git/01-chapter5.markdown +++ b/ko/05-distributed-git/01-chapter5.markdown @@ -512,11 +512,11 @@ format-patch 명령을 실행하면 생성한 파일 이름을 보여준다. -M -- 1.6.2.rc1.20.g8c5b.dirty -메일링리스트에 메일을 보내기 전에 각 Patch 메일 파일의 내용을 손으로 고칠 수 있다. -- 줄과 Patch가 시작되는 줄(lib/simplegit.rb로 시작하는 줄) 사이에 내용을 추가하면 개발자는 읽을 수 있지만, 나중에 Patch에 적용되지는 않는다. +메일링리스트에 메일을 보내기 전에 각 Patch 메일 파일의 내용을 손으로 고칠 수 있다. `---` 줄과 Patch가 시작되는 줄(`lib/simplegit.rb`로 시작하는 줄) 사이에 내용을 추가하면 개발자는 읽을 수 있지만, 나중에 Patch에 적용되지는 않는다. 특정 메일 프로그램을 사용하거나 이메일을 보내는 명령어로 메일링리스트에 보낼 수 있다. 붙여 넣기로 위의 내용이 그대로 들어가지 않는 메일 프로그램도 있다. 사용자 편의를 위해 공백이나 줄 바꿈 문자 등을 넣어 주는 메일 프로그램은 원본 그대로 들어가지 않는다. -다행히 Git에는 Patch 메일을 그대로 보낼 수 있는 도구가 있다. IMAP 프로토콜로 보낸다. 저자가 사용하는 방법으로 Gmail을 사용하여 Patch 메일을 전송하는 방법을 살펴보자. 추가로 Git 프로젝트의 `Docuementation/SubmittingPatches` 문서의 마지막 부분을 살펴보면 다양한 메일 프로그램으로 메일을 보내는 방법을 설명한다. +다행히 Git에는 Patch 메일을 그대로 보낼 수 있는 도구가 있다. IMAP 프로토콜로 보낸다. 저자가 사용하는 방법으로 Gmail을 사용하여 Patch 메일을 전송하는 방법을 살펴보자. 추가로 Git 프로젝트의 `Documentation/SubmittingPatches` 문서의 마지막 부분을 살펴보면 다양한 메일 프로그램으로 메일을 보내는 방법을 설명한다. 메일을 보내려면 먼저 ~/.gitconfig 파일에서 이메일 부분 설정한다. `git config` 명령으로 추가할 수도 있고 직접 파일을 열어서 추가할 수도 있다. 아무튼, 아래와 같이 설정을 한다: diff --git a/pl/05-distributed-git/01-chapter5.markdown b/pl/05-distributed-git/01-chapter5.markdown index f2ddeb47e..257072367 100644 --- a/pl/05-distributed-git/01-chapter5.markdown +++ b/pl/05-distributed-git/01-chapter5.markdown @@ -152,15 +152,15 @@ Here is a template originally written by Tim Pope at tpope.net: --> Bardziej szczegółowy tekst jeżeli jest taka konieczność. Zawijaj wiersze po około 72 znakach. Czasami pierwsza linia jest traktowana jako temat wiadomości email, a reszta komentarza jako treść. Pusta - linia oddzielająca opis od streszczenia jest konieczna (chyba że + linia oddzielająca opis od streszczenia jest konieczna (chyba że ominiesz szczegółowy opis kompletnie); narzędzia takie jak `rebase` mogą się pogubić jeżeli nie oddzielisz ich. Kolejne paragrafy przychodzą po pustej linii. - - wypunktowania są poprawne, również + - wypunktowania są poprawne, również - - zazwyczaj łącznik lub gwiazdka jest używana do punktowania, + - zazwyczaj łącznik lub gwiazdka jest używana do punktowania, poprzedzona pojedynczym znakiem spacji, z pustą linią pomiędzy, jednak zwyczaje mogą się tutaj różnić. @@ -182,10 +182,10 @@ Najprostszym przykładem który możesz spotkać, to prywatne repozytorium z jed W takim środowisku możesz naśladować sposób pracy znany z Subversion czy innego scentralizowanego systemu kontroli wersji. Nadal masz wszystkie zalety takie jak commitowanie bez dostępu do centralnego serwera, oraz prostsze tworzenie gałęzi i łączenie zmian, ale przepływ pracy jest bardzo podobny; główną różnicą jest to, że łączenie zmian wykonywane jest po stronie klienta a nie serwera podczas commitu. Zobaczmy jak to może wyglądać, w sytuacji w której dwóch programistów rozpocznie prace z współdzielonym repozytorium. Pierwszy programista, John, klonuje repozytorium, wprowadza zmiany i zatwierdza je lokalnie. (Zamieniłem część informacji znakami `...` aby skrócić przykłady.) - - # Komputer Johna + # Komputer Johna $ git clone john@githost:simplegit.git Initialized empty Git repository in /home/john/simplegit/.git/ ... @@ -318,7 +318,7 @@ Teraz Jessica może połączyć zmiany ze swojej gałęzi z gałęzią "master", Switched to branch "master" Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. -Może ona włączyć `origin/master` lub `issue54` jako pierwszą, obie są nadrzędne więc kolejność nie ma znaczenia. Końcowa wersja plików powinna być identyczna bez względu na kolejność którą wybierze; tylko historia będzie się lekko różniła. Wybiera pierwszą do włączenia gałąź `issue54`: +Może ona włączyć `origin/master` lub `issue54` jako pierwszą, obie są nadrzędne więc kolejność nie ma znaczenia. Końcowa wersja plików powinna być identyczna bez względu na kolejność którą wybierze; tylko historia będzie się lekko różniła. Wybiera pierwszą do włączenia gałąź `issue54`: @@ -575,7 +575,7 @@ Musisz wysłać swoje zmiany do niego. Najprościej będzie wypchnąć lokalną $ git push myfork featureA -Kiedy wgrasz wprowadzone zmiany do swojego rozwidlenia projektu, powinieneś powiadomić o tym opiekuna. Jest to często nazywane `pull request`, i możesz je wygenerować poprzez stronę - GitHub ma przycisk "pull request", który automatycznie generuje wiadomość do opiekuna - lub wykonaj komendę `git request-pull` i wyślij jej wynik do opiekuna projektu samodzielnie. +Kiedy wgrasz wprowadzone zmiany do swojego rozwidlenia projektu, powinieneś powiadomić o tym opiekuna. Jest to często nazywane `pull request`, i możesz je wygenerować poprzez stronę - GitHub ma przycisk "pull request", który automatycznie generuje wiadomość do opiekuna - lub wykonaj komendę `git request-pull` i wyślij jej wynik do opiekuna projektu samodzielnie. @@ -725,9 +725,9 @@ Komenda `format-patch` wypisuje nazwy plików które stworzyła. Opcja `-M` mów -- 1.6.2.rc1.20.g8c5b.dirty -Możesz oczywiście zmienić te pliki i dodać większą ilość informacji w mailu, których nie chciałeś pokazywać w komentarzu do zmiany. Jeżeli dodasz tekst miedzy linię z `--`, oraz początkiem łaty (linia z `lin/simplegit.rb`), programiści będą mogli to przeczytać; ale podczas nakładania łaty zostanie do pominięte. +Możesz oczywiście zmienić te pliki i dodać większą ilość informacji w mailu, których nie chciałeś pokazywać w komentarzu do zmiany. Jeżeli dodasz tekst miedzy linię z `---`, oraz początkiem łaty (linia z `lib/simplegit.rb`), programiści będą mogli to przeczytać; ale podczas nakładania łaty zostanie do pominięte. - + Aby wysłać to na listę dyskusyjną, możesz albo wkleić zawartość plików w programie e-mail lub użyć programu uruchamianego z linii komend. Wklejanie tekstu często wprowadza problemy z zachowaniem formatowania, szczególnie przy użyciu tych "mądrzejszych" programów pocztowych, które nie zachowują poprawnie znaków nowej linii i spacji. Na szczęście Git udostępnia narzędzie, które pomoże Ci wysłać poprawnie sformatowane łaty poprzez protokół IMAP, może to być łatwiejsze dla Ciebie. Pokażę w jaki sposób wysyłać łaty przy pomocy Gmaila, którego używam; możesz znaleźć bardziej szczegółowe instrukcje dla różnych programów pocztowych na końcu wcześniej wymienionego pliku `Documentation/SubmittingPatches`, który znajduje się w kodzie źródłowym Gita. @@ -777,7 +777,7 @@ Następnie, Git pokaże garść informacji podobnych tych, dla każdej łaty kt Result: OK -Od tego momentu powinieneś móc przejść do folderu Draft, zmienić pole odbiorcy wiadomości na adres listy dyskusyjnej do której wysyłasz łatę, ewentualnie dodać adres osób zainteresowanych tym tematem w kopii i wysłać. +Od tego momentu powinieneś móc przejść do folderu Draft, zmienić pole odbiorcy wiadomości na adres listy dyskusyjnej do której wysyłasz łatę, ewentualnie dodać adres osób zainteresowanych tym tematem w kopii i wysłać. @@ -839,7 +839,7 @@ Możesz również użyć `git apply` aby zobaczyć, czy łata nałoży się czys error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply -Jeżeli nie zostanie wygenerowany żaden komunikat, to łata nałoży się poprawnie. Ta komenda również kończy działanie z niezerowym statusem w przypadku błędu, możesz więc użyć jej w skryptach jeżeli tylko chcesz. +Jeżeli nie zostanie wygenerowany żaden komunikat, to łata nałoży się poprawnie. Ta komenda również kończy działanie z niezerowym statusem w przypadku błędu, możesz więc użyć jej w skryptach jeżeli tylko chcesz. @@ -966,7 +966,7 @@ Jeżeli napisze do Ciebie ponownie z nową gałęzią która zawiera kolejną fu -Jest to bardzo pomocne w sytuacji, w której współpracujesz z jakąś osobą na stałe. Jeżeli ktoś ma tylko pojedyncze łatki które udostępnia raz na jakiś czas, to akceptowanie ich poprzez e-mail może być szybsze, niż zmuszanie wszystkich do tego aby mieli własny serwer, jak również dodawanie i usuwanie zdalnych repozytoriów aby otrzymać jedną lub dwie łatki. Jednakże, skrypty oraz usługi udostępniane mogą uczynić to prostszym - zależy od tego w taki sposób pracujesz, oraz jak pracują Twoi współpracownicy. +Jest to bardzo pomocne w sytuacji, w której współpracujesz z jakąś osobą na stałe. Jeżeli ktoś ma tylko pojedyncze łatki które udostępnia raz na jakiś czas, to akceptowanie ich poprzez e-mail może być szybsze, niż zmuszanie wszystkich do tego aby mieli własny serwer, jak również dodawanie i usuwanie zdalnych repozytoriów aby otrzymać jedną lub dwie łatki. Jednakże, skrypty oraz usługi udostępniane mogą uczynić to prostszym - zależy od tego w taki sposób pracujesz, oraz jak pracują Twoi współpracownicy. @@ -1124,7 +1124,7 @@ Z chwilą, gdy gałąź tematycznie zostanie włączona do `master`, jest usuwan #### Zmiana bazy oraz wybiórcze pobieranie zmian #### -Część opiekunów woli używać "rebase" lub "cherry-pick" w celu włączania zmian w gałęzi master, zamiast przy użyciu "merge", aby zachować bardziej liniową historię. Kiedy masz zmiany w gałęzi tematycznej i decydujesz się zintegrować je, przenosisz gałąź i uruchamiasz "rebase" aby nałożyć zmiany na górze swojej gałęzi master (lub `develop`, czy innej). Jeżeli to zadziała poprawnie, możesz przesunąć swoją gałąź `master` i otrzymasz praktycznie liniową historię. +Część opiekunów woli używać "rebase" lub "cherry-pick" w celu włączania zmian w gałęzi master, zamiast przy użyciu "merge", aby zachować bardziej liniową historię. Kiedy masz zmiany w gałęzi tematycznej i decydujesz się zintegrować je, przenosisz gałąź i uruchamiasz "rebase" aby nałożyć zmiany na górze swojej gałęzi master (lub `develop`, czy innej). Jeżeli to zadziała poprawnie, możesz przesunąć swoją gałąź `master` i otrzymasz praktycznie liniową historię. @@ -1161,7 +1161,7 @@ Teraz możesz usunąć swoją gałąź tematyczną, oraz zmiany których nie chc ### Tagowanie Twoich Wersji ### -Kiedy zdecydowałeś, że wydasz nową wersję, najprawdopodobniej będziesz chciał stworzyć taga, tak abyś mógł odtworzyć tą wersję w każdym momencie. Możesz stworzyć nowego taga, tak jak zostało to opisane w rozdziale 2. Jeżeli zdecydujesz się na utworzenie taga jako opiekun, komenda powinna wyglądać podobnie do: +Kiedy zdecydowałeś, że wydasz nową wersję, najprawdopodobniej będziesz chciał stworzyć taga, tak abyś mógł odtworzyć tą wersję w każdym momencie. Możesz stworzyć nowego taga, tak jak zostało to opisane w rozdziale 2. Jeżeli zdecydujesz się na utworzenie taga jako opiekun, komenda powinna wyglądać podobnie do: @@ -1170,7 +1170,7 @@ Kiedy zdecydowałeś, że wydasz nową wersję, najprawdopodobniej będziesz chc user: "Scott Chacon " 1024-bit DSA key, ID F721C45A, created 2009-02-09 -Jeżeli podpisujesz swoje tagi, możesz mieć problem z dystrybucją swojego publicznego klucza PGP, który został użyty. Można rozwiązać ten problem poprzez dodanie obiektu binarnego (ang. blob) w repozytorium, a następnie stworzenie taga kierującego dokładnie na jego zawartość. Aby to zrobić, musisz wybrać klucz za pomocą komendy `gpg --list-keys`: +Jeżeli podpisujesz swoje tagi, możesz mieć problem z dystrybucją swojego publicznego klucza PGP, który został użyty. Można rozwiązać ten problem poprzez dodanie obiektu binarnego (ang. blob) w repozytorium, a następnie stworzenie taga kierującego dokładnie na jego zawartość. Aby to zrobić, musisz wybrać klucz za pomocą komendy `gpg --list-keys`: @@ -1220,7 +1220,7 @@ W ten sposób, możesz udostępnić konkretną wersję lub kompilację pod nazw -Komenda `git describe` faworyzuje etykiety stworzone przy użyciu opcji `-a` lub `-s`, więc etykiety dotyczące konkretnych wersji powinny być tworzone w ten sposób, jeżeli używasz `git describe` w celu zapewnienia poprawnych nazw commitów. Możesz również używać tej nazwy do komend "checkout" lub "show", choć polegają one na skróconej wartości SHA-1, mogą więc nie być wiecznie poprawne. Na przykład, projekt jądra Linuksa przeszedł ostatnio z 8 na 10 znaków aby zapewnić unikalność sum SHA-1, więc poprzednie nazwy wygenerowane za pomocą `git describe` zostały unieważnione. +Komenda `git describe` faworyzuje etykiety stworzone przy użyciu opcji `-a` lub `-s`, więc etykiety dotyczące konkretnych wersji powinny być tworzone w ten sposób, jeżeli używasz `git describe` w celu zapewnienia poprawnych nazw commitów. Możesz również używać tej nazwy do komend "checkout" lub "show", choć polegają one na skróconej wartości SHA-1, mogą więc nie być wiecznie poprawne. Na przykład, projekt jądra Linuksa przeszedł ostatnio z 8 na 10 znaków aby zapewnić unikalność sum SHA-1, więc poprzednie nazwy wygenerowane za pomocą `git describe` zostały unieważnione. From cfc48daac0792e19d04eaaa9666afed091e8455c Mon Sep 17 00:00:00 2001 From: Nilton Moura Date: Fri, 22 Nov 2013 15:41:34 -0200 Subject: [PATCH 046/862] Update 01-chapter2.markdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Diversas pequenas correções da língua Portuguesa, como erros de pontuação. Many little corrections of the Portuguese language, like punctuation errors. --- pt-br/02-git-basics/01-chapter2.markdown | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pt-br/02-git-basics/01-chapter2.markdown b/pt-br/02-git-basics/01-chapter2.markdown index bcf12e673..a426d25a9 100644 --- a/pt-br/02-git-basics/01-chapter2.markdown +++ b/pt-br/02-git-basics/01-chapter2.markdown @@ -59,7 +59,7 @@ A principal ferramenta utilizada para determinar quais arquivos estão em quais Isso significa que você tem um diretório de trabalho limpo — em outras palavras, não existem arquivos monitorados e modificados. Git também não encontrou qualquer arquivo não monitorado, caso contrário eles seriam listados aqui. Por fim, o comando lhe mostra em qual branch você se encontra. Por enquanto, esse sempre é o `master`, que é o padrão; você não deve se preocupar com isso. No próximo capítulo nós vamos falar sobre branches e referências em detalhes. -Vamos dizer que você adicione um novo arquivo em seu projeto, um simples arquivo `README`. Caso o arquivo não exista e você executar `git status`, você verá o arquivo não monitorado dessa forma: +Vamos dizer que você adicione um novo arquivo em seu projeto, um simples arquivo `README`. Caso o arquivo não exista e você execute `git status`, você verá o arquivo não monitorado dessa forma: $ vim README $ git status @@ -70,7 +70,7 @@ Vamos dizer que você adicione um novo arquivo em seu projeto, um simples arquiv # README nothing added to commit but untracked files present (use "git add" to track) -Você pode ver que o seu novo arquivo `README` não está sendo monitorado, pois está listado sob o cabeçalho "Untracked files" na saída do comando status. Não monitorado significa basicamente que o Git está vendo um arquivo que não existia na última captura (commit); o Git não vai incluí-lo nas suas capturas de commit até que você diga explicitamente à ele para fazer isso. Ele faz isso para que você não inclua acidentalmente arquivos binários gerados ou outros arquivos que você não tenha a intenção de incluir. Digamos, que você queira incluir o arquivo README, portanto vamos começar a monitorar este arquivo. +Você pode ver que o seu novo arquivo `README` não está sendo monitorado, pois está listado sob o cabeçalho "Untracked files" na saída do comando status. Não monitorado significa basicamente que o Git está vendo um arquivo que não existia na última captura (commit); o Git não vai incluí-lo nas suas capturas de commit até que você o diga explicitamente que assim o faça. Ele faz isso para que você não inclua acidentalmente arquivos binários gerados, ou outros arquivos que você não têm a intenção de incluir. Digamos, que você queira incluir o arquivo README, portanto vamos começar a monitorar este arquivo. ### Monitorando Novos Arquivos ### @@ -92,7 +92,7 @@ Você pode dizer que ele está selecionado pois está sob o cabeçalho “Change ### Selecionando Arquivos Modificados ### -Vamos alterar um arquivos que já está sendo monitorado. Se você alterar um aquivo previamente monitorado chamado `benchmarks.rb` e então rodar o comando `status` novamente, você terá algo semelhante a: +Vamos alterar um arquivo que já está sendo monitorado. Se você alterar um aquivo previamente monitorado chamado `benchmarks.rb` e então rodar o comando `status` novamente, você terá algo semelhante a: $ git status # On branch master @@ -107,7 +107,7 @@ Vamos alterar um arquivos que já está sendo monitorado. Se você alterar um aq # modified: benchmarks.rb # -O arquivo `benchmarks.rb` aparece sob a seção chamada “Changes not staged for commit” — que significa que um arquivo monitorado foi modificado no diretório de trabalho mas ainda não foi selecionado (staged). Para selecioná-lo, você utiliza o comando `git add` (é um comando com várias funções — você o utiliza para monitorar novos arquivos, selecionar arquivos, e para fazer outras coisas como marcar como resolvido aquivos com conflito). Agora vamos rodar o comando `git add` para selecionar o arquivo `benchmarks.rb`, e então rodar `git status` novamente: +O arquivo `benchmarks.rb` aparece sob a seção chamada “Changes not staged for commit” — que significa que um arquivo monitorado foi modificado no diretório de trabalho, mas ainda não foi selecionado (staged). Para selecioná-lo, utilize o comando `git add` (é um comando com várias funções — você o utiliza para monitorar novos arquivos, selecionar arquivos, e para fazer outras coisas como marcar como resolvido aquivos com conflito). Agora vamos rodar o comando `git add` para selecionar o arquivo `benchmarks.rb`, e então rodar `git status` novamente: $ git add benchmarks.rb $ git status @@ -156,16 +156,16 @@ Muitas vezes, você terá uma classe de arquivos que não quer que o Git automat *.[oa] *~ -A primeira linha fala para o Git ignorar qualquer arquivo finalizado em `.o` ou `.a` — arquivos *objetos* e *archive* (compactados) que devem ter produto da construção (build) de seu código. A segunda linha fala para o Git ignorar todos os arquivos que terminam com um til (`~`), os quais são utilizados por muitos editores de texto como o Emacs para marcar arquivos temporários. Você também pode incluir um diretório `log`, `tmp` ou `pid`; documentação gerada automaticamente; e assim por diante. Configurar um arquivo `.gitignore` antes de começar a trabalhar normalmente é uma boa ideia, evitando que você commite acidentalmente arquivos que não deveriam ir para o seu repositório Git. +A primeira linha fala para o Git ignorar qualquer arquivo finalizado em `.o` ou `.a` — arquivos *objetos* e *archive* (compactados) que devem ter produto da construção (build) de seu código. A segunda linha fala para o Git ignorar todos os arquivos que terminam com um til (`~`), os quais são utilizados por muitos editores de texto como o Emacs para marcar arquivos temporários. Você também pode incluir um diretório `log`, `tmp` ou `pid`; documentação gerada automaticamente; e assim por diante. Configurar um arquivo `.gitignore` antes de começar a trabalhar, normalmente é uma boa ideia, pois evita que você commite acidentalmente arquivos que não deveriam ir para o seu repositório Git. -As regras para os padrões que você pode por no arquivo `.gitignore` são as seguintes: +As regras para os padrões que você pode pôr no arquivo `.gitignore` são as seguintes: * Linhas em branco ou iniciando com `#` são ignoradas. * Padrões glob comuns funcionam. * Você pode terminar os padrões com uma barra (`/`) para especificar diretórios. * Você pode negar um padrão ao iniciá-lo com um ponto de exclamação (`!`). -Padrões glob são como expressões regulares simples que os shells usam. Um asterísco (`*`) significa zero ou mais caracteres; `[abc]` condiz com qualquer um dos caracteres de dentro dos colchetes (nesse caso a, b, ou c); um ponto de interrogação (`?`) condiz com um único caractere; e os caracteres separados por hífen dentro de colchetes (`[0-9]`) condizem à qualquer um dos caracteres entre eles (neste cado de 0 a 9). +Padrões glob são como expressões regulares simples que os shells usam. Um asterísco (`*`) significa zero ou mais caracteres; `[abc]` condiz com qualquer um dos caracteres de dentro dos colchetes (nesse caso, a, b, ou c); um ponto de interrogação (`?`) condiz com um único caractere; e os caracteres separados por hífen dentro de colchetes (`[0-9]`) condizem à qualquer um dos caracteres entre eles (neste caso, de 0 à 9). Segue um outro exemplo de arquivo `.gitignore`: @@ -183,7 +183,7 @@ Segue um outro exemplo de arquivo `.gitignore`: ### Visualizando Suas Mudanças Selecionadas e Não Selecionadas ### -Se o comando `git status` for muito vago — você quer saber exatamente o que você alterou, não apenas quais arquivos foram alterados — você pode utilizar o comando `git diff`. Nós trataremos o comando `git diff` em mais detalhes posteriormente; mas provavelmente você vai utilizá-lo com frequência para responder estas duas perguntas: O que você alterou mas ainda não selecionou (stage)? E o que você selecionou que está para ser commitado? Apesar do comando `git status` responder essas duas perguntas de maneira geral, o `git diff` mostra as linhas exatas que foram adicionadas e removidas — o patch, por assim dizer. +Se o comando `git status` for muito vago — você quer saber exatamente o que você alterou, não apenas quais arquivos foram alterados — você pode utilizar o comando `git diff`. Nós trataremos o comando `git diff` em mais detalhes posteriormente; mas provavelmente você vai utilizá-lo com frequência para responder estas duas perguntas: O que você alterou, mas ainda não selecionou (stage)? E o que você selecionou, que está para ser commitado? Apesar do comando `git status` responder essas duas perguntas de maneira geral, o `git diff` mostra as linhas exatas que foram adicionadas e removidas — o patch, por assim dizer. Vamos dizer que você edite e selecione o arquivo `README` de novo e então edite o arquivo `benchmarks.rb` sem selecioná-lo. Se você rodar o comando `status`, você novamente verá algo assim: @@ -221,7 +221,7 @@ Para ver o que você alterou mas ainda não selecionou, digite o comando `git di Este comando compara o que está no seu diretório de trabalho com o que está na sua área de seleção (staging). O resultado te mostra as mudanças que você fez que ainda não foram selecionadas. -Se você quer ver o que selecionou que irá no seu próximo commit, pode utilizar `git diff --cached`. (Nas versões do Git 1.6.1 e superiores, você também pode utilizar `git diff --staged`, o que deve ser mais fácil de lembrar.) Este comando compara as mudanças selecionadas com o seu último commit: +Se você quer ver o que selecionou que irá no seu próximo commit, pode utilizar `git diff --cached`. (Nas versões do Git 1.6.1 e superiores, você também pode utilizar `git diff --staged`, que deve ser mais fácil de lembrar.) Este comando compara as mudanças selecionadas com o seu último commit: $ git diff --cached diff --git a/README b/README @@ -238,7 +238,7 @@ Se você quer ver o que selecionou que irá no seu próximo commit, pode utiliza É importante notar que o `git diff` por si só não mostra todas as mudanças desde o último commit — apenas as mudanças que ainda não foram selecionadas. Isso pode ser confuso, pois se você selecionou todas as suas mudanças, `git diff` não te dará nenhum resultado. -Como um outro exemplo, se você selecionar o arquivo `benchmarks.rb` e então editá-lo, você pode utilizar o `git diff` para ver as mudanças no arquivo que estão selecionadas e as mudanças que não estão: +Como um outro exemplo, se você selecionar o arquivo `benchmarks.rb` e então editá-lo, você pode utilizar o `git diff` para ver as mudanças no arquivo que estão selecionadas, e as mudanças que não estão: $ git add benchmarks.rb $ echo '# test line' >> benchmarks.rb @@ -267,7 +267,7 @@ Agora você pode utilizar o `git diff` para ver o que ainda não foi selecionado ##pp Grit::GitRuby.cache_client.stats +# test line -e executar `git diff --cached` para ver o que você já alterou para o estado staged até o momento: +E executar `git diff --cached` para ver o que você já alterou para o estado staged até o momento: $ git diff --cached diff --git a/benchmarks.rb b/benchmarks.rb @@ -371,7 +371,7 @@ Em seguida, se você rodar `git rm`, a remoção do arquivo é colocada na área Na próxima vez que você fizer o commit, o arquivo sumirá e não será mais monitorado. Se você modificou o arquivo e já o adicionou na área de seleção, você deve forçar a remoção com a opção `-f`. Essa é uma funcionalidade de segurança para prevenir remoções acidentais de dados que ainda não foram gravados em um snapshot e não podem ser recuperados do Git. -Outra coisa útil que você pode querer fazer é manter o arquivo no seu diretório mas apagá-lo da sua área de seleção. Em outras palavras, você quer manter o arquivo no seu disco rígido mas não quer que o Git o monitore mais. Isso é particularmente útil se você esqueceu de adicionar alguma coisa no seu arquivo `.gitignore` e acidentalmente o adicionou, como um grande arquivo de log ou muitos arquivos `.a` compilados. Para fazer isso, use a opção `--cached`: +Outra coisa útil que você pode querer fazer é manter o arquivo no seu diretório, mas apagá-lo da sua área de seleção. Em outras palavras, você quer manter o arquivo no seu disco rígido mas não quer que o Git o monitore mais. Isso é particularmente útil se você esqueceu de adicionar alguma coisa no seu arquivo `.gitignore` e acidentalmente o adicionou, como um grande arquivo de log ou muitos arquivos `.a` compilados. Para fazer isso, use a opção `--cached`: $ git rm --cached readme.txt From 0c5ef4f8c764d66136dbfa7bdfecd2dc907ea2a1 Mon Sep 17 00:00:00 2001 From: Nilton Moura Date: Fri, 22 Nov 2013 16:50:35 -0200 Subject: [PATCH 047/862] Update 01-chapter2.markdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pequenas correções em pontuação e gramaticais da língua Portuguesa. Little punctuations corrections and rules of Portuguese language. --- pt-br/02-git-basics/01-chapter2.markdown | 32 ++++++++++++------------ 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/pt-br/02-git-basics/01-chapter2.markdown b/pt-br/02-git-basics/01-chapter2.markdown index bcf12e673..8eb77e99d 100644 --- a/pt-br/02-git-basics/01-chapter2.markdown +++ b/pt-br/02-git-basics/01-chapter2.markdown @@ -416,9 +416,9 @@ O Git descobre que o arquivo foi renomeado implicitamente, então ele não se im ## Visualizando o Histórico de Commits ## -Depois que você tenha criado vários commits, ou se você clonou um repositório com um histórico de commits existente, você provavelmente irá querer ver o que aconteceu. A ferramente mais básica e poderosa para fazer isso é o comando `git log`. +Depois que você tiver criado vários commits, ou se clonou um repositório com um histórico de commits existente, você provavelmente vai querer ver o que aconteceu. A ferramente mais básica e poderosa para fazer isso é o comando `git log`. -Estes exemplos usam um projeto muito simples chamado `simplegit` que eu frequentemente uso para demonstrações. Para pegar o projeto, execute +Estes exemplos usam um projeto muito simples chamado `simplegit`, que eu frequentemente uso para demonstrações. Para pegar o projeto, execute: git clone git://github.com/schacon/simplegit-progit.git @@ -445,7 +445,7 @@ Quando você executar `git log` neste projeto, você deve ter uma saída como es Por padrão, sem argumentos, `git log` lista os commits feitos naquele repositório em ordem cronológica reversa. Isto é, os commits mais recentes primeiro. Como você pode ver, este comando lista cada commit com seu checksum SHA-1, o nome e e-mail do autor, a data e a mensagem do commit. -Um grande número e variedade de opções para o comando `git log` estão disponíveis para mostrar a você exatamente o que você quer ver. Aqui, nós mostraremos algumas das opções mais usadas. +Um grande número e variedade de opções para o comando `git log` estão disponíveis para mostrá-lo exatamente o que você quer ver. Aqui, nós mostraremos algumas das opções mais usadas. Uma das opções mais úteis é `-p`, que mostra o diff introduzido em cada commit. Você pode ainda usar `-2`, que limita a saída somente às duas últimas entradas. @@ -487,7 +487,7 @@ Uma das opções mais úteis é `-p`, que mostra o diff introduzido em cada comm -end \ No newline at end of file -Esta opção mostra a mesma informação mas com um diff diretamente seguido de cada entrada. Isso é muito útil para revisão de código ou para navegar rapidamente e saber o que aconteceu durante uma série de commits que um colaborador adicionou. +Esta opção mostra a mesma informação, mas com um diff diretamente seguido de cada entrada. Isso é muito útil para revisão de código ou para navegar rapidamente e saber o que aconteceu durante uma série de commits que um colaborador adicionou. Você pode ainda usar uma série de opções de sumarização com `git log`. Por exemplo, se você quiser ver algumas estatísticas abreviadas para cada commit, você pode usar a opção `--stat` $ git log --stat @@ -521,14 +521,14 @@ Você pode ainda usar uma série de opções de sumarização com `git log`. Por 3 files changed, 54 insertions(+), 0 deletions(-) Como você pode ver, a opção `--stat` imprime abaixo de cada commit uma lista de arquivos modificados, quantos arquivos foram modificados, e quantas linhas nestes arquivos foram adicionadas e removidas. Ele ainda mostra um resumo destas informações no final. -Outra opção realmente útil é `--pretty`. Esta opção muda a saída do log para outro formato que não o padrão. Algumas opções pré-construídas estão disponíveis para você usar. A opção `oneline` mostra cada commit em uma única linha, o que é útil se você está olhando muitos commits. Em adição, as opções `short`, `full` e `fuller` mostram a saída aproximadamente com o mesmo formato mas com menos ou mais informações, respectivamente: +Outra opção realmente útil é `--pretty`. Esta opção muda a saída do log para outro formato que não o padrão. Algumas opções pré-construídas estão disponíveis para você usar. A opção `oneline` mostra cada commit em uma única linha, o que é útil se você está olhando muitos commits. Em adição, as opções `short`, `full` e `fuller` mostram a saída aproximadamente com o mesmo formato, mas com menos ou mais informações, respectivamente: $ git log --pretty=oneline ca82a6dff817ec66f44342007202690a93763949 changed the verison number 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code a11bef06a3f659402fe7563abf99ad00de2209e6 first commit -A opção mais interessante é `format`, que permite que você especifique seu próprio formato de saída do log. Isto é especialmente útil quando você está gerando saída para a análise automatizada máquina — porque você especifica o formato explicitamente, você sabe que ele não vai mudar junto com as atualizações do Git: +A opção mais interessante é `format`, que permite que você especifique seu próprio formato de saída do log. Isto é especialmente útil quando você está gerando saída para análise automatizada (parsing) — porque você especifica o formato explicitamente, você sabe que ele não vai mudar junto com as atualizações do Git: $ git log --pretty=format:"%h - %an, %ar : %s" ca82a6d - Scott Chacon, 11 months ago : changed the verison number @@ -546,7 +546,7 @@ Tabela 2-1 lista algumas das opções mais importantes para formatação. %p Hashes pais abreviados %an Nome do autor %ae Email do autor - %ad Data do autor (formato respeira a opção -date=) + %ad Data do autor (formato respeita a opção -date=) %ar Data do autor, relativa %cn Nome do committer %ce Email do committer @@ -554,7 +554,7 @@ Tabela 2-1 lista algumas das opções mais importantes para formatação. %cr Data do committer, relativa %s Assunto -Você deve estar se perguntando qual a diferença entre _autor_ e _committer_. O _autor_ é a pessoa que originalmente escreveu o trabalho, enquanto o _commiter_ é a pessoa que por último aplicou o trabalho. Então, se você envia um patch para o projeto e algum dos membros do núcleo aplicar o patch, ambos receberão créditos — você como o autor e o membro do núcleo como o commiter. Nós cobriremos esta distinção mais um pouco mais no *Capítulo 5*. +Você deve estar se perguntando qual a diferença entre _autor_ e _committer_. O _autor_ é a pessoa que originalmente escreveu o trabalho, enquanto o _commiter_ é a pessoa que por último aplicou o trabalho. Então, se você envia um patch para um projeto, e algum dos membros do núcleo o aplicam, ambos receberão créditos — você como o autor, e o membro do núcleo como o commiter. Nós cobriremos esta distinção um pouco mais no *Capítulo 5*. As opções `oneline` e `format` são particularmente úteis com outra opção chamada `--graph`. Esta opção gera um agradável gráfico ASCII mostrando seu branch e histórico de merges, que nós podemos ver em nossa cópia do repositório do projeto Grit: @@ -585,7 +585,7 @@ Estas são apenas algumas opções de formatação de saída do `git log` — h ### Limitando a Saída de Log ### -Em adição às opções de formatação, `git log` tem inúmeras opções de limitações úteis — que são, opções que deixam você mostrar somente um subconjunto de commits. Você já viu algumas — a opção `-2`, que mostra apenas os dois últimos commits. De fato, você pode fazer `-`, onde `n` é qualquer inteiro para mostrar os últimos `n` commits. Na realidade você provavelmente não deve usar isso frequentemente, porque o Git por padrão enfileira toda a saída em um paginador e então você vê somente uma página da saída do log por vês. +Em adição às opções de formatação, `git log` tem inúmeras opções de limitações úteis — que são opções que lhe deixam mostrar somente um subconjunto de commits. Você já viu algumas — a opção `-2`, que mostra apenas os dois últimos commits. De fato, você pode fazer `-`, onde `n` é qualquer inteiro para mostrar os últimos `n` commits. Na verdade, você provavelmente não usará isso frequentemente, porque por padrão o Git enfileira toda a saída em um paginador, e então você vê somente uma página da saída do log por vez. No entanto, as opções de limites de tempo como `--since` e `--until` são muito úteis. Por exemplo, este comando pega a lista de commits feitos nas últimas duas semanas: @@ -593,20 +593,20 @@ No entanto, as opções de limites de tempo como `--since` e `--until` são muit Este comando funciona com vários formatos — você pode especificar uma data específica(“2008-01-15”) ou uma data relativa como “2 years 1 day 3 minutes ago”. -Você pode ainda filtrar a lista de commits que batem com alguns critérios de busca. A opção `--author` permite que você filtre por algum autor específico, e a opção `--grep` deixa você buscar por palavras chave nas mensagens dos commits. (Note que se você quer especificar ambas as opções author e grep, você deve adicionar `--all-match` ou o comando considerará commits que batem com qualquer um). +Você pode ainda filtrar a lista de commits que casam com alguns critérios de busca. A opção `--author` permite que você filtre por algum autor específico, e a opção `--grep` deixa você buscar por palavras chave nas mensagens dos commits. (Note que se você quiser especificar ambas as opções author e grep simultâneamente, você deve adicionar `--all-match`, ou o comando considerará commits que casam com qualquer um.) -A última opção realmente útil para passar para `git log` como um filtro é o caminho. Se você especificar um diretório ou um nome de arquivo, você pode limitar a saída a commits que modificaram aqueles arquivos. Essa é sempre a última opção e é geralmente precedida por dois traços (`--`) para separar caminhos das opções. +A última opção realmente útil para passar para `git log` como um filtro, é o caminho. Se você especificar um diretório ou um nome de arquivo, você pode limitar a saída a commits que modificaram aqueles arquivos. Essa é sempre a última opção, e geralmente é precedida por dois traços (`--`) para separar caminhos das opções. Na Tabela 2-3 nós listamos estas e outras opções comuns para sua referência. Opção Descrição - -(n) Mostra somente os últimos n commits + -(n) Mostra somente os últimos n commits. --since, --after Limita aos commits feitos depois da data especificada. --until, --before Limita aos commits feitos antes da data especificada. - --author Somente mostra commits que o autor bate com a string especificada. + --author Somente mostra commits que o autor casa com a string especificada. --committer Somente mostra os commits em que a entrada do commiter bate com a string especificada. -Por exemplo, se você quer ver quais commits modificaram arquivos de teste no histórico do código fonte do Git que foram commitados por Julio Hamano e não foi feito merge no mês de Outrubro de 2008, você pode executar algo como: +Por exemplo, se você quer ver quais commits modificaram arquivos de teste no histórico do código fonte do Git que foram commitados por Julio Hamano em Outubro de 2008, e não foram merges, você pode executar algo como: $ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \ --before="2008-11-01" --no-merges -- t/ @@ -617,11 +617,11 @@ Por exemplo, se você quer ver quais commits modificaram arquivos de teste no hi 51a94af - Fix "checkout --track -b newbranch" on detac b0ad11e - pull: allow "git pull origin $something:$cur -Dos 20.000 commits mais novos no histórico do código fonte do Git, este comando mostra os 6 que batem com aqueles critérios. +Dos 20.000 commits mais novos no histórico do código fonte do Git, este comando mostra os 6 que casam com aqueles critérios. ### Usando Interface Gráfica para Visualizar o Histórico ### -Se você quiser usar uma ferramenta gráfica para visualizar seu histórico de commit, você pode querer dar uma olhada em um programa Tcl/Tk chamado `gitk` que é distribuído com o Git. Gitk é basicamente uma ferramente visual para `git log`, e ele aceita aproximadamente todas as opções de filtros que `git log` aceita. Se você digitar `gitk` na linha de comando em seu projeto, você deve ver algo como a Figura 2-2. +Se você quiser usar uma ferramenta gráfica para visualizar seu histórico de commit, você pode querer dar uma olhada em um programa Tcl/Tk chamado `gitk` que é distribuído com o Git. Gitk é basicamente uma ferramenta visual para `git log`, e ele aceita aproximadamente todas as opções de filtros que `git log` aceita. Se você digitar `gitk` na linha de comando em seu projeto, você deve ver algo como a Figura 2-2. Insert 18333fig0202.png Figura 2-2. O visualizador de histórico gitk. From e50da390beb549cd92148cdc691945249c0b2339 Mon Sep 17 00:00:00 2001 From: Harry Lee Date: Sun, 24 Nov 2013 20:07:25 +0800 Subject: [PATCH 048/862] =?UTF-8?q?fix=20typo=20"=E8=A7=92=E6=9C=AC"=3D>"?= =?UTF-8?q?=E8=84=9A=E6=9C=AC"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- zh/07-customizing-git/01-chapter7.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh/07-customizing-git/01-chapter7.markdown b/zh/07-customizing-git/01-chapter7.markdown index d922e284f..092312c18 100644 --- a/zh/07-customizing-git/01-chapter7.markdown +++ b/zh/07-customizing-git/01-chapter7.markdown @@ -540,7 +540,7 @@ update 脚本和 `pre-receive` 脚本十分类似。不同之处在于它会为 ## Git 强制策略实例 ### -在本节中,我们应用前面学到的知识建立这样一个Git 工作流程:检查提交信息的格式,只接受纯fast-forward内容的推送,并且指定用户只能修改项目中的特定子目录。我们将写一个客户端角本来提示开发人员他们推送的内容是否会被拒绝,以及一个服务端脚本来实际执行这些策略。 +在本节中,我们应用前面学到的知识建立这样一个Git 工作流程:检查提交信息的格式,只接受纯fast-forward内容的推送,并且指定用户只能修改项目中的特定子目录。我们将写一个客户端脚本来提示开发人员他们推送的内容是否会被拒绝,以及一个服务端脚本来实际执行这些策略。 这些脚本使用 Ruby 写成,一半由于它是作者倾向的脚本语言,另外作者觉得它是最接近伪代码的脚本语言;因而即便你不使用 Ruby 也能大致看懂。不过任何其他语言也一样适用。所有 Git 自带的样例脚本都是用 Perl 或 Bash 写的。所以从这些脚本中能找到相当多的这两种语言的挂钩样例。 From 8d3ac23fa6cf8fa02deef79726215040c57b314f Mon Sep 17 00:00:00 2001 From: Jean-Noel Avila Date: Sun, 24 Nov 2013 16:48:45 +0100 Subject: [PATCH 049/862] Fix example of filter branch To remove temporary files recursively in the project, you have first to find them recursively. This fixes #538 --- ar/06-git-tools/01-chapter6.markdown | 2 +- az/06-git-tools/01-chapter6.markdown | 2 +- ca/06-git-tools/01-chapter6.markdown | 2 +- es-ni/06-git-tools/01-chapter6.markdown | 2 +- es/06-git-tools/01-chapter6.markdown | 2 +- fr/06-git-tools/01-chapter6.markdown | 2 +- ko/06-git-tools/01-chapter6.markdown | 2 +- mk/06-git-tools/01-chapter6.markdown | 2 +- nl/06-git-tools/01-chapter6.markdown | 2 +- no-nb/06-git-tools/01-chapter6.markdown | 2 +- pl/06-git-tools/01-chapter6.markdown | 2 +- pt-br/06-git-tools/01-chapter6.markdown | 2 +- ru/06-git-tools/01-chapter6.markdown | 2 +- th/06-git-tools/01-chapter6.markdown | 2 +- tr/06-git-tools/01-chapter6.markdown | 2 +- zh-tw/06-git-tools/01-chapter6.markdown | 2 +- zh/06-git-tools/01-chapter6.markdown | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/ar/06-git-tools/01-chapter6.markdown b/ar/06-git-tools/01-chapter6.markdown index 9d2a39f0d..be116ffcf 100644 --- a/ar/06-git-tools/01-chapter6.markdown +++ b/ar/06-git-tools/01-chapter6.markdown @@ -700,7 +700,7 @@ This occurs fairly commonly. Someone accidentally commits a huge binary file wit Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter 'rm -f *~' HEAD`. +The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. diff --git a/az/06-git-tools/01-chapter6.markdown b/az/06-git-tools/01-chapter6.markdown index 71996a995..550699d2d 100644 --- a/az/06-git-tools/01-chapter6.markdown +++ b/az/06-git-tools/01-chapter6.markdown @@ -700,7 +700,7 @@ This occurs fairly commonly. Someone accidentally commits a huge binary file wit Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter 'rm -f *~' HEAD`. +The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. diff --git a/ca/06-git-tools/01-chapter6.markdown b/ca/06-git-tools/01-chapter6.markdown index 394648267..8383d2168 100644 --- a/ca/06-git-tools/01-chapter6.markdown +++ b/ca/06-git-tools/01-chapter6.markdown @@ -700,7 +700,7 @@ This occurs fairly commonly. Someone accidentally commits a huge binary file wit Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter 'rm -f *~' HEAD`. +The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. diff --git a/es-ni/06-git-tools/01-chapter6.markdown b/es-ni/06-git-tools/01-chapter6.markdown index ff656d90b..bc40ab6dc 100644 --- a/es-ni/06-git-tools/01-chapter6.markdown +++ b/es-ni/06-git-tools/01-chapter6.markdown @@ -683,7 +683,7 @@ This occurs fairly commonly. Someone accidentally commits a huge binary file wit Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter 'rm -f *~' HEAD`. +The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. diff --git a/es/06-git-tools/01-chapter6.markdown b/es/06-git-tools/01-chapter6.markdown index 0c61a7f9a..254a8656f 100644 --- a/es/06-git-tools/01-chapter6.markdown +++ b/es/06-git-tools/01-chapter6.markdown @@ -687,7 +687,7 @@ Es algo que frecuentemente suele ser necesario. Alguien confirma cambios y almac Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -Esta opción `--tree-filter`, tras cada extracción (checkout) del proyecto, lanzará el comando especificado y reconfirmará los cambios resultantes(recommit). En esta ocasión, se eliminará un archivo llamado passwords.txt de todas y cada una de las instantáneas (snapshot) almacenadas, tanto si este existe como si no. Otro ejemplo: si se desean eliminar todos los archivos de respaldo del editor que han sido almacenados por error, se podría lanzar algo así como `git filter-branch --tree-filter 'rm -f *~' HEAD`. +Esta opción `--tree-filter`, tras cada extracción (checkout) del proyecto, lanzará el comando especificado y reconfirmará los cambios resultantes(recommit). En esta ocasión, se eliminará un archivo llamado passwords.txt de todas y cada una de las instantáneas (snapshot) almacenadas, tanto si este existe como si no. Otro ejemplo: si se desean eliminar todos los archivos de respaldo del editor que han sido almacenados por error, se podría lanzar algo así como `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. Y se iria viendo como Git reescribe árboles y confirmaciones de cambio, hasta que el apuntador de la rama llegue al final. Una recomendación: en general, suele ser buena idea lanzar cualquiera de estas operaciones primero sobre una rama de pruebas y luego reinicializar (hard-reset) la rama maestra (master), una vez se haya comprobado que el resultado de las operaciones es el esperado. Si se desea lanzar `filter-branch` sobre todas las ramas del repositorio, se ha de pasar la opción `--all` al comando. diff --git a/fr/06-git-tools/01-chapter6.markdown b/fr/06-git-tools/01-chapter6.markdown index ba662065c..1fe8e5f19 100644 --- a/fr/06-git-tools/01-chapter6.markdown +++ b/fr/06-git-tools/01-chapter6.markdown @@ -822,7 +822,7 @@ Pour supprimer un fichier nommé « passwords.txt » de tout votre historique, L'option `--tree-filter` exécute la commande spécifiée pour chaque *commit* et le revalide ensuite. Dans le cas présent, vous supprimez le fichier nommé « passwords.txt » de chaque contenu, qu'il existait ou non. -Si vous voulez supprimer tous les fichiers temporaires des éditeurs validés accidentellement, vous pouvez exécuter une commande telle que `git filter-branch --tree-filter 'rm -f *~' HEAD`. +Si vous voulez supprimer tous les fichiers temporaires des éditeurs validés accidentellement, vous pouvez exécuter une commande telle que `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. Vous pourrez alors regarder Git réécrire l'arbre des *commits* et revalider à chaque fois, pour finir en modifiant la référence de la branche. C'est généralement une bonne idée de le faire dans un branche de test puis de faire une réinitialisation forte (*hard-reset*) de votre branche `master` si le résultat vous convient. diff --git a/ko/06-git-tools/01-chapter6.markdown b/ko/06-git-tools/01-chapter6.markdown index f9b23b67c..048b8344c 100644 --- a/ko/06-git-tools/01-chapter6.markdown +++ b/ko/06-git-tools/01-chapter6.markdown @@ -696,7 +696,7 @@ Git으로 일하다 보면 어떤 이유로든 커밋 히스토리를 수정해 Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -`--tree-filter` 옵션은 프로젝트를 Checkout한 후에 각 커밋에 명시한 명령어를 실행시키고 그 결과를 다시 커밋한다. 이 예제에서는 각 스냅샷에 passwords.txt라는 파일이 있으면 그 파일을 삭제한다. 실수로 편집기의 백업파일을 커밋했으면 `git filter-branch --tree-filter 'rm -f *~' HEAD`라고 실행해서 삭제할 수 있다. +`--tree-filter` 옵션은 프로젝트를 Checkout한 후에 각 커밋에 명시한 명령어를 실행시키고 그 결과를 다시 커밋한다. 이 예제에서는 각 스냅샷에 passwords.txt라는 파일이 있으면 그 파일을 삭제한다. 실수로 편집기의 백업파일을 커밋했으면 `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`라고 실행해서 삭제할 수 있다. 이 명령은 모든 파일과 커밋을 정리하고 브랜치 포인터를 다시 복원해준다. 테스팅 브랜치에서 사용할 명령을 점검하고 나서 master 브랜치를 정리한다. 그리고 `filter-branch` 명령에 `--all` 옵션을 추가하면 모든 브랜치에 적용된다. diff --git a/mk/06-git-tools/01-chapter6.markdown b/mk/06-git-tools/01-chapter6.markdown index 9d2a39f0d..be116ffcf 100644 --- a/mk/06-git-tools/01-chapter6.markdown +++ b/mk/06-git-tools/01-chapter6.markdown @@ -700,7 +700,7 @@ This occurs fairly commonly. Someone accidentally commits a huge binary file wit Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter 'rm -f *~' HEAD`. +The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. diff --git a/nl/06-git-tools/01-chapter6.markdown b/nl/06-git-tools/01-chapter6.markdown index d207fcb00..edd83de41 100644 --- a/nl/06-git-tools/01-chapter6.markdown +++ b/nl/06-git-tools/01-chapter6.markdown @@ -683,7 +683,7 @@ Dit gebeurd vrij vaak. Iemand voegt per ongeluk een enorm binair bestand toe met Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -De `--tree-filter` optie voert het gegeven commando uit na iedere checkout van het project, en commit de resultaten weer. In dit geval, verwijder je een bestand genaamd passwords.txt van iedere snapshot, of het bestaat of niet. Als je alle per ongeluk toegevoegde editor backup bestanden wilt verwijderen, kun je zoiets als dit uitvoeren `git filter-branch --tree-filter 'rm -f *~' HEAD`. +De `--tree-filter` optie voert het gegeven commando uit na iedere checkout van het project, en commit de resultaten weer. In dit geval, verwijder je een bestand genaamd passwords.txt van iedere snapshot, of het bestaat of niet. Als je alle per ongeluk toegevoegde editor backup bestanden wilt verwijderen, kun je zoiets als dit uitvoeren `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. Je kunt Git bomen en commits zien herschrijven en de branch wijzer aan het einde zien verplaatsen. Het is over het algemeen een goed idee om dit in een test branch te doen, en dan je master branch te hard-resetten nadat je gecontroleerd hebt dat de uitkomst echt zo is als je wil. Om `filter-branch` op al je branches uit te voeren, kun je `--all` aan het commando meegeven. diff --git a/no-nb/06-git-tools/01-chapter6.markdown b/no-nb/06-git-tools/01-chapter6.markdown index 71996a995..550699d2d 100644 --- a/no-nb/06-git-tools/01-chapter6.markdown +++ b/no-nb/06-git-tools/01-chapter6.markdown @@ -700,7 +700,7 @@ This occurs fairly commonly. Someone accidentally commits a huge binary file wit Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter 'rm -f *~' HEAD`. +The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. diff --git a/pl/06-git-tools/01-chapter6.markdown b/pl/06-git-tools/01-chapter6.markdown index 5225365a1..0aff34822 100644 --- a/pl/06-git-tools/01-chapter6.markdown +++ b/pl/06-git-tools/01-chapter6.markdown @@ -968,7 +968,7 @@ To często występująca sytuacja. Ktoś niechcący zapisać duży plik za pomoc Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -Opcja `--tree-filter` umożliwia wykonanie jakiejś komendy po każdej zmianie i następnie ponownie zapisuje wynik. W tym przypadku, usuwasz plik passwords.txt z każdej migawki, bez względu na to czy on istnieje czy nie. Jeżeli chcesz usunąć wszystkie niechcący dodane kopie zapasowe plików stworzone przez edytor, możesz uruchomić coś podobnego do `git filter-branch --tree-filter "rm -f *~" HEAD`. +Opcja `--tree-filter` umożliwia wykonanie jakiejś komendy po każdej zmianie i następnie ponownie zapisuje wynik. W tym przypadku, usuwasz plik passwords.txt z każdej migawki, bez względu na to czy on istnieje czy nie. Jeżeli chcesz usunąć wszystkie niechcący dodane kopie zapasowe plików stworzone przez edytor, możesz uruchomić coś podobnego do `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. diff --git a/pt-br/06-git-tools/01-chapter6.markdown b/pt-br/06-git-tools/01-chapter6.markdown index 7c5d051c3..62e4811c4 100644 --- a/pt-br/06-git-tools/01-chapter6.markdown +++ b/pt-br/06-git-tools/01-chapter6.markdown @@ -696,7 +696,7 @@ Isso é bastante comum de acontecer. Alguém acidentalmente faz um commit sem pe Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -A opção `--tree-filter` executa o comando especificado depois de cada checkout do projeto e faz o commit do resultado novamente. Neste caso, você está removendo um arquivo chamado passwords.txt de cada snapshot, quer ele exista ou não. Se você quer remover todos os arquivos de backup do editor que entraram em commits acidentalmente, você pode executar algo como `git filter-branch --tree-filter 'rm -f *~' HEAD`. +A opção `--tree-filter` executa o comando especificado depois de cada checkout do projeto e faz o commit do resultado novamente. Neste caso, você está removendo um arquivo chamado passwords.txt de cada snapshot, quer ele exista ou não. Se você quer remover todos os arquivos de backup do editor que entraram em commits acidentalmente, você pode executar algo como `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. Você irá assistir o Git reescrever árvores e commits e, em seguida, no final, mover a referência do branch. Geralmente é uma boa idéia fazer isso em um branch de teste e depois fazer um hard-reset do seu branch master depois que você viu que isso era realmente o que queria fazer. Para executar `filter-branch` em todos os seus branches, você pode informar `--all` ao comando. diff --git a/ru/06-git-tools/01-chapter6.markdown b/ru/06-git-tools/01-chapter6.markdown index 37f95dd7b..dbba23f5b 100644 --- a/ru/06-git-tools/01-chapter6.markdown +++ b/ru/06-git-tools/01-chapter6.markdown @@ -700,7 +700,7 @@ Insert 18333fig0601.png Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -Опция `--tree-filter` выполняет указанную команду после выгрузки каждой версии проекта и затем заново делает коммит из результата. В нашем случае мы удалили файл с именем passwords.txt из каждого снимка состояния независимо от того, существовал ли он там или нет. Если вы хотите удалить все случайно добавленные резервные копии, сделанные вашим текстовым редактором, выполните что-то типа `git filter-branch --tree-filter 'rm -f *~' HEAD`. +Опция `--tree-filter` выполняет указанную команду после выгрузки каждой версии проекта и затем заново делает коммит из результата. В нашем случае мы удалили файл с именем passwords.txt из каждого снимка состояния независимо от того, существовал ли он там или нет. Если вы хотите удалить все случайно добавленные резервные копии, сделанные вашим текстовым редактором, выполните что-то типа `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. Вы увидите, как Git переписывает деревья и коммиты, а в конце переставляет указатель ветки. Как правило, хороший вариант — делать это в тестовой ветке, а затем жёстко сбрасывать ветку master с помощью `reset --hard`, когда вы поймёте, что результат — это то, чего вы действительно добивались. Чтобы запустить `filter-branch` для всех веток, можно передать команде параметр `--all`. diff --git a/th/06-git-tools/01-chapter6.markdown b/th/06-git-tools/01-chapter6.markdown index 9d2a39f0d..be116ffcf 100644 --- a/th/06-git-tools/01-chapter6.markdown +++ b/th/06-git-tools/01-chapter6.markdown @@ -700,7 +700,7 @@ This occurs fairly commonly. Someone accidentally commits a huge binary file wit Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter 'rm -f *~' HEAD`. +The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. diff --git a/tr/06-git-tools/01-chapter6.markdown b/tr/06-git-tools/01-chapter6.markdown index 71996a995..550699d2d 100644 --- a/tr/06-git-tools/01-chapter6.markdown +++ b/tr/06-git-tools/01-chapter6.markdown @@ -700,7 +700,7 @@ This occurs fairly commonly. Someone accidentally commits a huge binary file wit Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter 'rm -f *~' HEAD`. +The `--tree-filter` option runs the specified command after each checkout of the project and then recommits the results. In this case, you remove a file called passwords.txt from every snapshot, whether it exists or not. If you want to remove all accidentally committed editor backup files, you can run something like `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`. You’ll be able to watch Git rewriting trees and commits and then move the branch pointer at the end. It’s generally a good idea to do this in a testing branch and then hard-reset your master branch after you’ve determined the outcome is what you really want. To run `filter-branch` on all your branches, you can pass `--all` to the command. diff --git a/zh-tw/06-git-tools/01-chapter6.markdown b/zh-tw/06-git-tools/01-chapter6.markdown index 30221c668..c5e1f5f26 100644 --- a/zh-tw/06-git-tools/01-chapter6.markdown +++ b/zh-tw/06-git-tools/01-chapter6.markdown @@ -699,7 +699,7 @@ Git 在腳本中應用了最後一次提交(`a5f4a0d`),你的歷史看起 Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -`--tree-filter` 選項會在每次 checkout 專案時先執行指定的命令然後重新提交結果。在這個例子中,你會在所有快照中刪除一個名叫 password.txt 的檔,無論它是否存在。如果你想刪除所有不小心提交上去的編輯器備份檔案,你可以執行類似 `git filter-branch --tree-filter 'rm -f *~' HEAD` 的命令。 +`--tree-filter` 選項會在每次 checkout 專案時先執行指定的命令然後重新提交結果。在這個例子中,你會在所有快照中刪除一個名叫 password.txt 的檔,無論它是否存在。如果你想刪除所有不小心提交上去的編輯器備份檔案,你可以執行類似 `git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD` 的命令。 你可以觀察到 Git 重寫目錄樹並且提交,然後將分支指標移到末尾。一個比較好的辦法是在一個測試分支上做這件事,然後在你確定結果真的是你所要的之後,再 hard-reset 你的主分支。要在你所有的分支上運行 `filter-branch` 的話,你可以傳遞一個 `--all` 參數給該命令。 diff --git a/zh/06-git-tools/01-chapter6.markdown b/zh/06-git-tools/01-chapter6.markdown index b360ae563..8a3913553 100644 --- a/zh/06-git-tools/01-chapter6.markdown +++ b/zh/06-git-tools/01-chapter6.markdown @@ -707,7 +707,7 @@ Git在脚本中应用了最后一次提交(`a5f4a0d`),你的历史看起 Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten -`--tree-filter`选项会在每次检出项目时先执行指定的命令然后重新提交结果。在这个例子中,你会在所有快照中删除一个名叫 password.txt 的文件,无论它是否存在。如果你想删除所有不小心提交上去的编辑器备份文件,你可以运行类似`git filter-branch --tree-filter 'rm -f *~' HEAD`的命令。 +`--tree-filter`选项会在每次检出项目时先执行指定的命令然后重新提交结果。在这个例子中,你会在所有快照中删除一个名叫 password.txt 的文件,无论它是否存在。如果你想删除所有不小心提交上去的编辑器备份文件,你可以运行类似`git filter-branch --tree-filter "find * -type f -name '*~' -delete" HEAD`的命令。 你可以观察到 Git 重写目录树并且提交,然后将分支指针移到末尾。一个比较好的办法是在一个测试分支上做这些然后在你确定产物真的是你所要的之后,再 hard-reset 你的主分支。要在你所有的分支上运行`filter-branch`的话,你可以传递一个`--all`给命令。 From 855c073cf8542d87c5ebb861c34dd5fc54180715 Mon Sep 17 00:00:00 2001 From: better0332 Date: Mon, 25 Nov 2013 16:47:28 +0800 Subject: [PATCH 050/862] Update 01-chapter3.markdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s worth noting here that the work you did in your hotfix branch is not contained in the files in your iss53 branch. If you need to pull it in, you can merge your master branch into your iss53 branch by running git merge master, or you can wait to integrate those changes until you decide to pull the iss53 branch back into master later. --- zh/03-git-branching/01-chapter3.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh/03-git-branching/01-chapter3.markdown b/zh/03-git-branching/01-chapter3.markdown index c5686fafc..ce915730b 100644 --- a/zh/03-git-branching/01-chapter3.markdown +++ b/zh/03-git-branching/01-chapter3.markdown @@ -191,7 +191,7 @@ Insert 18333fig0314.png Insert 18333fig0315.png 图 3-15. iss53 分支可以不受影响继续推进。 -不用担心之前 `hotfix` 分支的修改内容尚未包含到 `iss53` 中来。如果确实需要纳入此次修补,可以用 `git merge master` 把 master 分支合并到 `iss53`;或者等 `iss53` 完成之后,再将 `iss53` 分支中的更新并入 `master`。 +值得注意的是之前 `hotfix` 分支的修改内容尚未包含到 `iss53` 中来。如果需要纳入此次修补,可以用 `git merge master` 把 master 分支合并到 `iss53`;或者等 `iss53` 完成之后,再将 `iss53` 分支中的更新并入 `master`。 ### 分支的合并 ### From 981c04d9a93a4e156a9f47e37aa9b0416bf0fd79 Mon Sep 17 00:00:00 2001 From: harupong Date: Tue, 26 Nov 2013 17:39:33 +0900 Subject: [PATCH 051/862] [ja] Apply c267f27 --- ja/03-git-branching/01-chapter3.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ja/03-git-branching/01-chapter3.markdown b/ja/03-git-branching/01-chapter3.markdown index f61f7a2d1..71afcde2d 100644 --- a/ja/03-git-branching/01-chapter3.markdown +++ b/ja/03-git-branching/01-chapter3.markdown @@ -15,7 +15,7 @@ Git にコミットすると、Git はコミットオブジェクトを作成し $ git add README test.rb LICENSE $ git commit -m 'initial commit of my project' -`git commit` を実行してコミットを作成すると、Git は各サブディレクトリ (この場合はプロジェクトのルートディレクトリのみ) のチェックサムを計算し、ツリーオブジェクトを Git リポジトリに格納します。それから、メタデータおよびルートオブジェクトツリーへのポインタを含むコミットオブジェクトを作成します。これで、必要に応じてこのスナップショットを再作成できるようになります。 +`git commit` を実行すると、プロジェクト内全ディレクトリのチェックサムが計算され、`tree` オブジェクトとして Git リポジトリに格納されます。続いて、メタデータおよびさきほどの `tree` オブジェクトへのポインタを含むコミットオブジェクトを作成します。これで、必要に応じてこのスナップショットを再作成できるようになります。 この時点で、Git リポジトリには 5 つのオブジェクトが含まれています。3 つのファイルそれぞれの中身をあらわす blob オブジェクト、ディレクトリの中身の一覧とどのファイルがどの blob に対応するかをあらわすツリーオブジェクト、そしてそのルートツリーおよびすべてのメタデータへのポインタを含むコミットオブジェクトです。Git リポジトリ内のデータを概念図であらわすと、図 3-1 のようになります。 From f127dd3d68d87201c3e6f54a48de39677541b211 Mon Sep 17 00:00:00 2001 From: harupong Date: Tue, 26 Nov 2013 17:50:26 +0900 Subject: [PATCH 052/862] [ja] Apply 90c92ce --- ja/08-git-and-other-scms/01-chapter8.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ja/08-git-and-other-scms/01-chapter8.markdown b/ja/08-git-and-other-scms/01-chapter8.markdown index 5d8d8ded0..03b252da0 100644 --- a/ja/08-git-and-other-scms/01-chapter8.markdown +++ b/ja/08-git-and-other-scms/01-chapter8.markdown @@ -370,7 +370,7 @@ SVN で使っている作者の一覧を取得するには、このようにし このファイルを `git svn` に渡せば、作者のデータをより正確にマッピングできるようになります。また、Subversion が通常インポートするメタデータを含めないよう `git svn` に指示することもできます。そのためには `--no-metadata` を `clone` コマンドあるいは `init` コマンドに渡します。そうすると、 `import` コマンドは次のようになります。 - $ git-svn clone http://my-project.googlecode.com/svn/ \ + $ git svn clone http://my-project.googlecode.com/svn/ \ --authors-file=users.txt --no-metadata -s my_project これで、Subversion をちょっとマシにインポートした `my_project` ディレクトリができあがりました。コミットがこんなふうに記録されるのではなく、 From 21f8d9ee07c36428509c2ef642400ed2e72ec7c7 Mon Sep 17 00:00:00 2001 From: Fredrik Sudmann Date: Tue, 26 Nov 2013 10:43:17 +0100 Subject: [PATCH 053/862] Translated the "Getting Started" section The old translation was terrible. Filled with bad language and typos. I have started from the beginning, pasting in the english version of the file. --- no-nb/01-introduction/01-chapter1.markdown | 88 +++++++++++----------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/no-nb/01-introduction/01-chapter1.markdown b/no-nb/01-introduction/01-chapter1.markdown index 105bc86ab..4bf89dcb8 100644 --- a/no-nb/01-introduction/01-chapter1.markdown +++ b/no-nb/01-introduction/01-chapter1.markdown @@ -1,59 +1,59 @@ -# Å komme igang # +# Komme i gang # -Dette kapittelet vil være on å komme igang med Git. Vi vil begynne med å forklare litt om bakgrunnen til versjons kontoll verktøy, then move on to how to get Git running on your system and finally how to get it setup to start working with. At the end of this chapter you should understand why Git is around, why you should use it and you should be all setup to do so. +Dette kapittelet handler om å komme i gang med Git. Vi vil begynne på begynnelsen, ved å fortelle noe om bakgrunnen til versjonskontroll, før vi går over til hvordan du kan få Git til å kjøre på ditt system, og til slutt hvordan man kan sette opp og begynne å arbeide med det. Ved kapittelets slutt burde du kunne forstå hvorfor Git finnes, hvorfor du burde bruke det, og du burde være satt opp til å gjøre det. -## Om versjons kontroll ## +## About Version Control ## -What is version control, and why should you care? Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later. For the examples in this book you will use software source code as the files being version controlled, though in reality you can do this with nearly any type of file on a computer. +What is version control, and why should you care? Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later. Even though the examples in this book show software source code as the files under version control, in reality any type of file on a computer can be placed under version control. -If you are a graphic or web designer and want to keep every version of an image or layout (which you would most certainly want to), a Version Control System (VCS) is a very wise thing to use. It allows you to revert files back to a previous state, revert the entire project back to a previous state, compare changes over time, see who last modified something that might be causing a problem, who introduced an issue and when, and more. Using a VCS also generally means that if you screw things up or lose files, you can easily recover. In addition, you get all this for very little overhead. +If you are a graphic or web designer and want to keep every version of an image or layout (which you certainly would), it is very wise to use a Version Control System (VCS). A VCS allows you to: revert files back to a previous state, revert the entire project back to a previous state, review changes made over time, see who last modified something that might be causing a problem, who introduced an issue and when, and more. Using a VCS also means that if you screw things up or lose files, you can generally recover easily. In addition, you get all this for very little overhead. -### Lokale versjons kontoll systemer ### +### Local Version Control Systems ### Many people’s version-control method of choice is to copy files into another directory (perhaps a time-stamped directory, if they’re clever). This approach is very common because it is so simple, but it is also incredibly error prone. It is easy to forget which directory you’re in and accidentally write to the wrong file or copy over files you don’t mean to. To deal with this issue, programmers long ago developed local VCSs that had a simple database that kept all the changes to files under revision control (see Figure 1-1). -Insert 18333fig0101.png +Insert 18333fig0101.png Figure 1-1. Local version control diagram. -One of the more popular VCS tools was a system called rcs, which is still distributed with many computers today. Even the popular Mac OS X operating system includes the rcs command when you install the Developer Tools. This tool basically works by keeping patch sets (that is, the differences between files) from one change to another in a special format on disk; it can then re-create what any file looked like at any point in time by adding up all the patches. +One of the more popular VCS tools was a system called rcs, which is still distributed with many computers today. Even the popular Mac OS X operating system includes the rcs command when you install the Developer Tools. This tool basically works by keeping patch sets (that is, the differences between files) from one revision to another in a special format on disk; it can then recreate what any file looked like at any point in time by adding up all the patches. -### Sentrale versjons kontroll systemer ### +### Centralized Version Control Systems ### The next major issue that people encounter is that they need to collaborate with developers on other systems. To deal with this problem, Centralized Version Control Systems (CVCSs) were developed. These systems, such as CVS, Subversion, and Perforce, have a single server that contains all the versioned files, and a number of clients that check out files from that central place. For many years, this has been the standard for version control (see Figure 1-2). -Insert 18333fig0102.png +Insert 18333fig0102.png Figure 1-2. Centralized version control diagram. This setup offers many advantages, especially over local VCSs. For example, everyone knows to a certain degree what everyone else on the project is doing. Administrators have fine-grained control over who can do what; and it’s far easier to administer a CVCS than it is to deal with local databases on every client. However, this setup also has some serious downsides. The most obvious is the single point of failure that the centralized server represents. If that server goes down for an hour, then during that hour nobody can collaborate at all or save versioned changes to anything they’re working on. If the hard disk the central database is on becomes corrupted, and proper backups haven’t been kept, you lose absolutely everything—the entire history of the project except whatever single snapshots people happen to have on their local machines. Local VCS systems suffer from this same problem—whenever you have the entire history of the project in a single place, you risk losing everything. -### Distribuerte kontroll systemer ### +### Distributed Version Control Systems ### This is where Distributed Version Control Systems (DVCSs) step in. In a DVCS (such as Git, Mercurial, Bazaar or Darcs), clients don’t just check out the latest snapshot of the files: they fully mirror the repository. Thus if any server dies, and these systems were collaborating via it, any of the client repositories can be copied back up to the server to restore it. Every checkout is really a full backup of all the data (see Figure 1-3). -Insert 18333fig0103.png +Insert 18333fig0103.png Figure 1-3. Distributed version control diagram. Furthermore, many of these systems deal pretty well with having several remote repositories they can work with, so you can collaborate with different groups of people in different ways simultaneously within the same project. This allows you to set up several types of workflows that aren’t possible in centralized systems, such as hierarchical models. -## En kort historie om Git ## +## A Short History of Git ## As with many great things in life, Git began with a bit of creative destruction and fiery controversy. The Linux kernel is an open source software project of fairly large scope. For most of the lifetime of the Linux kernel maintenance (1991–2002), changes to the software were passed around as patches and archived files. In 2002, the Linux kernel project began using a proprietary DVCS system called BitKeeper. -I 2005, the relationship between the community that developed the Linux kernel and the commercial company that developed BitKeeper broke down, and the tool’s free-of-charge status was revoked. This prompted the Linux development community (and in particular Linus Torvalds, the creator of Linux) to develop their own tool based on some of the lessons they learned while using BitKeeper. Some of the goals of the new system were as follows: +In 2005, the relationship between the community that developed the Linux kernel and the commercial company that developed BitKeeper broke down, and the tool’s free-of-charge status was revoked. This prompted the Linux development community (and in particular Linus Torvalds, the creator of Linux) to develop their own tool based on some of the lessons they learned while using BitKeeper. Some of the goals of the new system were as follows: -* Fast -* Enkel design -* Sterk støtte for ikke-liniær utvikling (tusenvis av paralelle grener) -* Fult distibuert +* Speed +* Simple design +* Strong support for non-linear development (thousands of parallel branches) +* Fully distributed * Able to handle large projects like the Linux kernel efficiently (speed and data size) -Siden fødselen i 2005, har Git evolved and matured to be easy to use and yet retain these initial qualities. It’s incredibly fast, it’s very efficient with large projects, and it has an incredible branching system for non-linear development (See Chapter 3). +Since its birth in 2005, Git has evolved and matured to be easy to use and yet retain these initial qualities. It’s incredibly fast, it’s very efficient with large projects, and it has an incredible branching system for non-linear development (See Chapter 3). -## Grunnleggende Git ## +## Git Basics ## So, what is Git in a nutshell? This is an important section to absorb, because if you understand what Git is and the fundamentals of how it works, then using Git effectively will probably be much easier for you. As you learn Git, try to clear your mind of the things you may know about other VCSs, such as Subversion and Perforce; doing so will help you avoid subtle confusion when using the tool. Git stores and thinks about information much differently than these other systems, even though the user interface is fairly similar; understanding those differences will help prevent you from becoming confused while using it. @@ -61,17 +61,17 @@ So, what is Git in a nutshell? This is an important section to absorb, because i The major difference between Git and any other VCS (Subversion and friends included) is the way Git thinks about its data. Conceptually, most other systems store information as a list of file-based changes. These systems (CVS, Subversion, Perforce, Bazaar, and so on) think of the information they keep as a set of files and the changes made to each file over time, as illustrated in Figure 1-4. -Insert 18333fig0104.png +Insert 18333fig0104.png Figure 1-4. Other systems tend to store data as changes to a base version of each file. -Git doesn’t think of or store its data this way. Instead, Git thinks of its data more like a set of snapshots of a mini filesystem. Every time you commit, or save the state of your project in Git, it basically takes a picture of what all your files look like at that moment and stores a reference to that snapshot. To be efficient, if files have not changed, Git doesn’t store the file again—just a link to the previous identical file it has already stored. Git thinks about its data more like Figure 1-5. +Git doesn’t think of or store its data this way. Instead, Git thinks of its data more like a set of snapshots of a mini filesystem. Every time you commit, or save the state of your project in Git, it basically takes a picture of what all your files look like at that moment and stores a reference to that snapshot. To be efficient, if files have not changed, Git doesn’t store the file again—just a link to the previous identical file it has already stored. Git thinks about its data more like Figure 1-5. -Insert 18333fig0105.png +Insert 18333fig0105.png Figure 1-5. Git stores data as snapshots of the project over time. This is an important distinction between Git and nearly all other VCSs. It makes Git reconsider almost every aspect of version control that most other systems copied from the previous generation. This makes Git more like a mini filesystem with some incredibly powerful tools built on top of it, rather than simply a VCS. We’ll explore some of the benefits you gain by thinking of your data this way when we cover Git branching in Chapter 3. -### Nesten alle operasjoner er lokale ### +### Nearly Every Operation Is Local ### Most operations in Git only need local files and resources to operate — generally no information is needed from another computer on your network. If you’re used to a CVCS where most operations have that network latency overhead, this aspect of Git will make you think that the gods of speed have blessed Git with unworldly powers. Because you have the entire history of the project right there on your local disk, most operations seem almost instantaneous. @@ -101,7 +101,7 @@ Now, pay attention. This is the main thing to remember about Git if you want the This leads us to the three main sections of a Git project: the Git directory, the working directory, and the staging area. -Insert 18333fig0106.png +Insert 18333fig0106.png Figure 1-6. Working directory, staging area, and git directory. The Git directory is where Git stores the metadata and object database for your project. This is the most important part of Git, and it is what is copied when you clone a repository from another computer. @@ -133,11 +133,11 @@ To install Git, you need to have the following libraries that Git depends on: cu $ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \ libz-dev libssl-dev - + When you have all the necessary dependencies, you can go ahead and grab the latest snapshot from the Git web site: http://git-scm.com/download - + Then, compile and install: $ tar -zxf git-1.7.2.2.tar.gz @@ -148,8 +148,8 @@ Then, compile and install: After this is done, you can also get Git via Git itself for updates: $ git clone git://git.kernel.org/pub/scm/git/git.git - -### Installasjon Linux ### + +### Installing on Linux ### If you want to install Git on Linux via a binary installer, you can generally do so through the basic package-management tool that comes with your distribution. If you’re on Fedora, you can use yum: @@ -159,13 +159,13 @@ Or if you’re on a Debian-based distribution like Ubuntu, try apt-get: $ apt-get install git -### Installasjon på Mac ### +### Installing on Mac ### There are two easy ways to install Git on a Mac. The easiest is to use the graphical Git installer, which you can download from the Google Code page (see Figure 1-7): http://code.google.com/p/git-osx-installer -Insert 18333fig0107.png +Insert 18333fig0107.png Figure 1-7. Git OS X installer. The other major way is to install Git via MacPorts (`http://www.macports.org`). If you have MacPorts installed, install Git via @@ -174,7 +174,7 @@ The other major way is to install Git via MacPorts (`http://www.macports.org`). You don’t have to add all the extras, but you’ll probably want to include +svn in case you ever have to use Git with Subversion repositories (see Chapter 8). -### Installasjon på Windows ### +### Installing on Windows ### Installing Git on Windows is very easy. The msysGit project has one of the easier installation procedures. Simply download the installer exe file from the GitHub page, and run it: @@ -182,33 +182,35 @@ Installing Git on Windows is very easy. The msysGit project has one of the easie After it’s installed, you have both a command-line version (including an SSH client that will come in handy later) and the standard GUI. -## Første-gangs oppsett for Git ## +Note on Windows usage: you should use Git with the provided msysGit shell (Unix style), it allows to use the complex lines of command given in this book. If you need, for some reason, to use the native Windows shell / command line console, you have to use double quotes instead of simple quotes (for parameters with spaces in them) and you must quote the parameters ending with the circumflex accent (^) if they are last on the line, as it is a continuation symbol in Windows. + +## First-Time Git Setup ## Now that you have Git on your system, you’ll want to do a few things to customize your Git environment. You should have to do these things only once; they’ll stick around between upgrades. You can also change them at any time by running through the commands again. Git comes with a tool called git config that lets you get and set configuration variables that control all aspects of how Git looks and operates. These variables can be stored in three different places: -* `/etc/gitconfig` file: Contains values for every user on the system and all their repositories. If you pass the option` --system` to `git config`, it reads and writes from this file specifically. -* `~/.gitconfig` file: Specific to your user. You can make Git read and write to this file specifically by passing the `--global` option. +* `/etc/gitconfig` file: Contains values for every user on the system and all their repositories. If you pass the option` --system` to `git config`, it reads and writes from this file specifically. +* `~/.gitconfig` file: Specific to your user. You can make Git read and write to this file specifically by passing the `--global` option. * config file in the git directory (that is, `.git/config`) of whatever repository you’re currently using: Specific to that single repository. Each level overrides values in the previous level, so values in `.git/config` trump those in `/etc/gitconfig`. -På Windows systemer, Git leter etter `.gitconfig` filen i `$HOME` mappen (`C:\Documents and Settings\$USER` for de fleste). It also still looks for /etc/gitconfig, although it’s relative to the MSys root, which is wherever you decide to install Git on your Windows system when you run the installer. +On Windows systems, Git looks for the `.gitconfig` file in the `$HOME` directory (`%USERPROFILE%` in Windows’ environment), which is `C:\Documents and Settings\$USER` or `C:\Users\$USER` for most people, depending on version (`$USER` is `%USERNAME%` in Windows’ environment). It also still looks for /etc/gitconfig, although it’s relative to the MSys root, which is wherever you decide to install Git on your Windows system when you run the installer. -### Din identitet ### +### Your Identity ### The first thing you should do when you install Git is to set your user name and e-mail address. This is important because every Git commit uses this information, and it’s immutably baked into the commits you pass around: - $ git config --global user.name "Ole Nordmann" - $ git config --global user.email ole@example.com + $ git config --global user.name "John Doe" + $ git config --global user.email johndoe@example.com Again, you need to do this only once if you pass the `--global` option, because then Git will always use that information for anything you do on that system. If you want to override this with a different name or e-mail address for specific projects, you can run the command without the `--global` option when you’re in that project. -### Din tekstbehandler ### +### Your Editor ### Now that your identity is set up, you can configure the default text editor that will be used when Git needs you to type in a message. By default, Git uses your system’s default editor, which is generally Vi or Vim. If you want to use a different text editor, such as Emacs, you can do the following: $ git config --global core.editor emacs - + ### Your Diff Tool ### Another useful option you may want to configure is the default diff tool to use to resolve merge conflicts. Say you want to use vimdiff: @@ -245,13 +247,13 @@ If you ever need help while using Git, there are three ways to get the manual pa $ git --help $ man git- -F.eks., du kan gå til manpage hjelpen for config kommandoen ved å kjøre +For example, you can get the manpage help for the config command by running $ git help config These commands are nice because you can access them anywhere, even offline. If the manpages and this book aren’t enough and you need in-person help, you can try the `#git` or `#github` channel on the Freenode IRC server (irc.freenode.net). These channels are regularly filled with hundreds of people who are all very knowledgeable about Git and are often willing to help. -## Sammendrag ## +## Summary ## You should have a basic understanding of what Git is and how it’s different from the CVCS you may have been using. You should also now have a working version of Git on your system that’s set up with your personal identity. It’s now time to learn some Git basics. From 04ce6328d1cded31b9528ff6ae8eb5b42d3b5b7d Mon Sep 17 00:00:00 2001 From: Fredrik Sudmann Date: Tue, 26 Nov 2013 12:28:01 +0100 Subject: [PATCH 054/862] Translated the "About Version Control" section --- no-nb/01-introduction/01-chapter1.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/no-nb/01-introduction/01-chapter1.markdown b/no-nb/01-introduction/01-chapter1.markdown index 4bf89dcb8..734a299ba 100644 --- a/no-nb/01-introduction/01-chapter1.markdown +++ b/no-nb/01-introduction/01-chapter1.markdown @@ -2,11 +2,11 @@ Dette kapittelet handler om å komme i gang med Git. Vi vil begynne på begynnelsen, ved å fortelle noe om bakgrunnen til versjonskontroll, før vi går over til hvordan du kan få Git til å kjøre på ditt system, og til slutt hvordan man kan sette opp og begynne å arbeide med det. Ved kapittelets slutt burde du kunne forstå hvorfor Git finnes, hvorfor du burde bruke det, og du burde være satt opp til å gjøre det. -## About Version Control ## +## Om versjonskontroll ## -What is version control, and why should you care? Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later. Even though the examples in this book show software source code as the files under version control, in reality any type of file on a computer can be placed under version control. +Hva er versjonskontroll, og hvorfor burdeu du bry deg? Versjonskontroll er et system som holder styr på forandringer i en fil, eller et sett av filer over tid, slik at du kan finne tilbake til spesifikke versjoner senere. Selv om eksemplene i denne boka viser kildekodefiler under versjonskontroll, kan man i realiteten bruke det på alle typer filer på en datamaskin. -If you are a graphic or web designer and want to keep every version of an image or layout (which you certainly would), it is very wise to use a Version Control System (VCS). A VCS allows you to: revert files back to a previous state, revert the entire project back to a previous state, review changes made over time, see who last modified something that might be causing a problem, who introduced an issue and when, and more. Using a VCS also means that if you screw things up or lose files, you can generally recover easily. In addition, you get all this for very little overhead. +Er du en grafisk designer eller arbeider med webdesign og ønsker å beholde alle versjoner av et bilde eller en layout (som du sannsynligvis vil), så er det lurt å bruke et Version Control System (VCS). Et VCS gjør det mulig for deg å: tilbakestille filer til en tidligere utgave, tilbakestille hele prosjektet til en tidligere utgave, sjekke forandringer over tid, se hvem som sist forandret noe som muligens forårsaker et problem, hvem som introduserte en sak og når, osv. Å benytte seg av et VCS betyr også at dersom du roter det til eller mister filer, kan du vanligvis komme tilbake opp å kjøre raskt og enkelt. I tillegg, så får du alt dette uten at det krever noe videre av deg eller systemet ditt. ### Local Version Control Systems ### From ebc95397d6b74a95e673d33c24f2e7a1ec5c2bf3 Mon Sep 17 00:00:00 2001 From: Nilton Moura Date: Thu, 28 Nov 2013 18:14:18 -0200 Subject: [PATCH 055/862] Update 01-chapter2.markdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Algumas correções entre a parte 2.4 e 2.8. A maioria de pontuação, mas eventualmente pode haver outro pequeno ajuste. Some corrections between part 2.4 and 2.8. Mostly about punctuation, but eventually can have another little adjust. --- pt-br/02-git-basics/01-chapter2.markdown | 42 ++++++++++++------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/pt-br/02-git-basics/01-chapter2.markdown b/pt-br/02-git-basics/01-chapter2.markdown index 10541d1b8..a773e232c 100644 --- a/pt-br/02-git-basics/01-chapter2.markdown +++ b/pt-br/02-git-basics/01-chapter2.markdown @@ -630,19 +630,19 @@ Você pode ver o histórico de commit na metade de cima da janela juntamente com ## Desfazendo Coisas ## -Em qualquer fase, você pode querer desfazer alguma coisa. Aqui, vamos ver algumas ferramentas básicas para desfazer modificações que você fez. Cuidado, porque você não pode desfazer algumas dessas mudanças. Essa é uma das poucas áreas no Git onde você pode perder algum trabalho se você fizer errado. +Em qualquer fase, você pode querer desfazer alguma coisa. Aqui, veremos algumas ferramentas básicas para desfazer modificações que você fez. Cuidado, porque você não pode desfazer algumas dessas mudanças. Essa é uma das poucas áreas no Git onde você pode perder algum trabalho se fizer errado. ### Modificando Seu Último Commit ### -Uma das mais comuns situações de desfazer acontece quando você faz o commit muito cedo e possivelmente esqueceu de adicionar alguns arquivos, ou você bagunçou sua mensagem de commit. Se você quer tentar fazer esse commit de novo, você pode executá-lo com a opção `--amend`: +Uma das situações mais comuns para desfazer algo, acontece quando você faz o commit muito cedo e possivelmente esqueceu de adicionar alguns arquivos, ou você bagunçou sua mensagem de commit. Se você quiser tentar fazer novamente esse commit, você pode executá-lo com a opção `--amend`: $ git commit --amend Esse comando pega sua área de seleção e a utiliza no commit. Se você não fez nenhuma modificação desde seu último commit (por exemplo, você rodou esse comando imediatamente após seu commit anterior), seu snapshot será exatamente o mesmo e tudo que você mudou foi sua mensagem de commit. -O mesmo editor de mensagem de commits abre, mas ele já tem a mensagem do seu commit anterior. Você pode editar a mensagem como sempre, mas ele substituirá seu último commit. +O mesmo editor de mensagem de commits abre, mas ele já tem a mensagem do seu commit anterior. Você pode editar a mensagem como sempre, mas ela substituirá seu último commit. -Como exemplo, se você fez um commit e esqueceu de adicionar na área de seleção as modificações de um arquivo que gostaria de adicionar nesse commit, você pode fazer algo como isso: +Por exemplo, se você fez um commit e esqueceu de adicionar na área de seleção as modificações de um arquivo que gostaria de ter adicionado nesse commit, você pode fazer algo como isso: $ git commit -m 'initial commit' $ git add forgotten_file @@ -664,7 +664,7 @@ As duas próximas seções mostram como trabalhar nas suas modificações na ár # modified: benchmarks.rb # -Logo abaixo do texto “Changes to be committed”, ele diz `use git reset HEAD ... to unstage` ("use `git reset HEAD ...` para retirá-los do estado unstage"). Então, vamos usar esse conselho para retirar o arquivo `benchmarks.rb`: +Logo abaixo do texto “Changes to be committed”, ele diz `use git reset HEAD ... to unstage` ("use `git reset HEAD ...` para retirá-los do estado unstaged"). Então, vamos usar esse conselho para retirar o arquivo `benchmarks.rb`: $ git reset HEAD benchmarks.rb benchmarks.rb: locally modified @@ -682,7 +682,7 @@ Logo abaixo do texto “Changes to be committed”, ele diz `use git reset HEAD # modified: benchmarks.rb # -O comando é um pouco estranho, mas funciona. O arquivo `benchmarks.rb` está modificado mas, mais uma vez fora da área de seleção. +O comando é um pouco estranho, mas funciona. O arquivo `benchmarks.rb` está modificado, mas, novamente fora da área de seleção. ### Desfazendo um Arquivo Modificado ### @@ -708,7 +708,7 @@ Ele diz explicitamente como descartar as modificações que você fez (pelo meno Você pode ver que as alterações foram revertidas. Perceba também que esse comando é perigoso: qualquer alteração que você fez nesse arquivo foi desfeita — você acabou de copiar outro arquivo sobre ele. Nunca use esse comando a menos que você tenha certeza absoluta que não quer o arquivo. Se você só precisa tirá-lo do caminho, vamos falar sobre stash e branch no próximo capítulo; geralmente essas são maneiras melhores de agir. -Lembre-se, qualquer coisa que foi incluída com um commit no Git quase sempre pode ser recuperada. Até mesmo commits que estavam em branches que foram apagados ou commits que foram sobrescritos com um commit `--amend` podem ser recuperados (consulte o *Capítulo 9* para recuperação de dados). No entanto, qualquer coisa que você perder que nunca foi commitada provavelmente nunca mais será vista novamente. +Lembre-se, qualquer coisa que foi incluída com um commit no Git quase sempre pode ser recuperada. Até mesmo commits que estavam em branches que foram apagados ou commits que foram sobrescritos com um commit `--amend` podem ser recuperados (consulte o *Capítulo 9* para recuperação de dados). No entanto, qualquer coisa que você perder que nunca foi commitada, provavelmente nunca mais será vista novamente. ## Trabalhando com Remotos ## @@ -730,7 +730,7 @@ Para ver quais servidores remotos você configurou, você pode executar o comand $ git remote origin -Você também pode especificar `-v`, que mostra a você a URL que o Git armazenou para o nome do remoto: +Você também pode especificar `-v`, que mostra a URL que o Git armazenou para o nome do remoto: $ git remote -v origin git://github.com/schacon/ticgit.git (fetch) @@ -746,11 +746,11 @@ Se você tem mais de um remoto, o comando lista todos. Por exemplo, meu reposit koke git://github.com/koke/grit.git origin git@github.com:mojombo/grit.git -Isso significa que podemos puxar contribuições de qualquer um desses usuários muito facilmente. Mas note que somente o remoto origin é uma URL SSH, é o único pra onde eu posso fazer o push (vamos ver o motivo disso no *Capítulo 4*). +Isso significa que podemos puxar contribuições de qualquer um desses usuários muito facilmente. Mas note que somente o remoto origin é uma URL SSH, sendo o único pra onde eu posso fazer o push (vamos ver o motivo disso no *Capítulo 4*). ### Adicionando Repositórios Remotos ### -Eu mencionei e dei algumas demonstrações de adição de repositórios remotos nas seções anteriores, mas aqui está como fazê-lo explicitamente. Para adicionar um novo repositório remoto no Git com um nome curto para que você possa fazer referência facilmente, execute `git remote add [nomecurto] [url]`: +Eu mencionei e dei algumas demonstrações de adição de repositórios remotos nas seções anteriores, mas aqui está como fazê-lo explicitamente. Para adicionar um novo repositório remoto no Git com um nome curto, para que você possa fazer referência facilmente, execute `git remote add [nomecurto] [url]`: $ git remote origin @@ -790,7 +790,7 @@ Quando o seu projeto estiver pronto para ser compartilhado, você tem que enviá $ git push origin master -Este comando funcionando apenas se você clonou de um servidor onde você tenha permissão para escrita e se ninguém mais enviou dados no meio tempo. Se você e mais alguém clonar ao mesmo tempo e você enviar suas modificações após a pessoa ter enviado as dela, o seu push será rejeitado. Você terá que fazer um pull das modificações deste outro alguém antes e incorporá-las às suas antes que você tenha permissão para enviá-las. Veja o *Capítulo 3* para mais detalhes sobre como enviar suas modificações para servidores remotos. +Este comando funciona apenas se você clonou de um servidor que você têm permissão para escrita, e se mais ninguém enviou dados no meio tempo. Se você e mais alguém clonarem ao mesmo tempo, e você enviar suas modificações após a pessoa ter enviado as dela, o seu push será rejeitado. Antes, você terá que fazer um pull das modificações deste outro alguém, e incorporá-las às suas para que você tenha permissão para enviá-las. Veja o *Capítulo 3* para mais detalhes sobre como enviar suas modificações para servidores remotos. ### Inspecionando um Remoto ### @@ -805,7 +805,7 @@ Se você quer ver mais informação sobre algum remoto em particular, você pode master ticgit -Ele lista a URL do repositório remoto assim como as branches sendo rastreadas. O resultado deste comando lhe diz que se você está na branch master e rodar `git pull`, ele irá automaticamente fazer um merge na branch master no remoto depois que ele fizer o fetch de todas as referências remotas. Ele também lista todas as referências remotas que foram puxadas. +Ele lista a URL do repositório remoto assim como as branches sendo rastreadas. O resultado deste comando lhe diz que se você está na branch master e rodar `git pull`, ele automaticamente fará um merge na branch master no remoto depois que ele fizer o fetch de todas as referências remotas. Ele também lista todas as referências remotas que foram puxadas. Este é um simples exemplo que você talvez encontre por aí. Entretanto, quando se usa o Git pra valer, você pode ver muito mais informação vindo de `git remote show`: @@ -831,7 +831,7 @@ Este é um simples exemplo que você talvez encontre por aí. Entretanto, quando Local branch pushed with 'git push' master:master -Este comando mostra qual branch é automaticamente pushed quando você roda `git push` em determinadas branches. Ele também mostra quais branches remotas que estão no servidor e você não tem, quais branches remotas você tem e que foram removidos do servidor, e múltiplas branches que são automaticamente merged quando você roda `git pull`. +Este comando mostra qual branch é automaticamente enviado (pushed) quando você roda `git push` em determinados branches. Ele também mostra quais branches remotos que estão no servidor e você não tem, quais branches remotos você tem e que foram removidos do servidor, e múltiplos branches que são automaticamente mesclados (merged) quando você roda `git pull`. ### Removendo e Renomeando Remotos ### @@ -842,7 +842,7 @@ Se você quiser renomear uma referência, em versões novas do Git você pode ro origin paul -É válido mencionar que isso modifica também os nomes das branches no servidor remoto. O que costumava ser referenciado como `pb/master` agora é `paul/master`. +É válido mencionar que isso modifica também os nomes dos branches no servidor remoto. O que costumava ser referenciado como `pb/master` agora é `paul/master`. Se você quiser remover uma referência por qualquer razão — você moveu o servidor ou não está mais usando um mirror específico, ou talvez um contribuidor não está mais contribuindo — você usa `git remote rm`: @@ -852,7 +852,7 @@ Se você quiser remover uma referência por qualquer razão — você moveu o se ## Tagging ## -Assim como a maioria dos VCS's, Git tem a habilidade de criar tags em pontos específicos na história do código como pontos importantes. Geralmente as pessoas usam esta funcionalidade para marcar pontos de release (`v1.0`, e por aí vai). Nesta seção, você irá aprender como listar as tags disponíveis, como criar novas tags, e quais são os tipos diferentes de tags. +Assim como a maioria dos VCS's, Git tem a habilidade de criar tags em pontos específicos na história do código como pontos importantes. Geralmente as pessoas usam esta funcionalidade para marcar pontos de release (`v1.0`, e por aí vai). Nesta seção, você aprenderá como listar as tags disponíveis, como criar novas tags, e quais são os tipos diferentes de tags. ### Listando Suas Tags ### @@ -950,7 +950,7 @@ Outro jeito para taggear commits é com a tag leve. Esta é basicamente a chave v1.4-lw v1.5 -Desta vez, se você executar `git show` na tag, você não verá nenhum informação extra. O comando apenas mostra o commit: +Desta vez, se você executar `git show` na tag, você não verá nenhuma informação extra. O comando apenas mostra o commit: $ git show v1.4-lw commit 15027957951b64cf874c3557a0f3547bd83b3ff6 @@ -1061,20 +1061,20 @@ Antes de terminarmos este capítulo em Git Essencial, algumas dicas e truques po ### Preenchimento Automático ### -Se você usa um Bash shell, Git vem com um script de preenchimento automático que você pode habilitar. Faça download do código fonte, e olhe no diretório `contrib/completion`; lá deve existir um arquivo chamado `git-completion.bash`. Copie este arquivo para o seu diretório home, e adicione a linha abaixo ao seu arquivo `.bashrc`: +Se você usa um shell Bash, você pode habilitar um script de preenchimento automático que vem com o Git. Faça download do código fonte, e olhe no diretório `contrib/completion`; lá deve existir um arquivo chamado `git-completion.bash`. Copie este arquivo para o seu diretório home, e adicione a linha abaixo ao seu arquivo `.bashrc`: source ~/.git-completion.bash -Se você quiser configurar Git para automaticamente ter preenchimento automático para todos os usuários, copie o script para o diretório `/opt/local/etc/bash_completion.d` em Mac ou para o diretório `/etc/bash_completion.d/` em Linux. Este é o diretório de scripts que o Bash irá automaticamente carregar para prover preenchimento automático. +Se você quiser configurar Git para automaticamente ter preenchimento automático para todos os usuários, copie o script para o diretório `/opt/local/etc/bash_completion.d` em Mac ou para o diretório `/etc/bash_completion.d/` em Linux. Este é o diretório de scripts que o Bash automaticamente carregará para prover o preenchimento automático. -Se você estiver usando Windows com Git Bash, que é o padrão quando instalando Git no Windows com msysGit, preenchimento automático deve estar pré-configurado. +Se você estiver usando Windows com Git Bash, que é o padrão quando instalando Git no Windows com msysGit, o preenchimento automático deve estar pré-configurado. Pressiona a tecla Tab quando estiver escrevendo um comando Git, e ele deve retornar uma lista de sugestões para você escolher: $ git co commit config -Neste caso, escrevendo `git co` e pressionando a tecla Tab duas vezes sugere commit e config. Addicionando `m` completa `git commit` automaticamente. +Neste caso, escrevendo `git co` e pressionando a tecla Tab duas vezes, ele sugere commit e config. Adicionando `m` completa `git commit` automaticamente. Isto também funciona com opções, o que é provavelmente mais útil. Por exemplo, se você estiver executando o comando `git log` e não consegue lembrar uma das opções, você pode começar a escrever e pressionar Tab para ver o que corresponde: @@ -1085,7 +1085,7 @@ Este é um truque bem bacana e irá te poupar tempo e leitura de documentação. ### Pseudônimos no Git ### -Git não interfere com seu comando se você digitar ele parcialmente. Se você não quiser digitar o texto todo de cada comando Git, você pode facilmente criar um pseudônimo para cada um usando `git config`. Abaixo alguns exemplos que você pode usar: +O Git não interfere em seu comando se você digitá-lo parcialmente. Se você não quiser digitar o texto todo de cada comando Git, você pode facilmente criar um pseudônimo para cada um usando `git config`. Abaixo alguns exemplos que você pode usar: $ git config --global alias.co checkout $ git config --global alias.br branch From 8d0d6b79abd0f22478e91a49b4b3f3f5a7302c89 Mon Sep 17 00:00:00 2001 From: Nilton Moura Date: Tue, 3 Dec 2013 09:58:42 -0200 Subject: [PATCH 056/862] [pt-br] Update 01-chapter4.markdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [pt-br] Concordance, punctuation, plural and another mistakes corrected. Concordância, pontuação, plural e outros erros corrigidos. --- pt-br/04-git-server/01-chapter4.markdown | 40 ++++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/pt-br/04-git-server/01-chapter4.markdown b/pt-br/04-git-server/01-chapter4.markdown index b2b30756d..505ed24ff 100644 --- a/pt-br/04-git-server/01-chapter4.markdown +++ b/pt-br/04-git-server/01-chapter4.markdown @@ -1,10 +1,10 @@ # Git no Servidor # -Neste ponto, você deve estar apto a fazer a maior parte das tarefas do dia a dia para as quais estará usando o Git. No entanto, para qualquer colaboração no Git, você precisará ter um repositório remoto do Git. Apesar de que você pode tecnicamente enviar (push) mudanças e receber (pull) mudanças de repositórios de indivíduos, isto é desencorajado pois você pode facilmente confundi-los no que eles estão trabalhando se não for cuidadoso. Além disso, você quer que seus colaboradores possam acessar o repositório mesmo quando seu computador estiver offline — ter um repositório comum mais confiável é muitas vezes útil. Portanto, o método preferido para colaborar com alguém é configurar um repositório intermediário que vocês dois podem acessar, enviar para (push to) e receber de (pull from). Nos iremos nos referir a este repositório como um "Servidor Git"; mas você perceberá que geralmente são necessários uma quantidade ínfima de recursos para hospedar um repositório Git, logo você raramente precisará de um servidor inteiro para ele. +Neste ponto, você deve estar apto a fazer a maior parte das tarefas do dia a dia para as quais estará usando o Git. No entanto, para qualquer colaboração no Git, você precisará ter um repositório remoto do Git. Apesar de você poder tecnicamente enviar (push) e receber (pull) mudanças de repositórios de indivíduos, isto é desencorajado pois você pode facilmente confundi-los no que eles estão trabalhando se não for cuidadoso. Além disso, você quer que seus colaboradores possam acessar o repositório mesmo quando seu computador estiver offline — ter um repositório comum mais confiável é útil muitas vezes. Portanto, o método preferido para colaborar com alguém é configurar um repositório intermediário que vocês dois podem acessar, enviar para (push to) e receber de (pull from). Nós iremos nos referir a este repositório como um "Servidor Git"; mas você perceberá que geralmente é necessária uma quantidade ínfima de recursos para hospedar um repositório Git, logo, você raramente precisará de um servidor inteiro para ele. Rodar um servidor Git é simples. Primeiro, você escolhe quais protocolos seu servidor usará para se comunicar. A primeira seção deste capítulo cobrirá os protocolos disponíveis e os prós e contras de cada um. As próximas seções explicararão algumas configurações típicas usando estes protocolos e como fazer o seu servidor rodar com eles. Por último, passaremos por algumas opções de hospedagem, se você não se importar em hospedar seu código no servidor dos outros e não quiser passar pelo incômodo de configurar e manter seu próprio servidor. -Se você não tiver interesse em rodar seu próprio servidor, você pode pular para a ultima seção do capítulo para ver algumas opções para configurar uma conta hospedada e então ir para o próximo capítulo, onde discutiremos os vários altos e baixos de trabalhar em um ambiente distribuído de controle de versão. +Se você não tiver interesse em rodar seu próprio servidor, você pode pular para a última seção do capítulo para ver algumas opções para configurar uma conta hospedada, e então ir para o próximo capítulo, onde discutiremos os vários altos e baixos de se trabalhar em um ambiente distribuído de controle de versão. Um repositório remoto é geralmente um _repositório vazio_ — um repositório Git que não tem um diretório de trabalho. Uma vez que o repositório é usado apenas como um ponto de colaboração, não há razão para ter cópias anteriores em disco; são apenas dados Git. Em termos simples, um repositório vazio é o conteúdo do diretório `.git` e nada mais. @@ -26,7 +26,7 @@ Ou você pode fazer isso: $ git clone file:///opt/git/project.git -O Git opera de forma ligeiramente diferente se você explicitar `file://` no começo da URL. Se você apenas especificar o caminho, o Git tenta usar hardlinks ou copiar diretamente os arquivos que necessita. Se você especificar `file://`, o Git aciona os processos que normalmente utiliza para transferir dados através da redes, o que é geralmente uma forma de transferência bem menos eficiente. A principal razão para especificar o prefixo `file://` é se você quer uma cópia limpa do repositório com referências e objetos estranhos deixados de lado — geralmente depois de importar de outro sistema de controle de versões ou algo similar (ver Capítulo 9 para tarefas de manutenção). Usaremos o caminho normal aqui pois isto é quase sempre mais rápido. +O Git opera de forma ligeiramente diferente se você explicitar `file://` no começo da URL. Se você apenas especificar o caminho, o Git tenta usar hardlinks ou copiar diretamente os arquivos que necessita. Se você especificar `file://`, o Git aciona os processos que normalmente utiliza para transferir dados através de uma rede, o que é geralmente uma forma de transferência bem menos eficiente. A principal razão para especificar o prefixo `file://` é se você quer uma cópia limpa do repositório com referências e objetos estranhos deixados de lado — geralmente depois de importar de outro sistema de controle de versões ou algo similar (ver Capítulo 9 para tarefas de manutenção). Usaremos o caminho normal aqui pois isto é quase sempre mais rápido. Para adicionar um repositório local para um projeto Git existente, você pode rodar algo assim: @@ -36,7 +36,7 @@ Então você pode enviar para e receber deste remoto como se você estivesse faz #### Os Prós #### -Os prós de repositórios baseados em arquivos é que eles são simples e usam permissões de arquivo e acessos de rede existentes. Se você já tem um sistema de arquivos compartilhados ao qual todo o seu time tem acesso, configurar um repositório é muito fácil. Você coloca o repositório vazio em algum lugar onde todos tem acesso compartilhado e configura as permissões de leitura/escrita como você faria para qualquer outro diretório compartilhado. Discutiremos como exportar uma cópia de repositório vazio com este objetivo na próxima seção, “Colocando Git em um Servidor.” +Os prós de repositórios baseados em arquivos são que eles são simples e usam permissões de arquivo e acessos de rede existentes. Se você já tem um sistema de arquivos compartilhados ao qual todo o seu time tem acesso, configurar um repositório é muito fácil. Você coloca o repositório vazio em algum lugar onde todos tem acesso compartilhado e configura as permissões de leitura/escrita como você faria para qualquer outro diretório compartilhado. Discutiremos como exportar uma cópia de repositório vazio com este objetivo na próxima seção, “Colocando Git em um Servidor.” Esta é também uma boa opção para rapidamente pegar trabalhos do diretório em que outra pessoa estiver trabalhando. Se você e seu colega estiverem trabalhando no mesmo projeto e ele quiser que você olhe alguma coisa, rodar um comando como `git pull /home/john/project` é frequentemente mais fácil do que ele enviar para um servidor remoto e você pegar de lá. @@ -58,11 +58,11 @@ Ou você pode deixar de especificar o protocolo — O Git assume SSH se você n $ git clone user@server:project.git -Você também pode deixar de especificar um usuário, e o Git assume o usuário que você esteja usando atualmente. +Você também pode deixar de especificar um usuário, e o Git assume o usuário que você estiver usando atualmente. #### Os Prós #### -Os prós de usar SSH são muitos. Primeiro, você basicamente tem que usá-lo se você quer acesso de escrita autenticado através de uma rede. Segundo, o SSH é relativamente simples de configurar — Serviços (Daemons) SSH são muito comuns, muitos administradores de rede tem experiência com eles, e muitas distribuições de SOs estão configuradas com eles ou tem ferramentas para gerenciá-los. Em seguida, o acesso através de SSH é seguro — toda transferência de dados é encriptada e autenticada. Por último, como os protocolos Git e Local, o SSH é eficiente, compactando os dados da melhor forma possível antes de transferi-los. +Os prós de usar SSH são muitos. Primeiro, você basicamente tem que usá-lo se você quer acesso de escrita autenticado através de uma rede. Segundo, o SSH é relativamente simples de configurar — Serviços (Daemons) SSH são muito comuns, muitos administradores de rede tem experiência com eles, e muitas distribuições de SOs estão configuradas com eles ou tem ferramentas para gerenciá-los. Em seguida, o acesso através de SSH é seguro — toda transferência de dados é criptografada e autenticada. Por último, como os protocolos Git e Local, o SSH é eficiente, compactando os dados da melhor forma possível antes de transferi-los. #### Os Contras ### @@ -74,7 +74,7 @@ O próximo é o protocolo Git. Este é um daemon especial que vem no mesmo pacot #### Os Prós #### -O protocolo Git é o mais rápido entre os disponíveis. Se você está servindo muito tráfego para um projeto público ou servindo um projeto muito grande que não requer autenticação para acesso de leitura, é provável que você vai querer configurar um daemon Git para servir o seu projeto. Ele usa o mesmo mecanismo de transmissão de dados que o protocolo SSH mas sem o tempo gasto na encriptação e autenticação. +O protocolo Git é o mais rápido entre os disponíveis. Se você está servindo muito tráfego para um projeto público ou servindo um projeto muito grande que não requer autenticação para acesso de leitura, é provável que você vai querer configurar um daemon Git para servir o seu projeto. Ele usa o mesmo mecanismo de transmissão de dados que o protocolo SSH, mas sem o tempo gasto na criptografia e autenticação. #### Os Contras ### @@ -96,13 +96,13 @@ E pronto. O gancho `post-update` que vem com o Git executa o comando apropriado Neste caso particular, estamos usando o caminho `/var/www/htdocs` que é comum para configurações Apache, mas você pode usar qualquer servidor web estático — apenas coloque o caminho do repositório. Os dados no Git são servidos como arquivos estáticos básicos (veja o *Capítulo 9* para mais detalhes sobre como exatamente eles são servidos). -É possível fazer o Git enviar via HTTP também, embora esta técnica não seja muito usada e requer que você configure WebDav com parâmetros complexos. Pelo fato de ser usado raramente, não iremos mostrar isto neste livro. Se você está interessado em usar os protocolos HTTP-push, você pode ler sobre preparação de um repositório para este propósito em `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt`. Uma coisa legal sobre fazer o Git enviar via HTTP é que você pode usar qualquer servidor WebDAV, sem quaisquer características Git; então, você pode usar esta funcionalidade se o seu provedor web suporta WebDAV com permissão de escrita para o seu web site. +É possível fazer o Git enviar via HTTP também, embora esta técnica não seja muito usada e requer que você configure WebDav com parâmetros complexos. Pelo fato de ser usado raramente, não mostraremos isto neste livro. Se você está interessado em usar os protocolos HTTP-push, você pode ler sobre preparação de um repositório para este propósito em `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt`. Uma coisa legal sobre fazer o Git enviar via HTTP é que você pode usar qualquer servidor WebDAV, sem quaisquer características Git; então, você pode usar esta funcionalidade se o seu provedor web suporta WebDAV com permissão de escrita para o seu web site. #### Os Prós #### -O lado bom de usar protocolo HTTP é que ele é fácil de configurar. Executar o punhado de comandos obrigatórios lhe provém um jeito simples de fornecer ao mundo acesso ao seu repositório Git. Você só precisa de alguns minutos. O protocolo HTTP também não consume muitos recursos no servidor. Pelo fato de usar apenas um servidor HTTP estático para todo o dado, um servidor Apache normal pode servir em média milhares de arquivos por segundo — é difícil sobrecarregar até mesmo um servidor pequeno. +O lado bom de usar protocolo HTTP é que ele é fácil de configurar. Executar o punhado de comandos obrigatórios lhe provê um jeito simples de fornecer ao mundo acesso ao seu repositório Git. Você só precisa de alguns minutos. O protocolo HTTP também não consome muitos recursos no servidor. Pelo fato de usar apenas um servidor HTTP estático para todo o dado, um servidor Apache normal pode servir em média milhares de arquivos por segundo — é difícil sobrecarregar até mesmo um servidor pequeno. -Você também pode servir seus repositórios com apenas acesso de leitura via HTTPS, o que significa que você pode encriptar o conteúdo transferido; ou pode ir até o ponto de fazer seus usuários usarem certificados SSL assinados. Geralmente, se você está indo até este ponto, é mais fácil usar as chaves públicas SSH; mas pode ser uma solução melhor em casos específicos usar certificados SSL assinados ou outro método de autenticação HTTP para acesso de leitura via HTTPS. +Você também pode servir seus repositórios com apenas acesso de leitura via HTTPS, o que significa que você pode criptografar o conteúdo transferido; ou pode ir até o ponto de fazer seus usuários usarem certificados SSL assinados. Geralmente, se você está indo até este ponto, é mais fácil usar as chaves públicas SSH; mas pode ser uma solução melhor em casos específicos usar certificados SSL assinados ou outro método de autenticação HTTP para acesso de leitura via HTTPS. Outra coisa legal é que HTTP é um protocolo tão comumente usado que firewalls corporativos são normalmente configurados para permitir tráfego por esta porta. @@ -127,7 +127,7 @@ Existem algumas diferenças menores no arquivo de configuração caso você siga ### Colocando o Repositório Limpo no Servidor ### -Agora que você tem uma cópia limpa do seu repositório, tudo o que você precisa fazer é colocar ele num servidor e configurar os protocolos. Vamos dizer que você configurou um servidor chamado `git.example.com` que você tem acesso via SSH, e você quer armazenar todos os seus repositórios Git no diretório `/opt/git`. Você pode configurar o seu novo repositório apenas copiando o seu repositório limpo: +Agora que você tem uma cópia limpa do seu repositório, tudo o que você precisa fazer é colocá-lo num servidor e configurar os protocolos. Vamos dizer que você configurou um servidor chamado `git.example.com` que você tem acesso via SSH, e você quer armazenar todos os seus repositórios Git no diretório `/opt/git`. Você pode configurar o seu novo repositório apenas copiando o seu repositório limpo: $ scp -r my_project.git user@git.example.com:/opt/git @@ -135,7 +135,7 @@ Neste ponto, outros usuários com acesso SSH para o mesmo servidor e que possuam $ git clone user@git.example.com:/opt/git/my_project.git -Se um usuário acessar um servidor via SSH e tem acesso de escrita no diretório `/opt/git/my_project.git`, ele também terá acesso para envio (push) automaticamente. Git irá automaticamente adicionar permissões de escrita apropriadas para o grupo se o comando `git init` com a opção `--shared` for executada em um repositório. +Se um usuário acessar um servidor via SSH e ele tiver acesso de escrita no diretório `/opt/git/my_project.git`, ele também terá acesso para envio (push) automaticamente. Git irá automaticamente adicionar permissões de escrita apropriadas para o grupo se o comando `git init` com a opção `--shared` for executada em um repositório. $ ssh user@git.example.com $ cd /opt/git/my_project.git @@ -161,7 +161,7 @@ Existem algumas alternativas para dar acesso a todos no seu time. A primeira é Um segundo método é criar um único usuário 'git' na máquina, pedir a cada usuário que deve possuir acesso de escrita para enviar a você uma chave pública SSH, e adicionar estas chaves no arquivo `~/.ssh/authorized_keys` do seu novo usuário 'git'. Depois disto, todos poderão acessar aquela máquina usando o usuário 'git'. Isto não afeta os dados de commit de maneira alguma — o usuário SSH que você usa para se conectar não afeta os commits que você gravou previamente. -Outro método é fazer o seu servidor SSH se autenticar a partir de um servidor LDAP ou outro autenticador central que você talvez já tenha previamente configurado. Contanto que cada usuário tenha acesso shell à máquina, qualquer mecanismo de autenticação SSH que você deve funcionar. +Outro método é fazer o seu servidor SSH se autenticar a partir de um servidor LDAP ou outro autenticador central que você talvez já tenha previamente configurado. Contanto que cada usuário tenha acesso shell à máquina, qualquer mecanismo de autenticação SSH que você imaginar deve funcionar. ## Gerando Sua Chave Pública SSH ## @@ -196,7 +196,7 @@ Agora, cada usuário que executar o comando acima precisa enviar a chave públic mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx NrRFi9wrf+M7Q== schacon@agadorlaptop.local -Para um tutorial mais detalhado sobre criar chaves SSH em vários sistemas operacionais, veja o guia do GitHub sobre chaves SSH no endereço `http://github.com/guides/providing-your-ssh-key`. +Para um tutorial mais detalhado sobre criação de chaves SSH em vários sistemas operacionais, veja o guia do GitHub sobre chaves SSH no endereço `http://github.com/guides/providing-your-ssh-key`. ## Configurando o Servidor ## @@ -507,7 +507,7 @@ Nota: a última cópia desta seção do livro ProGit está sempre disponível na [gldpg]: http://sitaramc.github.com/gitolite/progit.html -Git começou a se tornar muito popular em ambientes corporativos, que tendem a ter alguns requisitos adicionais em termos de controle de acesso. Gitolite foi originalmente criado para ajudar com esses requisitos, mas verifica-se que é igualmente útil no mundo do código aberto: o Projeto Fedora controla o acesso aos seus repositórios de gerenciamento de pacotes (mais de 10.000 deles!) Usando gitolite, e isso é provavelmente a maior instalação do gitolite que existe. +Git começou a se tornar muito popular em ambientes corporativos, que tendem a ter alguns requisitos adicionais em termos de controle de acesso. Gitolite foi originalmente criado para ajudar com esses requisitos, mas verifica-se que é igualmente útil no mundo do código aberto: o Projeto Fedora controla o acesso aos seus repositórios de gerenciamento de pacotes (mais de 10.000 deles!) usando gitolite, e essa é provavelmente a maior instalação do gitolite que existe. Gitolite permite que você especifique as permissões não apenas por repositório (como o Gitosis faz), mas também por branch ou nomes de tag dentro de cada repositório. Ou seja, você pode especificar que certas pessoas (ou grupos de pessoas) só podem fazer um push em certas "refs" (branchs ou tags), mas não em outros. @@ -523,7 +523,7 @@ Pessoas sem acesso root podem instalá-lo dentro de suas próprias userids. E, f Vamos descrever este último método neste artigo; para os outros métodos, por favor consulte a documentação. -Você começa pela obtenção de acesso baseado em chave pública para o servidor, de modo que você pode entrar a partir de sua estação de trabalho no servidor sem receber uma solicitação de senha. O método a seguir funciona em Linux; para outros sistemas operacionais, você pode ter que fazer isso manualmente. Nós assumimos que você já tinha um par de chaves gerada usando o `ssh-keygen`. +Você começa pela obtenção de acesso baseado em chave pública para o servidor, de modo que você pode entrar a partir de sua estação de trabalho no servidor sem receber uma solicitação de senha. O método a seguir funciona em Linux; para outros sistemas operacionais, você pode ter que fazer isso manualmente. Nós assumimos que você já tinha um par de chaves gerado usando o `ssh-keygen`. $ ssh-copy-id -i ~/.ssh/id_rsa gitolite@gitserver @@ -554,7 +554,7 @@ Para clonar esses mesmos repositórios de qualquer outra conta: ### Customizando a Instalação ### -Enquanto que o padrão, "quick install" (instalação rápida) funciona para a maioria das pessoas, existem algumas maneiras de personalizar a instalação se você precisar. se você omitir o argumento `-q`, você entra em modo de instalação "verbose" -- mostra informações detalhadas sobre o que a instalação está fazendo em cada etapa. O modo verbose também permite que você altere alguns parâmetros do lado servidor, tais como a localização dos repositórios, através da edição de um arquivo "rc" que o servidor utiliza. Este arquivo "rc" é comentado, assim você deve ser capaz de fazer qualquer alteração que você precisar com bastante facilidade, salvá-lo, e continuar. Este arquivo também contém várias configurações que você pode mudar para ativar ou desativar alguns dos recursos avançados do gitolite. +Enquanto que o padrão, "quick install" (instalação rápida) funciona para a maioria das pessoas, existem algumas maneiras de personalizar a instalação se você precisar. Se você omitir o argumento `-q`, você entra em modo de instalação "verbose" -- mostra informações detalhadas sobre o que a instalação está fazendo em cada etapa. O modo verbose também permite que você altere alguns parâmetros do lado servidor, tais como a localização dos repositórios, através da edição de um arquivo "rc" que o servidor utiliza. Este arquivo "rc" é comentado, assim você deve ser capaz de fazer qualquer alteração que você precisar com bastante facilidade, salvá-lo, e continuar. Este arquivo também contém várias configurações que você pode mudar para ativar ou desativar alguns dos recursos avançados do gitolite. ### Arquivo de Configuração e Regras de Controle de Acesso ### @@ -625,7 +625,7 @@ Digamos que, na situação acima, queremos que os engenheiros sejam capazes de r - master integ = @engineers RW+ = @engineers -Mais uma vez, você simplesmente segue as regras do topo para baixo até atingir uma correspondência para o seu modo de acesso, ou uma negação. Um push sem retrocessos (rewind) no master ou integ é permitido pela primeira regra. Um "rewind push" a essas refs não coincide com a primeira regra, cai na segunda, e é, portanto, negada. Qualquer push (rewing ou não) para refs que não sejam integ ou master não coincidirão com as duas primeiras regras de qualquer maneira, e a terceira regra permite isso. +Mais uma vez, você simplesmente segue as regras do topo para baixo até atingir uma correspondência para o seu modo de acesso, ou uma negação. Um push sem retrocessos (rewind) no master ou integ é permitido pela primeira regra. Um "rewind push" a essas refs não coincide com a primeira regra, cai na segunda, e é, portanto, negada. Qualquer push (rewind ou não) para refs que não sejam integ ou master não coincidirão com as duas primeiras regras de qualquer maneira, e a terceira regra permite isso. Se isso soar complicado, você pode querer brincar com ele para aumentar a sua compreensão. Além disso, na maioria das vezes você não precisa "negar" regras de qualquer maneira, então você pode optar por apenas evitá-las, se preferir. @@ -664,7 +664,7 @@ Vamos terminar essa discussão com exemplos de outros recursos, os quais são de **Git fora do PATH normal**: Um recurso extremamente conveniente no gitolite é suportar instalações do git fora do `$PATH` normal (isso é mais comum do que você pensa; alguns ambientes corporativos ou mesmo alguns provedores de hospedagem se recusam a instalar coisas em todo o sistema e você acaba colocando-os em seus próprios diretórios). Normalmente, você é forçado a fazer com que o git do *lado cliente* fique ciente de que os binários git estão neste local não-padrão de alguma forma. Com gitolite, basta escolher uma instalação detalhada (verbose) e definir `$GIT_PATH` nos arquivos "RC". Não serão necessárias alterações do lado cliente depois disso. -**Reportar direitos de Accesso**: Outro recurso conveniente é o que acontece quando você apenas acessa o servido via ssh. Gitolite mostra que repositórios você tem acesso, e quais permissões de acesso você tem. Aqui está um exemplo: +**Reportar direitos de Accesso**: Outro recurso conveniente é o que acontece quando você apenas acessa o servidor via ssh. Gitolite mostra que repositórios você tem acesso, e quais permissões de acesso você tem. Aqui está um exemplo: hello sitaram, the gitolite version here is v1.5.4-19-ga3397d4 the gitolite config gives you the following access: @@ -717,7 +717,7 @@ Quando você reiniciar sua máquina, seu serviço Git será iniciado automaticam Em outro Sistema Operacional, talvez você queira usar o `xinetd`, um script em seu sistema `sysvinit`, ou qualquer outra solução — contanto que você tenha o serviço Git rodando e monitorado de alguma forma. -A seguir, você tem que configurar seu servidor Gitosis para permitir o acesso não autenticado aos repositórios Git. Se você adicionar uma seção para cada repositório, você pode especificar quais você quer que seu serviço Git tenha permissão de leitura. Se quiser permitir o acesso para o seu projeto para iphone usando o protocolo Git, acrescente no final do arquivo `gitosis.conf`: +A seguir, você tem que configurar seu servidor Gitosis para permitir o acesso não autenticado aos repositórios Git. Se você adicionar uma seção para cada repositório, você pode especificar quais você quer que seu serviço Git tenha permissão de leitura. Se quiser permitir o acesso para o seu projeto iphone usando o protocolo Git, acrescente no final do arquivo `gitosis.conf`: [repo iphone_project] daemon = yes From 927acdea7fa29bb218c4a195eacc61a805a9d91d Mon Sep 17 00:00:00 2001 From: Paulo Degering Rosa Junior Date: Wed, 4 Dec 2013 14:57:18 -0200 Subject: [PATCH 057/862] Update 01-chapter3.markdown General translation fixes --- pt-br/03-git-branching/01-chapter3.markdown | 40 ++++++++++----------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/pt-br/03-git-branching/01-chapter3.markdown b/pt-br/03-git-branching/01-chapter3.markdown index ee35c017d..6cd640efa 100644 --- a/pt-br/03-git-branching/01-chapter3.markdown +++ b/pt-br/03-git-branching/01-chapter3.markdown @@ -88,7 +88,7 @@ Figura 3-9. O histórico dos branches diverge. Como um branch em Git é na verdade um arquivo simples que contém os 40 caracteres do checksum SHA-1 do commit para o qual ele aponta, os branches são baratos para criar e destruir. Criar um novo branch é tão rápido e simples como escrever 41 bytes em um arquivo (40 caracteres e uma quebra de linha). -Isto está em nítido contraste com a forma coma a qual a maioria das ferramentas VCS gerenciam branches, que envolve a cópia de todos os arquivos do projeto para um segundo diretório. Isso pode demorar vários segundos ou até minutos, dependendo do tamanho do projeto, enquanto que no Git o processo é sempre instantâneo. Também, porque nós estamos gravando os pais dos objetos quando fazemos commits, encontrar uma boa base para fazer o merge é uma tarefa feita automaticamente para nós e geralmente é muito fácil de fazer. Esses recursos ajudam a estimular os desenvolvedores a criar e utilizar branches com frequência. +Isto está em nítido contraste com a forma com a qual a maioria das ferramentas VCS gerenciam branches, que envolve a cópia de todos os arquivos do projeto para um segundo diretório. Isso pode demorar vários segundos ou até minutos, dependendo do tamanho do projeto, enquanto que no Git o processo é sempre instantâneo. Também, porque nós estamos gravando os pais dos objetos quando fazemos commits, encontrar uma boa base para fazer o merge é uma tarefa feita automaticamente para nós e geralmente é muito fácil de fazer. Esses recursos ajudam a estimular os desenvolvedores a criar e utilizar branches com frequência. Vamos ver por que você deve fazê-lo. @@ -97,7 +97,7 @@ Vamos ver por que você deve fazê-lo. Vamos ver um exemplo simples de uso de branch e merge com um fluxo de trabalho que você pode usar no mundo real. Você seguirá esses passos: 1. Trabalhar em um web site. -2. Criar um branch para uma matéria em que está trabalhando. +2. Criar um branch para uma nova funcionalidade em que está trabalhando. 3. Trabalhar nesse branch. Nesse etapa, você receberá um telefonema informando que outro problema crítico existe e precisa de correção. Você fará o seguinte: @@ -105,7 +105,7 @@ Nesse etapa, você receberá um telefonema informando que outro problema crític 1. Voltar ao seu branch de produção. 2. Criar um branch para adicionar a correção. 3. Depois de testado, fazer o merge do branch da correção, e enviar para produção. -4. Retornar a sua matéria original e continuar trabalhando. +4. Retornar à sua funcionalidade anterior e continuar trabalhando. ### Branch Básico ### @@ -114,7 +114,7 @@ Primeiro, digamos que você esteja trabalhando no seu projeto e já tem alguns c Insert 18333fig0310.png Figura 3-10. Um histórico de commits pequeno e simples. -Você decidiu que irá trabalhar na tarefa (issue) #53 do gerenciador de bugs ou tarefas que sua empresa usa. Para deixar claro, Git não é amarrado a nenhum gerenciador de tarefas em particular; mas já que a tarefa #53 ter um foco diferente, você criará um branch novo para trabalhar nele. Para criar um branch e mudar para ele ao mesmo tempo, você pode executar o comando `git checkout` com a opção `-b`: +Você decidiu que irá trabalhar na tarefa (issue) #53 do gerenciador de bugs ou tarefas que sua empresa usa. Para deixar claro, Git não é amarrado a nenhum gerenciador de tarefas em particular; mas já que a tarefa #53 tem um foco diferente, você criará um branch novo para trabalhar nele. Para criar um branch e mudar para ele ao mesmo tempo, você pode executar o comando `git checkout` com a opção `-b`: $ git checkout -b iss53 Switched to a new branch "iss53" @@ -137,7 +137,7 @@ Você trabalha no seu web site e faz alguns commits. Ao fazer isso o branch `iss Insert 18333fig0312.png Figura 3-12. O branch iss53 avançou com suas modificações. -Nesse momento você recebe uma ligação dizendo que existe um problema com o web site, e você deve resolvê-lo imediatamente. Com Git, você não precisa fazer o deploy de sua correção junto com as modificações que você fez no `iss53`, e você não precisa se esforçar muito para reverter essas modificações antes que você possa aplicar sua correção em produção. Tudo que você tem a fazer é voltar ao seu branch master. +Nesse momento você recebe uma ligação dizendo que existe um problema com o web site e você deve resolvê-lo imediatamente. Com Git, você não precisa fazer o deploy de sua correção junto com as modificações que você fez no `iss53`, e você não precisa se esforçar muito para reverter essas modificações antes que você possa aplicar sua correção em produção. Tudo que você tem a fazer é voltar ao seu branch master. No entanto, antes de fazer isso, note que seu diretório de trabalho ou área de seleção tem modificações que não entraram em commits e que estão gerando conflitos com o branch que você está fazendo o checkout, Git não deixará você mudar de branch. É melhor ter uma área de trabalho limpa quando mudar de branch. Existem maneiras de contornar esta situação (isto é, incluir e fazer o commit) que vamos falar depois. Por enquanto, você fez o commit de todas as suas modificações, então você pode mudar para o seu branch master: @@ -267,7 +267,7 @@ Esta solução tem um pouco de cada seção, e eu removi completamente as linhas {remote}: modified Hit return to start merge resolution tool (opendiff): -Se você quer usar uma ferramenta de merge diferente da padrão (Git escolheu `opendiff` para mim neste caso porque eu rodei o comando em um Mac), você pode ver todas as ferramentas disponíveis listadas no topo depois de “merge tool candidates”. Digite o nome da ferramenta que você prefere usar. No *capítulo 7*, discutiremos como você pode alterar esse valor para o seu ambiente. +Se você quer usar uma ferramenta de merge diferente da padrão (Git escolheu `opendiff` para mim, neste caso, porque eu rodei o comando em um Mac), você pode ver todas as ferramentas disponíveis listadas no topo depois de “merge tool candidates”. Digite o nome da ferramenta que você prefere usar. No *capítulo 7*, discutiremos como você pode alterar esse valor para o seu ambiente. Depois de sair da ferramenta de merge, Git pergunta se o merge foi concluído com sucesso. Se você disser ao script que foi, ele coloca o arquivo na área de seleção para marcá-lo como resolvido pra você. @@ -341,7 +341,7 @@ Agora que você sabe o básico sobre criação e merge de branches, o que você ### Branches de Longa Duração ### -Por o Git usar um merge de três vias, fazer o merge de um branch em outro várias vezes em um período longo é geralmente fácil de fazer. Isto significa que você pode ter vários branches que ficam sempre abertos e que são usados em diferentes estágios do seu ciclo de desenvolvimento; você pode regularmente fazer o merge de alguns deles em outros. +Devido ao Git usar um merge de três vias, fazer o merge de um branch em outro várias vezes em um período longo é geralmente fácil de fazer. Isto significa que você pode ter vários branches que ficam sempre abertos e que são usados em diferentes estágios do seu ciclo de desenvolvimento; você pode regularmente fazer o merge de alguns deles em outros. Muitos desenvolvedores Git tem um fluxo de trabalho que adotam essa abordagem, como ter somente código completamente estável em seus branches `master` — possivelmente somente código que já foi ou será liberado. Eles têm outro branch paralelo chamado develop ou algo parecido em que eles trabalham ou usam para testar estabilidade — ele não é necessariamente sempre estável, mas quando ele chega a tal estágio, pode ser feito o merge com o branch `master`. Ele é usado para puxar (pull) branches tópicos (topic, branches de curta duração, como o seu branch `iss53` anteriormente) quando eles estão prontos, para ter certeza que eles passam em todos os testes e não acrescentam erros. @@ -361,7 +361,7 @@ Você pode continuar fazendo isso em vários níveis de estabilidade. Alguns pro Branches tópicos, entretanto, são úteis em projetos de qualquer tamanho. Um branch tópico é um branch de curta duração que você cria e usa para uma funcionalidade ou trabalho relacionado. Isso é algo que você provavelmente nunca fez com um controle de versão antes porque é geralmente muito custoso criar e fazer merge de branches. Mas no Git é comum criar, trabalhar, mesclar e apagar branches muitas vezes ao dia. -Você viu isso na seção anterior com os branches `iss53` e `hotfix` que você criou. Você fez commits neles e os apagou depois que fez o merge com seu branch principal. Tecnicamente isso lhe permite mudar completamente e rapidamente o contexto — por seu trabalho estar separado em contêineres onde todas as modificações naquele branch estarem relacionadas ao tópico, é fácil ver o que aconteceu durante a revisão de código. Você pode manter as mudanças la por minutos, dias, ou meses, e mesclá-las quando estivem prontas, não importando a ordem que foram criadas ou trabalhadas. +Você viu isso na seção anterior com os branches `iss53` e `hotfix` que você criou. Você fez commits neles e os apagou depois que fez o merge com seu branch principal. Tecnicamente, isso lhe permite mudar completamente e rapidamente o contexto — em razão de seu trabalho estar separado em contêineres onde todas as modificações naquele branch estarem relacionadas ao tópico, é fácil ver o que aconteceu durante a revisão de código. Você pode manter as mudanças lá por minutos, dias, ou meses, e mesclá-las quando estivem prontas, não importando a ordem que foram criadas ou trabalhadas. Considere um exemplo onde você está fazendo um trabalho (no `master`), cria um branch para um erro (`iss91`), trabalha nele um pouco, cria um segundo branch para testar uma nova maneira de resolver o mesmo problema (`iss91v2`), volta ao seu branch principal e trabalha nele por um tempo, e cria um novo branch para trabalhar em algo que você não tem certeza se é uma boa ideia (`dumbidea`). Seu histórico de commits irá se parecer com a Figura 3-20. @@ -379,7 +379,7 @@ Figura 3-21. Seu histórico depois de fazer o merge de dumbidea e iss91v2. Branches remotos são referências ao estado de seus branches no seu repositório remoto. São branches locais que você não pode mover, eles se movem automaticamente sempre que você faz alguma comunicação via rede. Branches remotos agem como marcadores para lembrá-lo onde estavam seus branches no seu repositório remoto na última vez que você se conectou a eles. -Eles seguem o padrão `(remoto)/(branch)`. Por exemplo, se você quer ver como o branch `master` estava no seu repositório remoto `origin` na última vez que você se comunicou com ele, você deve ver o branch `origin/master`. Se você estivesse trabalhando em um problema com um colega e eles colocassem o branch `iss53` no repositório, você poderia ter seu próprio branch `iss53`; mas o branch no servidor iria fazer referência ao commit em `origin/iss53`. +Eles seguem o padrão `(remote)/(branch)`. Por exemplo, se você quer ver como o branch `master` estava no seu repositório remoto `origin` na última vez que você se comunicou com ele, você deve ver o branch `origin/master`. Se você estivesse trabalhando em um problema com um colega e eles colocassem o branch `iss53` no repositório, você poderia ter seu próprio branch `iss53`; mas o branch no servidor iria fazer referência ao commit em `origin/iss53`. Isso pode parecer um pouco confuso, então vamos ver um exemplo. Digamos que você tem um servidor Git na sua rede em `git.ourcompany.com`. Se você cloná-lo, Git automaticamente dá o nome `origin` para ele, baixa todo o seu conteúdo, cria uma referência para onde o branch `master` dele está, e dá o nome `origin/master` para ele localmente; e você não pode movê-lo. O Git também dá seu próprio branch `master` como ponto de partida no mesmo local onde o branch `master` remoto está, a partir de onde você pode trabalhar (veja Figura 3-22). @@ -391,7 +391,7 @@ Se você estiver trabalhando no seu branch master local, e, ao mesmo tempo, algu Insert 18333fig0323.png Figura 3-23. Ao trabalhar local e alguém enviar coisas para seu servidor remoto faz cada histórico avançar de forma diferente. -Para sincronizar suas coisas, você executa o comando `git fetch origin`. Esse comando verifica qual servidor "origin" representa (nesse caso, é `git.ourcompany.com`), obtém todos os dados que você ainda não tem, e atualiza o seu banco de dados local, movendo o seu `origin/master` para a posição mais recente e atualizada (veja Figura 3-24). +Para sincronizar suas coisas, você executa o comando `git fetch origin`. Esse comando verifica qual servidor "origin" representa (nesse caso, é `git.ourcompany.com`), obtém todos os dados que você ainda não tem e atualiza o seu banco de dados local, movendo o seu `origin/master` para a posição mais recente e atualizada (veja Figura 3-24). Insert 18333fig0324.png Figura 3-24. O comando git fetch atualiza suas referências remotas. @@ -422,7 +422,7 @@ Se você tem um branch chamado `serverfix` e quer trabalhar com outros, você po Isso é um atalho. O Git automaticamente expande o branch `serverfix` para `refs/heads/serverfix:refs/heads/serverfix`, que quer dizer, "pegue meu branch local serverfix e envie para atualizar o branch serverfix no servidor remoto". Nós vamos ver a parte de `refs/heads/` em detalhes no capítulo 9, mas em geral você pode deixar assim. Você pode executar também `git push origin serverfix:serverfix`, que faz a mesma coisa — é como, "pegue meu serverfix e o transforme no serverfix remoto". Você pode usar esse formato para enviar (push) um branch local para o branch remoto que tem nome diferente. Se você não quer chamá-lo de serverfix no remoto, você pode executar `git push origin serverfix:awesomebranch` para enviar seu branch local `serverfix` para o branch `awesomebranch` no projeto remoto. -Na próxima vez que um dos seus colaboradores obter dados do servidor, eles irão ter uma referência para onde a versão do servidor de serverfix está no branch remoto `origin/serverfix`: +Na próxima vez que um dos seus colaboradores obtiver dados do servidor, ele terá uma referência para onde a versão do servidor de serverfix está no branch remoto `origin/serverfix`: $ git fetch origin remote: Counting objects: 20, done. @@ -440,11 +440,11 @@ Para fazer o merge desses dados no branch que você está trabalhando, você pod Branch serverfix set up to track remote branch refs/remotes/origin/serverfix. Switched to a new branch "serverfix" -Isso da a você um branch local para trabalhar que começa onde `origin/serverfix` está. +Isso dá a você um branch local para trabalhar que começa onde `origin/serverfix` está. -### Branches Seguidores (Tracking branches) ### +### Branches Rastreados (Tracking branches) ### -Baixar um branch local a partir de um branch remoto cria automaticamente o chamado _tracking branch_ (branches seguidores). Tracking branches são branches locais que tem uma relação direta com um branch remoto. Se você está em um tracking branch e digita `git push`, Git automaticamente sabe para que servidor e branch deve fazer o envio (push). Além disso, ao executar o comando `git pull` em um desses branches, é obtido todos os dados remotos e é automaticamente feito o merge do branch remoto correspondente. +Baixar um branch local a partir de um branch remoto cria automaticamente o chamado _tracking branch_ (branches rastreados). Tracking branches são branches locais que tem uma relação direta com um branch remoto. Se você está em um tracking branch e digita `git push`, Git automaticamente sabe para que servidor e branch deve fazer o envio (push). Além disso, ao executar o comando `git pull` em um desses branches, é obtido todos os dados remotos e é automaticamente feito o merge do branch remoto correspondente. Quando você faz o clone de um repositório, é automaticamente criado um branch `master` que segue `origin/master`. Esse é o motivo pelo qual `git push` e `git pull` funcionam sem argumentos. Entretanto, você pode criar outros tracking branches se quiser — outros que não seguem branches em `origin` e não seguem o branch `master`. Um caso simples é o exemplo que você acabou de ver, executando o comando `git checkout -b [branch] [nomeremoto]/[branch]`. Se você tem a versão do Git 1.6.2 ou mais recente, você pode usar também o atalho `--track`: @@ -495,7 +495,7 @@ Nesse exemplo, se você executar o seguinte: First, rewinding head to replay your work on top of it... Applying: added staged command -Ele vai ao ancestral comum dos dois branches (no que você está e no qual será feito o rebase), pega a diferença (diff) de cada commit do branch que você está, salva elas em um arquivo temporário, restaura o brach atual para o mesmo commit do branch que está sendo feito o rebase, e finalmente aplica uma mudança de cada vez. A Figura 3-29 ilustra esse processo. +Ele vai ao ancestral comum dos dois branches (no que você está e no qual será feito o rebase), pega a diferença (diff) de cada commit do branch que você está, salva elas em um arquivo temporário, restaura o brach atual para o mesmo commit do branch que está sendo feito o rebase e, finalmente, aplica uma mudança de cada vez. A Figura 3-29 ilustra esse processo. Insert 18333fig0329.png Figura 3-29. Fazendo o rebase em C4 de mudanças feitas em C3. @@ -563,26 +563,26 @@ Ahh, mas apesar dos benefícios do rebase existem os inconvenientes, que podem s **Não faça rebase de commits que você enviou para um repositório público.** -Se você seguir essa regra você ficará bem. Se não seguir, as pessoas odiarão você, e você será desprezado por amigos e familiares. +Se você seguir essa regra você ficará bem. Se não seguir, as pessoas te odiarão e você será desprezado por amigos e familiares. -Quando você faz o rebase, você está abandonando commits existentes e criando novos que são similares mas diferentes. Se fizer o push de commits em algum lugar e outros pegarem e fazerem trabalhos baseado neles, e você reescreve esses commits com `git rebase` e faz o push novamente, seus colaborares terão que fazer o merge novamente do trabalho deles e as coisas ficarão bagunçadas quando você tentar trazer o trabalho deles de volta para o seu. +Quando você faz o rebase, você está abandonando commits existentes e criando novos que são similares, mas diferentes. Se fizer o push de commits em algum lugar e outros pegarem e fizerem trabalhos baseado neles e você reescrever esses commits com `git rebase` e fizer o push novamente, seus colaboradores terão que fazer o merge de seus trabalhos novamente e as coisas ficarão bagunçadas quando você tentar trazer o trabalho deles de volta para o seu. Vamos ver um exemplo de como o rebase funciona e dos problemas que podem ser causados quando você torna algo público. Digamos que você faça o clone de um servidor central e faça algum trabalho em cima dele. Seu histórico de commits parece com a Figura 3-36. Insert 18333fig0336.png Figura 3-36. Clone de um repositório e trabalho a partir dele. -Agora, outra pessoa faz modificações que inclui um merge, e envia (push) esse trabalho para o servidor central. Você o obtêm e faz o merge do novo branch remoto no seu trabalho, fazendo com que seu histórico fique como na Figura 3-37. +Agora, outra pessoa faz modificações que inclui um merge e envia (push) esse trabalho para o servidor central. Você o obtêm e faz o merge do novo branch remoto no seu trabalho, fazendo com que seu histórico fique como na Figura 3-37. Insert 18333fig0337.png Figura 3-37. Obtêm mais commits e faz o merge deles no seu trabalho. -Em seguida, a pessoa que envio o merge voltou atrás e fez o rebase do seu trabalho; eles executam `git push --force` para sobrescrever o histórico no servidor. Você então obtém os dados do servidor, trazendo os novos commits. +Em seguida, a pessoa que enviou o merge voltou atrás e fez o rebase do seu trabalho; eles executam `git push --force` para sobrescrever o histórico no servidor. Você então obtêm os dados do servidor, trazendo os novos commits. Insert 18333fig0338.png Figura 3-38. Alguém envia commits com rebase, abandonando os commits que você usou como base para o seu trabalho. -Nesse ponto, você tem que fazer o merge dessas modificações novamente, mesmo que você já o tenha feito. Fazer o rebase muda o código hash SHA-1 desses commits então para o Git eles são commits novos, porém você já tem as modificações de C4 no seu histórico (veja Figura 3-39). +Nesse ponto, você tem que fazer o merge dessas modificações novamente, mesmo que você já o tenha feito. Fazer o rebase muda o código hash SHA-1 desses commits, então para o Git eles são commits novos, embora você já tenha as modificações de C4 no seu histórico (veja Figura 3-39). Insert 18333fig0339.png Figura 3-39. Você faz o merge novamente das mesmas coisas em um novo commit. From 6b2189296712d2192ba3dda0da1a798ff53b9d2d Mon Sep 17 00:00:00 2001 From: Paulo Degering Rosa Junior Date: Wed, 4 Dec 2013 15:30:41 -0200 Subject: [PATCH 058/862] Update 01-chapter3.markdown General fixes --- pt-br/03-git-branching/01-chapter3.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pt-br/03-git-branching/01-chapter3.markdown b/pt-br/03-git-branching/01-chapter3.markdown index 6cd640efa..1b41b516a 100644 --- a/pt-br/03-git-branching/01-chapter3.markdown +++ b/pt-br/03-git-branching/01-chapter3.markdown @@ -97,7 +97,7 @@ Vamos ver por que você deve fazê-lo. Vamos ver um exemplo simples de uso de branch e merge com um fluxo de trabalho que você pode usar no mundo real. Você seguirá esses passos: 1. Trabalhar em um web site. -2. Criar um branch para uma nova funcionalidade em que está trabalhando. +2. Criar um branch para uma nova história em que está trabalhando. 3. Trabalhar nesse branch. Nesse etapa, você receberá um telefonema informando que outro problema crítico existe e precisa de correção. Você fará o seguinte: @@ -105,7 +105,7 @@ Nesse etapa, você receberá um telefonema informando que outro problema crític 1. Voltar ao seu branch de produção. 2. Criar um branch para adicionar a correção. 3. Depois de testado, fazer o merge do branch da correção, e enviar para produção. -4. Retornar à sua funcionalidade anterior e continuar trabalhando. +4. Retornar à sua história anterior e continuar trabalhando. ### Branch Básico ### From 539129436e2872336626568f27636d259d840d5f Mon Sep 17 00:00:00 2001 From: harupong Date: Fri, 6 Dec 2013 16:12:54 +0900 Subject: [PATCH 059/862] Remove unnecessary comments --- latex/config.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/latex/config.yml b/latex/config.yml index 4d05cf875..e3c8196da 100644 --- a/latex/config.yml +++ b/latex/config.yml @@ -43,12 +43,8 @@ zh-tw: indent: "文" ja: langrule: "\\XeTeXlinebreakskip=0em plus 0.1em minus 0.01em\n\\XeTeXlinebreakpenalty=0" -# font: Japan -# font: Sazanami Mincho font: IPAPMincho bold: VL PGothic -# bold: Sazanami Gothic -# bold: IPAPGothic mono: VL Gothic prechap: "第" postchap: "章" From 4958780fd9b978581ce24153e52e7bfc1b308b20 Mon Sep 17 00:00:00 2001 From: harupong Date: Fri, 6 Dec 2013 16:27:20 +0900 Subject: [PATCH 060/862] Switch font for pdf to IPAexMincho --- latex/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/latex/config.yml b/latex/config.yml index e3c8196da..4271597c8 100644 --- a/latex/config.yml +++ b/latex/config.yml @@ -43,7 +43,7 @@ zh-tw: indent: "文" ja: langrule: "\\XeTeXlinebreakskip=0em plus 0.1em minus 0.01em\n\\XeTeXlinebreakpenalty=0" - font: IPAPMincho + font: IPAexMincho bold: VL PGothic mono: VL Gothic prechap: "第" From ec74eb186bf772bfa19e70afc3f2d48e2a41ee65 Mon Sep 17 00:00:00 2001 From: Radek Simko Date: Thu, 5 Dec 2013 18:38:27 +0000 Subject: [PATCH 061/862] svn log searches revisions in the whole repository --- ar/08-git-and-other-scms/01-chapter8.markdown | 2 +- az/08-git-and-other-scms/01-chapter8.markdown | 2 +- ca/08-git-and-other-scms/01-chapter8.markdown | 2 +- cs/08-git-and-other-scms/01-chapter8.markdown | 2 +- de/08-git-and-other-scms/01-chapter8.markdown | 2 +- en/08-git-and-other-scms/01-chapter8.markdown | 2 +- es-ni/08-git-and-other-scms/01-chapter8.markdown | 2 +- es/08-git-and-other-scms/01-chapter8.markdown | 2 +- fr/08-git-and-other-scms/01-chapter8.markdown | 2 +- ja/08-git-and-other-scms/01-chapter8.markdown | 2 +- ko/08-git-and-other-scms/01-chapter8.markdown | 2 +- mk/08-git-and-other-scms/01-chapter8.markdown | 2 +- nl/08-git-and-other-scms/01-chapter8.markdown | 2 +- no-nb/08-git-and-other-scms/01-chapter8.markdown | 2 +- pl/08-git-and-other-scms/01-chapter8.markdown | 2 +- pt-br/08-git-and-other-scms/01-chapter8.markdown | 2 +- ru/08-git-and-other-scms/01-chapter8.markdown | 2 +- th/08-git-and-other-scms/01-chapter8.markdown | 2 +- tr/08-git-and-other-scms/01-chapter8.markdown | 2 +- zh-tw/08-git-and-other-scms/01-chapter8.markdown | 2 +- zh/08-git-and-other-scms/01-chapter8.markdown | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/ar/08-git-and-other-scms/01-chapter8.markdown b/ar/08-git-and-other-scms/01-chapter8.markdown index 321cbb425..c91af673d 100644 --- a/ar/08-git-and-other-scms/01-chapter8.markdown +++ b/ar/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ However, the import isn’t perfect; and because it will take so long, you may a To get a list of the author names that SVN uses, you can run this: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt That gives you the log output in XML format — you can look for the authors, create a unique list, and then strip out the XML. (Obviously this only works on a machine with `grep`, `sort`, and `perl` installed.) Then, redirect that output into your users.txt file so you can add the equivalent Git user data next to each entry. diff --git a/az/08-git-and-other-scms/01-chapter8.markdown b/az/08-git-and-other-scms/01-chapter8.markdown index 41985f631..9aaf5c4e9 100644 --- a/az/08-git-and-other-scms/01-chapter8.markdown +++ b/az/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ However, the import isn’t perfect; and because it will take so long, you may a To get a list of the author names that SVN uses, you can run this: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt That gives you the log output in XML format — you can look for the authors, create a unique list, and then strip out the XML. (Obviously this only works on a machine with `grep`, `sort`, and `perl` installed.) Then, redirect that output into your users.txt file so you can add the equivalent Git user data next to each entry. diff --git a/ca/08-git-and-other-scms/01-chapter8.markdown b/ca/08-git-and-other-scms/01-chapter8.markdown index 41985f631..9aaf5c4e9 100644 --- a/ca/08-git-and-other-scms/01-chapter8.markdown +++ b/ca/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ However, the import isn’t perfect; and because it will take so long, you may a To get a list of the author names that SVN uses, you can run this: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt That gives you the log output in XML format — you can look for the authors, create a unique list, and then strip out the XML. (Obviously this only works on a machine with `grep`, `sort`, and `perl` installed.) Then, redirect that output into your users.txt file so you can add the equivalent Git user data next to each entry. diff --git a/cs/08-git-and-other-scms/01-chapter8.markdown b/cs/08-git-and-other-scms/01-chapter8.markdown index 3a1fc1a5a..b12839ae7 100644 --- a/cs/08-git-and-other-scms/01-chapter8.markdown +++ b/cs/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ Takový import však není úplně dokonalý a vzhledem k tomu, jak dlouho můž Chcete-li získat seznam jmen autorů používaných v SVN, spusťte tento příkaz: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt Vytvoříte tím log ve formátu XML. Můžete v něm vyhledávat autory, vytvořit si vlastní seznam a XML zase vyjmout. (Tento příkaz pochopitelně funguje pouze na počítačích, v nichž je nainstalován `grep`, `sort` a `perl`.) Poté tento výstup přesměrujte do souboru users.txt, abyste mohli vedle každého záznamu přidat stejná data o uživatelích Git. diff --git a/de/08-git-and-other-scms/01-chapter8.markdown b/de/08-git-and-other-scms/01-chapter8.markdown index 8f6fd6b41..b2adff7cd 100644 --- a/de/08-git-and-other-scms/01-chapter8.markdown +++ b/de/08-git-and-other-scms/01-chapter8.markdown @@ -506,7 +506,7 @@ Trotzdem ist der Import nicht perfekt. Und weil das ziemlich lange dauern wird, Um eine Liste der Namen der Autoren bekommen, die SVN benutzen, kannst Du folgendes Kommando ausführen: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt diff --git a/en/08-git-and-other-scms/01-chapter8.markdown b/en/08-git-and-other-scms/01-chapter8.markdown index 37ac490e4..7fddeda69 100644 --- a/en/08-git-and-other-scms/01-chapter8.markdown +++ b/en/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ However, the import isn’t perfect; and because it will take so long, you may a To get a list of the author names that SVN uses, you can run this: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt That gives you the log output in XML format — you can look for the authors, create a unique list, and then strip out the XML. (Obviously this only works on a machine with `grep`, `sort`, and `perl` installed.) Then, redirect that output into your users.txt file so you can add the equivalent Git user data next to each entry. diff --git a/es-ni/08-git-and-other-scms/01-chapter8.markdown b/es-ni/08-git-and-other-scms/01-chapter8.markdown index 1ea80ee65..ce703eb62 100644 --- a/es-ni/08-git-and-other-scms/01-chapter8.markdown +++ b/es-ni/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ However, the import isn’t perfect; and because it will take so long, you may a To get a list of the author names that SVN uses, you can run this: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt That gives you the log output in XML format — you can look for the authors, create a unique list, and then strip out the XML. (Obviously this only works on a machine with `grep`, `sort`, and `perl` installed.) Then, redirect that output into your users.txt file so you can add the equivalent Git user data next to each entry. diff --git a/es/08-git-and-other-scms/01-chapter8.markdown b/es/08-git-and-other-scms/01-chapter8.markdown index 6cb632876..981a56d40 100644 --- a/es/08-git-and-other-scms/01-chapter8.markdown +++ b/es/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ However, the import isn’t perfect; and because it will take so long, you may a To get a list of the author names that SVN uses, you can run this: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt That gives you the log output in XML format — you can look for the authors, create a unique list, and then strip out the XML. (Obviously this only works on a machine with `grep`, `sort`, and `perl` installed.) Then, redirect that output into your users.txt file so you can add the equivalent Git user data next to each entry. diff --git a/fr/08-git-and-other-scms/01-chapter8.markdown b/fr/08-git-and-other-scms/01-chapter8.markdown index 19e6caffb..e7e3ad7ac 100644 --- a/fr/08-git-and-other-scms/01-chapter8.markdown +++ b/fr/08-git-and-other-scms/01-chapter8.markdown @@ -445,7 +445,7 @@ Créez un fichier appelé `users.txt` contenant cette équivalence dans le forma Pour récupérer la liste des noms d'auteurs utilisés par SVN, vous pouvez utiliser la ligne suivante : - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt Cela génère une sortie au format XML — vous pouvez visualiser les auteurs, créer une liste unique puis éliminer l'XML. diff --git a/ja/08-git-and-other-scms/01-chapter8.markdown b/ja/08-git-and-other-scms/01-chapter8.markdown index 03b252da0..7b86af20e 100644 --- a/ja/08-git-and-other-scms/01-chapter8.markdown +++ b/ja/08-git-and-other-scms/01-chapter8.markdown @@ -363,7 +363,7 @@ Subversion に慣れているので SVN が出力する形式で歴史を見た SVN で使っている作者の一覧を取得するには、このようにします。 - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt これは、まずログを XML フォーマットで出力します。その中から作者を捜して重複を省き、XML を除去します (ちょっと見ればわかりますが、これは `grep` や `sort`、そして `perl` といったコマンドが使える環境でないと動きません)。この出力を users.txt にリダイレクトし、そこに Git のユーザーデータを書き足していきます。 diff --git a/ko/08-git-and-other-scms/01-chapter8.markdown b/ko/08-git-and-other-scms/01-chapter8.markdown index 2ff6aa7bf..307c1a6d4 100644 --- a/ko/08-git-and-other-scms/01-chapter8.markdown +++ b/ko/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ Subversion 저장소를 클론하면 쓸데 없는 파일을 커밋하지 않도 SVN에 기록된 Author 이름을 아래 명령으로 조회한다: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt 우선 XML 형식으로 SVN 로그를 출력하고, 거기서 Author 정보만 찾고, 중복된 것을 제거하고, XML 태그는 버린다. 물론 `grep`, `sort`, `perl` 명령이 동작하는 시스템에서만 이 명령을 사용할 수 있다. 이 결과에 Git Author 정보를 더해서 `users.txt`를 만든다. diff --git a/mk/08-git-and-other-scms/01-chapter8.markdown b/mk/08-git-and-other-scms/01-chapter8.markdown index 321cbb425..c91af673d 100644 --- a/mk/08-git-and-other-scms/01-chapter8.markdown +++ b/mk/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ However, the import isn’t perfect; and because it will take so long, you may a To get a list of the author names that SVN uses, you can run this: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt That gives you the log output in XML format — you can look for the authors, create a unique list, and then strip out the XML. (Obviously this only works on a machine with `grep`, `sort`, and `perl` installed.) Then, redirect that output into your users.txt file so you can add the equivalent Git user data next to each entry. diff --git a/nl/08-git-and-other-scms/01-chapter8.markdown b/nl/08-git-and-other-scms/01-chapter8.markdown index 80b861560..8939e3033 100644 --- a/nl/08-git-and-other-scms/01-chapter8.markdown +++ b/nl/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ Maar, de import is niet perfect; en omdat het zo lang zal duren, kun je het maar Om een lijst te krijgen van de auteurnamen, die SVN gebruikt kun je dit uitvoeren: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt Daarmee krijg je de log output in XML formaat – je kunt hierin zoeken naar de auteurs, een lijst met unieke vermeldingen creëren en dan de XML eruit halen. (Dit werkt natuurlijk alleen op een machine waarop `grep`, `sort` en `Perl` geïnstalleerd is.) Daarna stuur je die output naar je users.txt bestand zodat je de gelijkwaardige Git gebruiker data naast iedere vermelding kunt zetten. diff --git a/no-nb/08-git-and-other-scms/01-chapter8.markdown b/no-nb/08-git-and-other-scms/01-chapter8.markdown index 41985f631..9aaf5c4e9 100644 --- a/no-nb/08-git-and-other-scms/01-chapter8.markdown +++ b/no-nb/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ However, the import isn’t perfect; and because it will take so long, you may a To get a list of the author names that SVN uses, you can run this: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt That gives you the log output in XML format — you can look for the authors, create a unique list, and then strip out the XML. (Obviously this only works on a machine with `grep`, `sort`, and `perl` installed.) Then, redirect that output into your users.txt file so you can add the equivalent Git user data next to each entry. diff --git a/pl/08-git-and-other-scms/01-chapter8.markdown b/pl/08-git-and-other-scms/01-chapter8.markdown index c7c5762a8..90a3dcfc2 100644 --- a/pl/08-git-and-other-scms/01-chapter8.markdown +++ b/pl/08-git-and-other-scms/01-chapter8.markdown @@ -525,7 +525,7 @@ Aby otrzymać listę autorów używanych przez SVN, uruchom komendę: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt Komenda ta da wynik w formacie XML - z którego możesz wyciągnąć autorów, stworzyć z nich unikalną listę i następnie usunąć XMLa (Oczywiście to zadziała tylko na komputerze z zainstalowanymi programami `grep`, `sort`, oraz `perl`). Następnie przekieruj wynik komendy do pliku users.txt, tak abyś mógł dodać odpowiednik użytkownika w Gitcie dla każdego wpisu. diff --git a/pt-br/08-git-and-other-scms/01-chapter8.markdown b/pt-br/08-git-and-other-scms/01-chapter8.markdown index b575e499b..e44deec54 100644 --- a/pt-br/08-git-and-other-scms/01-chapter8.markdown +++ b/pt-br/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ No entanto, a importação não é perfeita; e já que vai demorar tanto tempo, Para obter uma lista dos nomes de autores que o SVN usa, você pode executar isto: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt Isso te dá a saída do log em formato XML — você pode pesquisar pelos autores, criar uma lista única, e depois tirar o XML. (Obviamente isso só funciona em uma máquina com `grep`, `sort`, e `perl` instalados.) Em seguida, redirecione a saída em seu arquivo users.txt assim, você pode adicionar os dados de usuários do Git equivalentes ao lado de cada entrada. diff --git a/ru/08-git-and-other-scms/01-chapter8.markdown b/ru/08-git-and-other-scms/01-chapter8.markdown index dd6b71084..1acefdbf1 100644 --- a/ru/08-git-and-other-scms/01-chapter8.markdown +++ b/ru/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ Git определяет ветку, в которую он отправит в Для того чтобы получить список авторов, который использует SVN, можно выполнить следующее: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' Эта команда выдаст журнал в формате XML — мы можем найти в нём информацию об авторах, создать из неё список с уникальными записями и избавиться от XML-разметки. (Разумеется, эта команда сработает только на машине с установленными `grep`, `sort` и `perl`). Затем перенаправьте вывод этой команды в файл `users.txt`, чтобы потом можно было добавить к каждой записи данные о соответствующих пользователях Git'а. diff --git a/th/08-git-and-other-scms/01-chapter8.markdown b/th/08-git-and-other-scms/01-chapter8.markdown index 321cbb425..c91af673d 100644 --- a/th/08-git-and-other-scms/01-chapter8.markdown +++ b/th/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ However, the import isn’t perfect; and because it will take so long, you may a To get a list of the author names that SVN uses, you can run this: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt That gives you the log output in XML format — you can look for the authors, create a unique list, and then strip out the XML. (Obviously this only works on a machine with `grep`, `sort`, and `perl` installed.) Then, redirect that output into your users.txt file so you can add the equivalent Git user data next to each entry. diff --git a/tr/08-git-and-other-scms/01-chapter8.markdown b/tr/08-git-and-other-scms/01-chapter8.markdown index 41985f631..9aaf5c4e9 100644 --- a/tr/08-git-and-other-scms/01-chapter8.markdown +++ b/tr/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ However, the import isn’t perfect; and because it will take so long, you may a To get a list of the author names that SVN uses, you can run this: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt That gives you the log output in XML format — you can look for the authors, create a unique list, and then strip out the XML. (Obviously this only works on a machine with `grep`, `sort`, and `perl` installed.) Then, redirect that output into your users.txt file so you can add the equivalent Git user data next to each entry. diff --git a/zh-tw/08-git-and-other-scms/01-chapter8.markdown b/zh-tw/08-git-and-other-scms/01-chapter8.markdown index 083b14f35..f781e3201 100644 --- a/zh-tw/08-git-and-other-scms/01-chapter8.markdown +++ b/zh-tw/08-git-and-other-scms/01-chapter8.markdown @@ -363,7 +363,7 @@ Git 通過搜尋提交歷史中 Subversion 分支的頭部(tip)來決定 dcommit 通過以下命令可以獲得 SVN 作者的列表: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt 它將輸出 XML 格式的日誌——你可以找到作者,建立一個單獨的列表,然後從 XML 中抽取出需要的資訊。(顯而易見,本方法要求主機上安裝了`grep`,`sort` 和 `perl`.)然後把輸出重定向到 user.txt 檔,然後就可以在每一項的後面添加相應的 Git 使用者資料。 diff --git a/zh/08-git-and-other-scms/01-chapter8.markdown b/zh/08-git-and-other-scms/01-chapter8.markdown index 8a0629743..34fa376f6 100644 --- a/zh/08-git-and-other-scms/01-chapter8.markdown +++ b/zh/08-git-and-other-scms/01-chapter8.markdown @@ -362,7 +362,7 @@ Git 通过搜寻提交历史中 Subversion 分支的头部来决定 dcommit 的 通过该命令可以获得 SVN 作者的列表: - $ svn log --xml | grep -P "^(.*?)<\/author>/$1 = /' > users.txt 它将输出 XML 格式的日志——你可以找到作者,建立一个单独的列表,然后从 XML 中抽取出需要的信息。(显而易见,本方法要求主机上安装了`grep`,`sort` 和 `perl`.)然后把输出重定向到 user.txt 文件,然后就可以在每一项的后面添加相应的 Git 用户数据。 From 679c1fd0116ef0b5b0a3ce5ee9cc36b84982c54b Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sat, 7 Dec 2013 15:12:03 +0100 Subject: [PATCH 062/862] [de] Translate chapter 6.4 (complete new translation) --- de/06-git-tools/01-chapter6.markdown | 85 ++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index f262dfcc2..7be31cbed 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -695,34 +695,59 @@ Damit ist es auf einfache Art und Weise möglich, die gestashten Änderungen in +Beim Arbeiten mit Git kommt es häufig vor, dass man seine Commit-Historie aus irgendeinem Grund noch einmal ändern möchte. Und das Tolle an Git ist, dass es dir die Möglichkeit bietet, Entscheidungen erst im allerletzten Moment zu treffen. Zum Beispiel bietet dir Git mit Hilfe der Staging-Area die Möglichkeit alle Dateien zu sammeln und kurz vor einem Commit zu entscheiden, welche Daten alle in einem Commit wandern sollen. Du kannst auch Deine Dateien, die sich geändert haben, aber noch nicht ins Repository eingepflegt werden sollen, mit dem Stash-Kommando in einem Zwischenspeicher ablegen. Außerdem kannst du bereits verfasste Commits nachträglich noch einmal ändern, so dass sich die Historie so ändert, als wäre sie ganz anders vorangeschritten. Das kann man zum Beispiel durch Änderung der Reihenfolge der Commits, durch Ändern von Commit-Nachrichten, durch Modifikationen an Dateien innerhalb eines Commits, durch Zusammenfügen zweier Commits zu einem Commit oder durch Löschen eines Commits erreichen. Und das besondere daran: Das alles bevor Du Deine Arbeit mit anderen teilst und veröffentlichst. + +In diesem Kapitel werden wir die nützlichen Arbeitsschritte besprechen, die Dir helfen Deine Commit-Historie Deinen Wünschen entsprechend zu gestalten, so dass Du Dein Ergebnis danach mit anderen teilen kannst und es damit Deinem gewünschten Ergebnis entspricht. + +### Ändern des letzten Commits ### +Am häufigsten möchte man wahrscheinlich seinen letzten durchgeführten Commit noch einmal nachträglich ändern. Meist sind es zwei Dinge, die man verändern möchte: Änderung der eingegebenen Commit-Nachricht oder den eigentlich Inhalt des Schnappschusses durch Hinzufügen, Ändern oder Löschen von Dateien. + +Die letzte Commit-Nachricht noch einmal zu ändern ist sehr einfach: + $ git commit --amend +Nach Eingabe dieses Befehls wird der Texteditor mit dem Inhalt der letzten Commit-Nachricht geöffnet. Jetzt hat man Gelegenheit diesen Text zu ändern. Nach dem Speichern und Schließen des Editors, wird die Commit-Nachricht des letzten Commits entsprechend angepasst. Der alte Commit ist dadurch nicht mehr vorhanden und Du erhälst einen neuen Commit mit dem gleichen Inhalt und Deiner neuen Commit-Nachricht. + +Wenn Du Deine Änderungen bereits eingecheckt hast und den Schnappschuss nachträglich durch Hinzufügen oder Ändern von Dateien noch einmal ändern möchtest, läuft das im Prinzip auf die gleiche Art und Weise ab. Meist kommt so etwas vor, weil man vergessen hat eine neu erstellte Datei zu stagen. Wenn so etwas passiert kannst Du folgendes machen: Führe Deine gewünschte Änderungen durch Ändern oder Hinzufügen einer Datei aus und stage dieses Ergebnis mit dem Befehl `git add`. Alternativ kannst Du auch mit dem Befehl `git rm` eine Datei aus dem Repository entfernen. Wenn die Staging Area Dein gewünschtes Ergebnis enthält, führst Du einfach den Befehl `git commit --amend` aus. Der neue Commit enthält nun die Änderungen aus dem alten Commit plus die Änderungen aus Deiner Staging Area. + +Mit dem Befehl `--amend` sollte man vorsichtig umgehen, weil mit jeder nachträglichen Modifikation eines Commits, ändert sich auch die SHA-1 Prüfsumme. Das Ändern des letzten Commits hat ein ähnliches Verhalten wie das Durchführen eines Rebase-Befehls. Deshalb sollte man einen Commit niemals nachträglich anpassen, wenn dieser bereits veröffentlicht wurde. + +### Änderung von mehreren Commit-Nachrichten ### +Um einen Commit, der etwas weiter in der Historie zurückliegt, zu ändern, hilft einem der Befehl `--amend` nicht weiter. Man benötigt dazu ein etwas mächtigeres und komplexeres Werkzeug. Für diese Aufgabe kann man den Rebase Befehl, den wir bereits kennengelernt haben, auf eine etwas andere Art und Weise nutzen. Anstatt den Rebase auf einen HEAD eines anderen Commits auszuführen, führt man den Rebase auf genau dem gleichen Commit aus, auf dem er bereits basiert. Dazu müssen wir nur den interaktiven Modus des Rebase-Befehls nutzen. Dieser bietet einem die Möglichkeit bei jedem Commit, der geändert werden soll, zu stoppen. Dann kann man seine Änderungen an den Dateien oder an der Commit-Nachricht entsprechend einpflegen und mit dem nächsten Commit fortfahren. Um einen interaktiven Rebase durchzuführen muss man die Option `-i` an den Befehl `git rebase` anhängen. Außerdem musst Du natürlich bestimmen, wie viele Commits Du ändern möchtest. Dazu musst Du den Commit angeben, auf welchem der Rebase basieren soll. + +Wenn Du zum Beispiel die letzten drei, oder eine oder mehrere der letzten drei Commit-Nachrichten ändern möchtest, musst du zusätzlich zu dem Befehl `git rebase -i` den übergeordneten Commit (also dem Commit, der in der Historie genau ein Commit zurückliegt) des letzten Commits, den Du ändern möchtest, angeben. Bei drei Commit-Nachrichten müsste das Argument also `HEAD~2^` beziehungsweise `HEAD~3` lauten. Wahrscheinlich fällt es Dir leichter das Argument `~3` zu merken, weil Du ja schließlich auf die letzten drei Einträge verweisen möchtest. Du solltest Dir aber bewusst sein, dass du auf den viertältesten Commit verweisen musst, also dem übergeordneten Commit, den Du ändern möchtest. + $ git rebase -i HEAD~3 +Es ist wichtig, dass Du dir bewusst bist, dass mit diesem Rebase Befehl jeder Commit im Bereich `HEAD~3..HEAD` geändert wird, unabhängig davon, ob Du die Commit-Nachricht beziehungsweise den Schnappschuss änderst oder nicht. Der Rebase-Befehl sollte nie einen Commit beinhalten, der bereits an einen zentralen Server gepusht worden ist. +Hälst Du Dich nicht daran, werden sich andere Entwickler über Dich ärgern oder wundern, weil es jetzt eine alternative Version von der gleichen Änderung gibt. + +Wenn Du den Befehl ausführst, erhälst Du eine Reihe von Commits in Deinem Texteditor. Das könnte in etwa folgendermaßen aussehen: + pick f7f3f6d changed my name a bit pick 310154e updated README formatting and added blame pick a5f4a0d added cat-file @@ -740,6 +765,8 @@ Damit ist es auf einfache Art und Weise möglich, die gestashten Änderungen in +Vielleicht ist es Dir schon aufgefallen, die Commits werden genau in der umgekehrten Reihenfolge dargestellt, wie sie der `log` Befehl ausgegeben hätte. Wenn Du also den Befehl `log` ausführst, erhält man in etwa die folgende Ausgabe: + $ git log --pretty=format:"%h %s" HEAD~3..HEAD a5f4a0d added cat-file 310154e updated README formatting and added blame @@ -747,14 +774,20 @@ Damit ist es auf einfache Art und Weise möglich, die gestashten Änderungen in +Siehst Du den Unterschied? Es ist genau die umgekehrte Reihenfolge. Ein interaktiver Rebase wird nach einem festen Schema, einer Art Skript, durchgeführt und der Texteditor zeigt dir an, wie dieses Skript genau ablaufen wird. Der Rebase startet bei dem Commit der in der Kommandozeile angegeben wird (`HEAD~3`) und führt die Änderungen, die durch jeden Commit hinzukommen, von oben nach unten aus. Das bedeteutet, dass anstatt dem neuesten, der älteste Commit ganz oben steht, weil dieser der erste Commit ist, der bearbeitet wird. + +Du musst das Skript so anpassen, dass es an jedem Commit anhält, den Du ändern möchtest. Dazu musst Du bei jedem Commit, an dem das Skript anhalten soll, das Wort "pick" mit dem Wort "edit" ersetzen. Um zum Beispiel die drittälteste Commit-Nachricht zu ändern, müssen die Änderungen am Skript in etwa folgendermaßen aussehen: + edit f7f3f6d changed my name a bit pick 310154e updated README formatting and added blame pick a5f4a0d added cat-file +Nachdem Du das Skript gespeichert und den Editor beendet hast, setzt Git nun alle Änderungen bis zum letzten Commit der Liste zurück und zeigt danach in der Kommandozeile in etwa folgendes an: + $ git rebase -i HEAD~3 Stopped at 7482e0d... updated the gemspec to hopefully work better You can amend the commit now, with @@ -767,33 +800,49 @@ Damit ist es auf einfache Art und Weise möglich, die gestashten Änderungen in +Diese Anweisungen zeigen dir sehr genau, was du zu tun hast. Gib also den folgenden Befehl ein: + $ git commit --amend +Im sich öffnenden Texteditor kannst Du jetzt die Commit-Nachricht ändern und danch wieder schließen. Danach führst Du folgenden Befehl aus: + $ git rebase --continue +Der letzte Befehl speichert die letzten beiden Commits automatisch im Repository und der Rebase ist danach abgeschlossen. Wenn Du in einer weiteren Zeile "pick" mit "edit" ersetzt hast, kannst Du die oben dargestellten Schritte entsprechend noch einmal ausführen. Git wird nach jedem Commit anhalten und dir die Möglichkeit bieten, den Commit anzupassen. Danach kannst Du Git auffordern den Rebase fortzusetzen (`git rebase --continue`). + +### Reihenfolge von Commits verändern ### +Mit einem interaktiven Rebase kannst du ebenso die Reihenfolge von Commits ändern oder sogar komplette Commits löschen. Um den Commit "added cat-file" zu löschen und die Reihenfolge der beiden anderen Commits zu ändern, kannst Du das vorhandene Skript + pick f7f3f6d changed my name a bit pick 310154e updated README formatting and added blame pick a5f4a0d added cat-file +folgendermaßen ändern: + pick 310154e updated README formatting and added blame pick f7f3f6d changed my name a bit +Nach dem Speichern und Verlassen des Editors, setzt Git nun alle Änderungen bis zum letzten Commit der Liste zurück, speichert den Commit `310154e`, danach den Commit `310154e` und beendet danach den Rebase. Das Ergebnis: Der Commit "added cat-file" ist aus der Historie verschwunden und die Reihenfolge der beiden restlichen Commits ist getauscht. + +### Mehrere Commits zusammenfassen ### +Man kann mit einem interaktiven Rebase auch mehrere Commits zu einem einzelnen Commit zusammenfassen. Im Skript der Rebase-Nachricht steht eine Anleitung, wie Du dazu vorgehen musst: + # # Commands: # p, pick = use commit @@ -806,12 +855,17 @@ Damit ist es auf einfache Art und Weise möglich, die gestashten Änderungen in +Wenn Du statt "pick" oder "edit", den Befehl "squash" angibst, führt Git beide Commits zu einem gemeinsamen Commit zusammen und bietet Dir die Möglichkeit die Commit-Nachricht ebenso entsprechend zu verheiraten. Wenn Du also aus den drei Commits einen einzelnen Commit machen willst, muss Dein Skript folgendermaßen aufgebaut sein: + pick f7f3f6d changed my name a bit squash 310154e updated README formatting and added blame squash a5f4a0d added cat-file +Nach dem Speichern und Beenden des Editor, führt Git alle drei Änderungen zu einem einzelnen Commit zusammen und öffnet einen Texteditor, der alle drei Commit-Nachrichten enthält: + + # This is a combination of 3 commits. # The first commit's message is: changed my name a bit @@ -826,16 +880,23 @@ Damit ist es auf einfache Art und Weise möglich, die gestashten Änderungen in +Du kannst nun die Commit-Nachricht entsprechend anpassen oder auch entsprechend dem vorgeschlagenen Ergebnis belassen. Wenn Du die Commit-Nachricht speicherst, hast Du danach nur noch einen einzelnen Commit, der die letzten drei Commits beinhaltet, in Deiner Historie. + +### Aufsplitten eines einzelnen Commits ### +Man kann mit Git einen einzelnen Commit auch aufsplitten. Das bedeutet, man setzt den ursprünglichen Commit zurück, fügt dann einen Teil der Änderungen zur Staging Area hinzu und checkt das Ergebnis ein. Dies kann man unbegrenzt oft wiederholen und so einen einzelnen Commit in mehrere Commits aufteilen. Nehmen wir an, wir möchten den mittleren der beiden Commits aufteilen. Anstatt "updated README formatting and added blame", möchten wir den Commit in folgende beiden Commits aufteilen: "updated README formatting" soll das Thema des ersten Commits und "added blame" soll das Thema des zweiten Commits sein. Dazu kannst Du das angezeigt Skript, welches Dir der Befehl `rebase -i` erzeugt, folgendermaßen anpassen: + pick f7f3f6d changed my name a bit edit 310154e updated README formatting and added blame pick a5f4a0d added cat-file +Nach dem Speichern und Schließen des Editors, setzt Git die Änderungen entsprechend zurück und wendet den ersten (`f7f3f6d`) und zweiten (`310154e`) Commit an und wechselt danach zurück zur Kommandozeile. Jetzt hast Du die Möglichkeit den letzten Commit zurückzusetzen, ohne das die Änderungen im Arbeitsverzeichnis zurückgesetzt werden. Das heißt, der Commit im Repository werden gelöscht, aber Deine Änderungen im Arbeitsverzeichnis gehen nicht verloren. Um dies durchzuführen, kannst du den Befehl `git reset HEAD^` verwenden. Jetzt kannst Du die gewünschten Änderungen für den ersten Commit zur Staging Area hinzufügen und danach einchecken. Diesen Vorgang kannst Du beliebig wiederholen, bis alle Änderungen eingecheckt sind. Wenn Du fertig bist, kannst du den Rebase mit `git rebase --continue` fortsetzen beziehungsweise abschließen: + $ git reset HEAD^ $ git add README $ git commit -m 'updated README formatting' @@ -845,6 +906,8 @@ Damit ist es auf einfache Art und Weise möglich, die gestashten Änderungen in +Git speichert dazu den letzten Commit (`a5f4a0d`) aus dem Skript im Repository. Das Resultet sieht in etwa folgendermaßen aus: + $ git log -4 --pretty=format:"%h %s" 1c002dd added cat-file 9b29157 added blame @@ -853,36 +916,56 @@ Damit ist es auf einfache Art und Weise möglich, die gestashten Änderungen in +Ich möchte Dich noch einmal darauf hinweisen, dass jede SHA Prüfsumme von allen Commits au der Liste geändert werden. Bitte stell also sicher, dass diese Commits in keinem öffentlichen Repository verfügbar sind. + +### Hol den Vorschlaghammer raus: filter-branch ### +Es gibt noch eine weitere Möglichkeit, wie man die Historie nach seinen Wünschen anpassen kann. Diese wird oft angewandt, wenn man eine große Zahl von Commits automatisiert mit Hilfe eines Skripts anpassen will. Zum Beispiel, kann man damit die E-Mail Adresse in jedem Commit ändern oder auch eine Datei aus jedem Commit entfernen. Das Werkzeug dazu heißt `filter-branch`. Damit kann man einen riesigen Teil der Historie ändern. Man sollte diesen Befehl also nur verwenden, wenn das Projekt noch nicht weit verbreitet ist, oder andere Personen noch nicht damit begonnen haben an dem Projekt zu Arbeiten (also auf Basis der bisherigen Historie neue Branches mit Commits erstellt). Trotzdem kann dieses Werkzeug sehr nützlich sein. Ich möchte hier ein paar der Möglichkeiten dieses Werkzeugs vorstellen. + +#### Löschen einer Datei aus jedem Commit #### +Dieses Szenario tritt sogar relativ häufig auf. Nehmen wir einmal an, jemand fügt gedankenlos eine große binäre Datei mit `git add .` zum Repository dazu und diese soll aber in keinem der Commits enthalten sein. Oder Du hast aus Versehen eine Datei, welche ein Passwort enthält, zum Repository hinzugefügt und möchtest dieses Repository nun veröffentlichen. `filter-branch` ist dann das Werkzeug Deiner Wahl um die komplette Historie umzukrempeln. Um eine Datei mit dem Namen "passwords.txt" aus der kompletten Historie zu löschen, kannst Du die Option `--tree-filter` verwenden: + $ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD Rewrite 6b9b3cf04e7c5686a9cb838c3f36a8cb6a0fc2bd (21/21) Ref 'refs/heads/master' was rewritten +Die Option `--tree-filer` führt den nachfolgenden Befehl nach jedem Auschecken eines Commits des Projekts aus und checkt danach das Ergebnis wieder ein. In diesem Beispiel, wird die Datei "passwords.txt" aus jedem Schnappschuss entfernt, unabhängig davon, ob sie existiert oder nicht. Ein anderes Beispiel wäre es, alle Backup-Dateien eines Texteditors aus dem Repository zu löschen. Dazu kann man in etwa den Befehl `git filter-branch -\-tree-filter "rm -f *~" HEAD` ausführen. + +Git informiert Dich über den Fortschritt dieses Vorgangs und Du siehst, wie jeder Commit angepasst wird und der Zeiger auf den Branch auf den letzten Commit gesetzt wird. Es ist empfehlenswert, diesen Befehl in einem Testzweig durchzuführen. Wenn das Ergebnis, wie gewünscht ausfällt, kann man danach den Master Branch auf diesen Testzweig setzen. Wenn man an den Befehl `filter-branch` die Option `--all` anfügt, führt Git diesen Vorgang für jeden vorhandenen Zweig aus. + +#### Aus einem Unterverzeichnis das neue Wurzelverzeichnis machen #### +Wenn man zum Beispiel ein Projekt aus einem anderen Versionskontrollwerkzeug in Git importiert, gibt es dort oft Verzeichnisse, die in Git nicht relevant sind, zum Beispiel trunk, tags, usw.. Wenn man also das Unterverzeichnis "trunk" das neue Wurzelverzeichnis machen will, kann man dies mit Hilfe von `filter-branch` umsetzen: + $ git filter-branch --subdirectory-filter trunk HEAD Rewrite 856f0bf61e41a27326cdae8f09fe708d679f596f (12/12) Ref 'refs/heads/master' was rewritten +Nach der Ausführung dieses Befehls ist das "trunk" Verzeichnis das neue Arbeitsverzeichnis. Bei diesem Vorgang entfernt Git außerdem alle Commits, die nicht eine Änderung des "trunk"-Verzeichnisses beinhalten. + +#### E-Mail Adresse in jedem Commit ändern #### +Verflixt, es ist schon wieder passiert. Du hast vergessen den Befehl `git config` auszuführen und Deinen Namen und E-Mail Adresse zu setzen bevor Du mit der Arbeit begonnen hast. Mit `filter-branch` kann man diesen Fehler einfach beheben. Man sollte nur darauf achten, dass man nur seine eigene E-Mail Adresse ändert. Deshalb verwenden wir die Option `--commit-filter`: + $ git filter-branch --commit-filter ' if [ "$GIT_AUTHOR_EMAIL" = "schacon@localhost" ]; then @@ -895,6 +978,8 @@ Damit ist es auf einfache Art und Weise möglich, die gestashten Änderungen in +Dieser Befehl durchforstet das Repository und ersetzt in jedem Commit, dessen E-Mail Adresse des Autors "schacon@localhost" lautet, mit der neuen E-Mail Adresse "schacon@example.com". Zusätzlich wir der Name des Autors geändert, falls dieser nicht vorher schon "Scott Chacon" war. Auf Grund der Architektur, dass in Git in jedem Commit die SHA1 Prüfsumme des Vorgänger Commits enthalten ist, ändert dieser Befehl jeden Commit in Deiner Historie. Die SHA1 Prüfsumme wird sich auch in allen Commits, die nicht die angegebene E-Mail Adresse enthalten, verändern. + ## Mit Hilfe von Git debuggen ## From 010788d52b9e856227eba5b8332272dbdf1abbbf Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 8 Dec 2013 13:55:02 +0100 Subject: [PATCH 063/862] [de] Translate chapter 6.5 (complete new translation) --- de/06-git-tools/01-chapter6.markdown | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index 7be31cbed..6c8e3111d 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -985,10 +985,15 @@ Dieser Befehl durchforstet das Repository und ersetzt in jedem Commit, dessen E- +Git bietet auch ein paar Werkzeuge, die den Debug-Vorgang bei einem Projekt unterstützen. Da Git so aufgebaut ist, dass es für nahezu jedes Projekt eingesetzt werden kann, sind diese Werkzeuge sehr generisch gehalten. Wenn gewisse Dinge schief laufen, können Dir aber diese Tools oft helfen, den Bug oder den Übeltäter zu finden. + +### Datei Annotation ### +Wenn Du nach einem Bug in Deinem Code suchst und gerne wissen willst, wann und warum dieser zum ersten mal auftrat, dann kann Dir das Werkzeug Datei Annotation (engl. File Annotation) sicher weiterhelfen. Es kann Dir anzeigen, in welchem Commit die jeweilige Zeile einer Datei zuletzt geändert wurde. Wenn Du also feststellst, dass eine Methode beziehungsweise eine Funktion in Deinem Code nicht mehr das gewünschte Resultat liefert, kannst Du Dir die Datei mit `git blame` genauer ansehen. Nach Aufruf des Befehls zeigt Git Dir an, welche Zeile von welcher Person als letztes geändert wurde, inklusive Datum. Das folgende Beispiel verwendet die Option `-L` um die Ausgabe auf die Zeilen 12 bis 22 einzuschränken: + $ git blame -L 12,22 simplegit.rb ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 12) def show(tree = 'master') ^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 13) command("git show #{tree}") @@ -1004,8 +1009,12 @@ Dieser Befehl durchforstet das Repository und ersetzt in jedem Commit, dessen E- +In der ersten Spalte wird die Kurzform der SHA1 Prüfsumme des Commits angezeigt, in welchem diese Zeile zuletzt verändert wurde. Die nächsten beiden Spalten weisen auf den Autor des Commits und wann dieser verfasst wurde, hin. Auf diese Weise kannst Du leicht bestimmen, wer die jeweilige Zeile geändert hat und wann dies durchgeführt wurde. In den nächsten Spalten wird die Zeilennummer und der Inhalt der Zeile angezeigt. Die Zeilen mit der SHA1 Prüfsumme `^4832fe2` weisen darauf hin, dass diese bereits im ersten Commit vorhanden waren. Das ist also der Commit, in dem die Datei "simplegit.rb" zum Repository hinzugefügt wurde und die Zeilen deuten damit darauf hin, dass diese bisher nie geändert wurden. Das ist für Dich wahrscheinlich ein bißchen verwirrend, denn nun kennst Du bereits drei Möglichkeiten, wie Git mit dem Zeichen `^` einer SHA1 Prüfsumme eine neue Bedeutung gibt. Aber in Zusammenhang mit `git blame` weist das Zeichen auf den eben geschilderten Sachverhalt hin. + +Eine weitere herausragende Eigenschaft von Git ist die Tatsache, dass es nicht per se das Umbenennen von Dateien verfolgt. Git speichert immer den jeweiligen Schnappschuss des Dateisystems und versucht erst danach zu bestimmen, welche Dateien umbenannt wurden. Das bietet Dir zum Beispiel die Möglichkeit herauszufinden, wie Code innerhalb des Repositorys hin und her verschoben wurde. Wenn Du also die Option `-C` an `git blame` anfügst, analysiert Git die angebene Datei und versucht herauszufinden, ob und von wo bestimmte Codezeilen herkopiert wurden. Vor kurzem habe ich ein Refactoring an einer Datei mit dem Namen `GITServerHandler.m` durchgeführt. Dabei habe ich diese Datei in mehrere Dateien aufgteilt, eine davon war `GITPackUpload.m`. Wenn ich jetzt `git blame` mit der Option `-C` auf die Datei `GITPackUpload.m` ausführe, erhalte ich eine Ausgabe mit den Codezeilen von denen das Ergebnis ursprünglich stammt: + $ git blame -C -L 141,153 GITPackUpload.m f344f58d GITServerHandler.m (Scott 2009-01-04 141) f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC @@ -1023,12 +1032,19 @@ Dieser Befehl durchforstet das Repository und ersetzt in jedem Commit, dessen E- +Das ist enorm hilfreich. Für gewöhnlich erhälst Du damit als ursprünglichen Commit, den Commit, von welchem der Code kopiert wurde, da dies der Zeitpunkt war, bei dem diese Zeilen zum ersten mal angefasst wurden. Git zeigt Dir den ursprünglichen Commit, in dem du die Zeilen verfasst hast, sogar an, wenn es sich dabei um eine andere Datei handelt. + +### Das Bisect Werkzeug - Binäre Suche### +`git blame` kann dir sehr weiterhelfen, wenn Du bereits weißt an welcher Stelle das Problem liegt. Wenn Du aber nicht weißt, warum gewisse Dinge schief laufen, und es gibt inzwischen dutzende oder hunderte von Commits seit dem letzten funktionierenden Stand, dann solltest du `git bisect` als Hilfestellung verwenden. Der `bisect` Befehl führt eine binäre Suche durch die Commit-Historie durch und hilft Dir auf schnelle Art und Weise die Commits zu bestimmen, die eventuell für das Problem verantwortlich sind. + +Nehmen wir zum Beispiel an, dass Du gerade eben Deinen Code in einer Produktivumgebung veröffentlicht hast und auf einmal bekommst Du zahlreiche Fehlerberichte über Probleme, die in Deiner Entwicklungsumgebung nicht aufgetreten sind. Du kannst Dir auch keinen Reim darauf bilden, warum der Code so reagiert. Nachdem Du Dich noch einmal näher mit Deinem Code beschäftigt hast, stellst Du fest, dass du die Fehlerwirkung reproduzieren kannst, aber Dir ist es immer noch ein Rätsel was genau schief läuft. Wenn Du vor einem solchen Problem stehst, hilft Dir es bestimmt, wenn Du die Historie in mehrere Teile aufspaltest (engl. bisect: halbieren, zweiteilen). Als erstes startest Du mit dem Befehl `git bisect start`. Danach gibst Du mit dem Befehl `git bisect bad` an, dass der derzeit ausgecheckte Commit den Fehler aufweist. Jetzt braucht Git noch die Information, in welchem Commit das Problem noch nicht aufgetreten ist. Dazu verwendest du den Befehl `git bisect good [good_commit]`: + $ git bisect start $ git bisect bad $ git bisect good v1.0 @@ -1037,18 +1053,24 @@ Dieser Befehl durchforstet das Repository und ersetzt in jedem Commit, dessen E- +Nach Ausführen des letzten Befehls, zeigt Git Dir als erstes an, dass in etwa 12 Commits zwischen der letzten guten Revision (v1.0) und der aktuellen, fehlerhaften Revision liegen. Auf Basis dieser Information hat Git Dir den mittleren Commit ausgecheckt. Jetzt hast Du die Möglichkeit Deine Tests auf Basis des ausgecheckten Stands durchzuführen um herauszufinden, ob in diesem Commit der Fehler bereits bestand. Wenn der Fehler hier bereits auftritt, dann wurde er in diesem oder in einem der früheren Commits eingefügt. Wenn der Fehler hier noch nicht auftritt, dann wurde er in einem der späteren Commits eingeschleppt. In unserem Beispiel nehmen wir an, dass in diesem Commit der Fehler noch nicht bestand. Das geben wir mit dem Befehl `git bisect good` an und fahren fort: + $ git bisect good Bisecting: 3 revisions left to test after this [b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing +Git hat Dir jetzt einen weiteren Commit ausgecheckt und zwar wieder den mittleren Commit zwischen dem letzten Stand im Repository und dem mittleren Commit aus der letzten Runde. Hier nehmen wir an, dass Du nach Deinen durchgeführten Tests feststellst, dass in diesem Commit der Fehler bereits vorhanden ist. Das müssen wir Git über `git bisect bad` mitteilen: + $ git bisect bad Bisecting: 1 revisions left to test after this [f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table +Git checkt wieder den nächsten mittleren Commit aus und wir stellen fest, dass dieser in Ordnung ist. Ab jetzt hat Git alle notwendigen Informationen um festzustellen, in welchem Commit der Fehler eingebaut wurde. Git zeigt Dir dazu die SHA1 Prüfsumme des ersten fehlerhaften Commits an. Zusätzlich gibt es noch weitere Commit Informationen und welche Dateien in diesem Commit geändert wurden, an. Das sollte dir nun helfen, den Fehler näher zu bestimmen: + $ git bisect good b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04 @@ -1062,15 +1084,21 @@ Dieser Befehl durchforstet das Repository und ersetzt in jedem Commit, dessen E- +Wenn Du fertig mit der Fehlersuche bist, solltest Du den Befehl `git bisect reset` ausführen. Dies checkt den ursprünglichen Stand aus, den du ausgecheckt hattest, bevor Du mit der Fehlersuche begonnen hast: + $ git bisect reset +Wie Du vielleicht gesehen hast, ist dieser Befehl ein mächtiges Werkzeug um hunderte von Commit auf schnelle Art und Weise nach einem bestimmten Fehler zu durchsuchen. Besonders nützlich ist es, wenn Du ein Skript hast, welches mit dem Fehlercode Null beendet, wenn das Projekt in Ordnung ist und mit einem Fehlercode größer Null, wenn das Projekt Fehler enthält. Wenn Dir ein solches Skript zur Verfügung steht, kannst Du den bisher manuell durchgeführten Vorgang auch automatisieren. Wie im vorigen Beispiel musst Du Git den zuletzt fehlerfreien Commit und den fehlerhaften Commit angeben. Als verkürzte Schreibweise kannst Du an den Befehl `bisect start` den fehlerhaften und den fehlerfreien Commit angeben: + $ git bisect start HEAD v1.0 $ git bisect run test-error.sh +Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem Auscheckvorgang das Skript `test-error.sh` aus und zwar solange bis es den Commit findet, der als erstes ein fehlerhaftes Ergebnis liefert. Statt einem Skript kannst Du natürlich auch `make` oder `make tests` oder eine beliebige, andere Testumgebung starten. + ## Submodule ## From ee7e3ce7578a96c1ab6c7450bc2e0e9c4c00a11b Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 8 Dec 2013 14:06:12 +0100 Subject: [PATCH 064/862] [de] Update german project progress in Readme file --- de/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/de/README.md b/de/README.md index a2e4f2e99..435baaec3 100644 --- a/de/README.md +++ b/de/README.md @@ -1,4 +1,4 @@ -# Deutsche Übersetzung # +# Deutsche Übersetzung # Die deutsche Übersetzung wird im Repository progit-de/progit verwaltet. Wenn Du an der deutschen Übersetzung mitarbeiten willst, dann melde dich am besten bei uns. Du kannst dazu einen Issue im Repository progit-de/progit erzeugen. Wir werden Dir dann einen Vorschlag machen, wie Du uns am besten helfen kannst. Der Workflow an sich ist unter Workflow beschrieben. Ein Status der Übersetzung der jeweiligen Kapitel findest Du unter "Status der Übersetzung". @@ -400,41 +400,41 @@ Bitte den Status nicht aktualisieren. Dies übernimmt ein Maintainer. Ja Nein Ja -Review notwendig +Review notwendig 6.4 -Nein Ja Nein -Übersetzung fehlt +Ja +Review notwendig 6.5 -Nein Ja Nein -Übersetzung fehlt +Ja +Review notwendig 6.6 Nein -Ja Nein +Ja Übersetzung fehlt 6.7 Nein -Ja Nein +Ja Übersetzung fehlt 6.8 Nein -Ja Nein +Ja Übersetzung fehlt From bedf387d42a4fed73e2a8014812dc6a24ad3d5cf Mon Sep 17 00:00:00 2001 From: harupong Date: Mon, 9 Dec 2013 13:09:50 +0900 Subject: [PATCH 065/862] Add bug info for pandoc to README.md Pandoc version 1.9.1.1, which is installed with `apt-get` on Ubuntu 12.04, has a [bug](https://github.com/jgm/pandoc/issues/964) that hides a word after tilde. It is fixed with Pandoc version 1.11.1. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index e33ec9bfe..713a4b3f6 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,10 @@ On MacOS you can do like this:: * xelatex: http://tug.org/mactex/ 4. `$ makeebooks zh` #will produce a mobi +## Notes on pandoc + +Please use Pandoc version 1.11.1 or later as older versions(confirmed on 1.9.1.1) has a [bug](https://github.com/jgm/pandoc/issues/964) which hides a word after tilde `~`. You can do `pandoc -v` to see which version you have installed. + # Errata If you see anything that is technically wrong or otherwise in need of From f3828f0ad5681df04843d2301da74b522c99a6d0 Mon Sep 17 00:00:00 2001 From: Karel Heyse Date: Thu, 12 Dec 2013 13:02:13 +0100 Subject: [PATCH 066/862] =?UTF-8?q?[nl]=20Replace=20the=20word=20=E2=80=9C?= =?UTF-8?q?disk=E2=80=9D=20by=20its=20translation=20=E2=80=9Charde=20schij?= =?UTF-8?q?f=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nl/09-git-internals/01-chapter9.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nl/09-git-internals/01-chapter9.markdown b/nl/09-git-internals/01-chapter9.markdown index 8026d2ee8..6c4a0e457 100644 --- a/nl/09-git-internals/01-chapter9.markdown +++ b/nl/09-git-internals/01-chapter9.markdown @@ -473,9 +473,9 @@ De blob is nu een andere blob, wat betekent dat alhoewel je slechts een enkele r $ git cat-file -s 05408d195263d853f09dca71d55116663690c27c 12908 -Je hebt nu twee vrijwel identieke 12K grote objecten op je disk. Zou het niet fijn zijn als Git één van de twee volledig op kon slaan, en het tweede object slechts als delta tussen die en de eerste? +Je hebt nu twee vrijwel identieke 12K grote objecten op je harde schijf. Zou het niet fijn zijn als Git één van de twee volledig op kon slaan, en het tweede object slechts als delta tussen die en de eerste? -Het blijkt dat dat kan. Het initiële formaat waarin Git objecten opslaat op disk wordt een los object formaat genoemd. Maar, eens in de zoveel tijd pakt Git een aantal van die objecten in een enkel binair bestand wat een packfile genoemd wordt, om wat ruimte te besparen en efficiënter te zijn. Git doet dit als je teveel losse objecten rond hebt slingeren, als je het `git gc` commando handmatig uitvoert, of als je naar een remote server pushed. Om te zien wat er gebeurd, kun je Git handmatig vragen om de objecten in te pakken met het `git gc` commando: +Het blijkt dat dat kan. Het initiële formaat waarin Git objecten opslaat op de harde schijf wordt een los object formaat genoemd. Maar, eens in de zoveel tijd pakt Git een aantal van die objecten in een enkel binair bestand wat een packfile genoemd wordt, om wat ruimte te besparen en efficiënter te zijn. Git doet dit als je teveel losse objecten rond hebt slingeren, als je het `git gc` commando handmatig uitvoert, of als je naar een remote server pushed. Om te zien wat er gebeurd, kun je Git handmatig vragen om de objecten in te pakken met het `git gc` commando: $ git gc Counting objects: 17, done. @@ -495,7 +495,7 @@ Als je in je objecten map kijkt, zul je zien dat de meeste objecten verdwenen zi De objecten die overgebleven zijn, zijn de blobs waarnaar geen enkel commit wijst – in dit geval zijn het de "what is up, doc?" en de "test content" voorbeeld-blobs die je eerder aangemaakt hebt. Omdat je ze nooit aan een commit toegevoegd hebt, worden ze beschouwd als 'rondslingerend' en worden ze niet in je nieuwe packfile ingepakt. -De andere bestanden zijn je nieuwe packfile en een index. De packfile is een enkel bestand dat de inhoud bevat van alle objecten die van je bestandssysteem verwijderd zijn. De index is een bestand dat offsets binnen de packfile bevat, zodat je snel naar een specifiek object kunt zoeken. Wat cool is, is dat alhoewel de objecten op de disk voordat je `gc` aanriep samen zo'n 12K groot waren, is de nieuwe packfile slechts 6K. Je hebt je diskverbruik gehalveerd door je bestanden in te pakken. +De andere bestanden zijn je nieuwe packfile en een index. De packfile is een enkel bestand dat de inhoud bevat van alle objecten die van je bestandssysteem verwijderd zijn. De index is een bestand dat offsets binnen de packfile bevat, zodat je snel naar een specifiek object kunt zoeken. Wat cool is, is dat alhoewel de objecten op de harde schijf voordat je `gc` aanriep samen zo'n 12K groot waren, is de nieuwe packfile slechts 6K. Je hebt je schijfgebruik gehalveerd door je bestanden in te pakken. Hoe doet Git dit? Als Git objecten inpakt, zoekt het naar bestanden die gelijk genaamd en in grootte zijn, en slaat slechts de delta's van één versie van het bestand naar de volgende op. Je kunt in de packfile kijken en zien wat Git gedaan heeft om ruimte te besparen. Het `git verify-pack` sanitaire voorzieningen commando stelt je in staat om te zien wat er ingepakt is: From f85f9e9c3e544f83dc7103ef712ffad92851ece5 Mon Sep 17 00:00:00 2001 From: Volkan Gezer Date: Thu, 12 Dec 2013 13:55:14 +0100 Subject: [PATCH 067/862] Fix typos --- tr/01-introduction/01-chapter1.markdown | 30 ++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tr/01-introduction/01-chapter1.markdown b/tr/01-introduction/01-chapter1.markdown index c2cb79170..c0ae4c269 100644 --- a/tr/01-introduction/01-chapter1.markdown +++ b/tr/01-introduction/01-chapter1.markdown @@ -1,6 +1,6 @@ # Başlangıç # -Bu bölümde Git kullanımı hakkında temel bilgileri bulacaksınız. İşe, sürüm kontrol sistemleri hakkında açıklamalarla başlayacağız; daha sonra Git kurulumunun nasıl yaplacağını, en son olarak da aracın konfigürasyon ve kullanımını açıklayacağız. Bu bölümün sonunda Git'in varlık sebebini ve neden onu kullanmanız gerektiğini anlayacak, Git'i kullanmaya başlamak için kurulumu tamamlamış olacaksınız. +Bu bölümde Git kullanımı hakkında temel bilgileri bulacaksınız. İşe, sürüm kontrol sistemleri hakkında açıklamalarla başlayacağız; daha sonra Git kurulumunun nasıl yapılacağını, en son olarak da aracın yapılandırma ve kullanımını açıklayacağız. Bu bölümün sonunda Git'in varlık sebebini ve neden onu kullanmanız gerektiğini anlayacak, Git'i kullanmaya başlamak için kurulumu tamamlamış olacaksınız. ## Sürüm Kontrolü Hakkında ## @@ -12,16 +12,16 @@ Bir grafik ya da web tasarımcısıysanız ve bir görselin ya da tasarımın de Çoğu insan, dosyaları bir klasöre (akılları başlarındaysa tarih ve zaman bilgisini de içeren bir klasöre) kopyalayarak sürüm kontrolü yapmayı tercih eder. Bu yaklaşım çok yaygındır, çünkü çok kolaydır; ama aynı zamanda hatalara da alabildiğine açıktır. Hangi klasörde olduğunuzu unutup yanlış dosyaya yazabilir ya da istemediğiniz dosyaların üstüne kopyalama yapabilirsiniz. -Bu sorunla başedebilmek için, programcılar uzun zaman önce, dosyalardaki bütün değişiklikleri sürüm kontrolüne alan basit bir veritabanına sahip olan yerel SKS'ler geliştirdiler (bkz. Figür 1-1). +Bu sorunla baş edebilmek için, programcılar uzun zaman önce, dosyalardaki bütün değişiklikleri sürüm kontrolüne alan basit bir veritabanına sahip olan yerel SKS'ler geliştirdiler (bkz. Figür 1-1). Insert 18333fig0101.png Figür 1-1. Yerel sürüm kontrol diyagramı. -En popüler SKS araçlarndan biri, bugün hâlâ pekçok bilgisayara kurulu olarak dağıtılan, rcs adında bir sistemdi. Ünlü Mac OS X işletim sistemi bile, Developer Tools'u yüklediğinizde, rcs komutunu kurmaktadır. Bu araç, iki sürüm arasındaki yamaları (yani, dosyalar arasındaki farkları) özel bir formatta diske kaydeder; daha sonra, bu yamaları birbirine ekleyerek, bir dosyann belirli bir sürümdeki görünümünü yeniden oluşturur. +En yaygın SKS araçlarından biri, bugün hâlâ pekçok bilgisayara kurulu olarak dağıtılan, rcs adında bir sistemdi. Ünlü Mac OS X işletim sistemi bile, Developer Tools'u yüklediğinizde, rcs komutunu kurmaktadır. Bu araç, iki sürüm arasındaki yamaları (yani, dosyalar arasındaki farkları) özel bir biçimde diske kaydeder; daha sonra, bu yamaları birbirine ekleyerek, bir dosyanın belirli bir sürümdeki görünümünü yeniden oluşturur. ### Merkezi Sürüm Kontrol Sistemleri ### -İnsanların karşılaştığı ikinci büyük sorun, başka sistemlerdeki programcılarla birlikte çalışma ihtiyacından ileri gelir. Bu sorunla başa çıkabilmek için, Merkezi Sürüm Kontrol Sistemleri (MSKS) gelitirilmiştir. Bu sistemler, meselâ CVS, Subversion ve Perforce, sürüm kontrolüne alınan bütün dosyaları tutan bir sunucu ve bu sunucudan dosyaları seçerek alan (_check out_) istemcilerden oluşur. Bu yöntem, yıllarca, sürüm kontrolünde standart yöntem olarak kabul gördü (bkz. Figür 1-2). +İnsanların karşılaştığı ikinci büyük sorun, başka sistemlerdeki programcılarla birlikte çalışma ihtiyacından ileri gelir. Bu sorunla başa çıkabilmek için, Merkezi Sürüm Kontrol Sistemleri (MSKS) geliştirilmiştir. Bu sistemler, meselâ CVS, Subversion ve Perforce, sürüm kontrolüne alınan bütün dosyaları tutan bir sunucu ve bu sunucudan dosyaları seçerek alan (_check out_) istemcilerden oluşur. Bu yöntem, yıllarca, sürüm kontrolünde standart yöntem olarak kabul gördü (bkz. Figür 1-2). Insert 18333fig0102.png Figür 1-2. Merkezi sürüm kontrol diyagramı. @@ -43,7 +43,7 @@ Dahası, bu sistemlerden çoğu birden çok uzak uçbirimdeki yazılım havuzuyl ## Git'in Kısa Bir Tarihçesi ## -Hayattaki pekçok harika şey gibi, Git de bir miktar yaratıcı yıkım ve ateşli tartışmayla başladı. Linux çekirdeği (_kernel_) oldukça büyük ölçekli bir açık kaynak kodlu yazılım projesidir. Linux çekirdek bakım ve geliştirme yaşam süresinin çoğunda (1991-2002), yazılım değişiklikleri yamalar ve arşiv dosyaları olarak tutulup taşındı. 2002 yılında, Linux çekirdek projesi, BitKeeper adında tescilli bir DSKS kullanmaya başladı. +Hayattaki pek çok harika şey gibi, Git de bir miktar yaratıcı yıkım ve ateşli tartışmayla başladı. Linux çekirdeği (_kernel_) oldukça büyük ölçekli bir açık kaynak kodlu yazılım projesidir. Linux çekirdek bakım ve geliştirme yaşam süresinin çoğunda (1991-2002), yazılım değişiklikleri yamalar ve arşiv dosyaları olarak tutulup taşındı. 2002 yılında, Linux çekirdek projesi, BitKeeper adında tescilli bir DSKS kullanmaya başladı. 2005 yılında, Linux çekirdeğini geliştiren toplulukla BitKeeper'ı geliştiren şirket arasındaki ilişki bozuldu ve aracın topluluk tarafından ücretsiz olarak kullanılabilmesi uygulamasına son verildi. Bu, Linux geliştirim topluluğunu (ve özellikle Linux'un yaratıcısı olan Linus Torvalds'ı) BitKeeper'ı kullanırken aldıkları derslerden yola çıkarak kendi araçlarını geliştirme konusunda harekete geçirdi. Yeni sistemin hedeflerinden bazıları şunlardı: @@ -53,18 +53,18 @@ Hayattaki pekçok harika şey gibi, Git de bir miktar yaratıcı yıkım ve ate * Bütünüyle dağıtık olma * Linux çekirdeği gibi büyük projelerle verimli biçimde başa çıkabilme (hız ve veri boyutu) -2005'teki doğumundan beri, Git kullanım kolaylıklarını geliştirebilmek için evrilip olgunlaştı, ama yine de bu niteliklerini korudu. Git, inanılmaz ölçüde hızlı, büyük ölçekli projelerde alabildiğine verimli ve çizgisel olmayan geiştirim (bkz. 3. Bölüm) için inanılmaz bir dallanma (_branching_) sistemine sahip. +2005'teki doğumundan beri, Git kullanım kolaylıklarını geliştirebilmek için evrilip olgunlaştı, ama yine de bu niteliklerini korudu. Git, inanılmaz ölçüde hızlı, büyük ölçekli projelerde alabildiğine verimli ve çizgisel olmayan geliştirim (bkz. 3. Bölüm) için inanılmaz bir dallanma (_branching_) sistemine sahip. ## Git'in Temelleri ## -Peki Git özünde nedir? Bu, özümsenmesi gereken önemli bir altbölüm, çünkü Git'in ne olduğunu ve temel çalışma ilkelerini anlarsanız, Git'i etkili biçimde kullanmanız çok daha kolay olacaktır. Git'i öğrenirken, Subversion ve Perforce gibi diğer SKS'ler hakkında bildiklerinizi aklınızdan çıkarmaya çalışın; bu aracı kullanırken yaşanabilecek kafa karışıklıklarını önlemenize yardımcı olacaktır. Git'in, kullanıcı arayüzü söz konusu sistemlerle benzerlik gösterse de, bilgiyi depolama ve yorumlama biçimi çok farklıdır; bu farklılıkları anlamak, aracı kullanırken kafa karışıklığına düşmenizi engellemekte yardımcı olacaktır. +Peki Git özünde nedir? Bu, özümsenmesi gereken önemli bir alt bölüm, çünkü Git'in ne olduğunu ve temel çalışma ilkelerini anlarsanız, Git'i etkili biçimde kullanmanız çok daha kolay olacaktır. Git'i öğrenirken, Subversion ve Perforce gibi diğer SKS'ler hakkında bildiklerinizi aklınızdan çıkarmaya çalışın; bu aracı kullanırken yaşanabilecek kafa karışıklıklarını önlemenize yardımcı olacaktır. Git'in, kullanıcı arayüzü söz konusu sistemlerle benzerlik gösterse de, bilgiyi depolama ve yorumlama biçimi çok farklıdır; bu farklılıkları anlamak, aracı kullanırken kafa karışıklığına düşmenizi engellemekte yardımcı olacaktır. ### Farklar Değil, Bellek Kopyaları ### Git ile diğer SKS'ler (Subversion ve ahbapları dahil) arasındaki esas fark, Git'in bilgiyi yorumlayış biçimiyle ilgilidir. Kavramsal olarak, diğer sistemlerin çoğu, bilgiyi dosya-tabanlı bir dizi değişiklik olarak depolar. Bu sistemler (CVS, Subversion, Perforce, Bazaar ve saire) bilgiyi, kayıt altında tuttukları bir dosya kümesi ve zamanla her bir dosya üzerinde yapılan değişikliklerin listesi olarak yorumlarlar (bkz. Figür 1-4). Insert 18333fig0104.png -Figür 1-4. Diğer sistemler veriyi her bir dosyanın ilk sürümu üzerinde yapılan değişiklikler olarak depolarma eğilimindedir. +Figür 1-4. Diğer sistemler veriyi her bir dosyanın ilk sürümu üzerinde yapılan değişiklikler olarak depolama eğilimindedir. Git, veriyi böyle yorumlayıp depolamaz. Bunun yerine, Git, veriyi, bir mini dosya sisteminin bellek kopyaları olarak yorumlar. Her kayıt işleminde (_commit_), ya da projenizin konumunu her kaydedişinizde, Git o anda dosyalarınızın nasıl göründüğünün bir fotoğrafını çekip o bellek kopyasına bir referansı depolar. Verimli olabilmek için, değişmeyen dosyaları yeniden depolamaz, yalnızca halihazırda depolanmış olan bir önceki özdeş kopyaya bir bağlantı kurar. Git'in veriyi yorumlayışı daha çok Figür 1-5'teki gibidir. @@ -75,17 +75,17 @@ Bu, Git'le neredeyse bütün diğer SKS'ler arasında ciddi bir ayrımdır. Bu a ### Neredeyse Her İşlem Yerel ### -Git'teki işlemlerin çoğu, yalnızca yerel dosyalara ve kaynaklara ihtiyaç duyar —genellikle bilgisayar ağındaki başka bir bilgisayardaki bilgilere ihtiyaç yoktur. Eğer çoğu işlemin ağ gecikmesi maliyetiyle gerçekleştiği bir MSKS kullanmışsanız, Git'in bu yönünü görünce, onun hız tanrıları tarafından kutsanmış olduğunu düşünebilirsiniz. Çünkü projenin bütün tarihçesi orada, yerel diskinide bulunmaktadır, işlemlerin çoğu anlık gerçekleşiyor gibi görünür. +Git'teki işlemlerin çoğu, yalnızca yerel dosyalara ve kaynaklara ihtiyaç duyar —genellikle bilgisayar ağındaki başka bir bilgisayardaki bilgilere ihtiyaç yoktur. Eğer çoğu işlemin ağ gecikmesi maliyetiyle gerçekleştiği bir MSKS kullanmışsanız, Git'in bu yönünü görünce, onun hız tanrıları tarafından kutsanmış olduğunu düşünebilirsiniz. Çünkü projenin bütün tarihçesi orada, yerel diskinde bulunmaktadır, işlemlerin çoğu anlık gerçekleşiyor gibi görünür. Örneğin, projenin tarihçesini taramak için Git bir sunucuya bağlanıp oradan tarihçeyi indirdikten sonra görüntülemekle uğraşmaz —yerel veritabanını okumak yeterlidir. Bu da proje terihçesini neredeyse anında görünteleyebilmeniz anlamına gelir. Bir dosyanın şimdiki haliyle bir ay önceki hali arasındaki farkları görmek isterseniz, Git, bir sunucudan fark hesaplaması yapmasını talep etmek ya da karşılaştırmayı yerelde yapabilmek için dosyanın bir ay önceki halini indirmek zorunda kalmak yerine, dosyanın bir ay önceki halini yerelde bulup fark hesaplamasını yerelde yapar. -Bu aynı zamanda, eğer bağlantınız kopmuşsa, ya da VPN bağlantını yoksa yapamayacağınız şeylerin de sayıca oldukça sınırlı olduğu anlamına geliyor. Uçağa ya da trene binmiş olduğunuz halde biraz çalışmak istiyorsanız, yükleme yapabileceğiniz bir ağ bağlantısına kavuşana kadar güle oynaya kayıt yapabilirsiniz. Eve vardığınızda VPN istemcinizin olması gerektiği gibi çalışmıyorsa, yine de çalışmaya devam edebilirsiniz. pekçok başka sistemde bunları yapmak ya imk^ansız ya da zahmetlidir. Söz gelimi Perforce'ta, bir sunucuya bağlı değilseniz fazlaca bir şey yapamazsınız; Subversion ve CVS'te dosyaları değiştirebilirsiniz, ama veritabanına kayıt yapamazsınız (çünkü veritabanına bağlantınız yoktur). Bu, çok önemli bir sorun gibi görünmeyebilir, ama ne kadar fark yaratabileceğini gördüğünüzde şaşırabilirsiniz. +Bu aynı zamanda, eğer bağlantınız kopmuşsa, ya da VPN bağlantını yoksa yapamayacağınız şeylerin de sayıca oldukça sınırlı olduğu anlamına geliyor. Uçağa ya da trene binmiş olduğunuz halde biraz çalışmak istiyorsanız, yükleme yapabileceğiniz bir ağ bağlantısına kavuşana kadar güle oynaya kayıt yapabilirsiniz. Eve vardığınızda VPN istemcinizin olması gerektiği gibi çalışmıyorsa, yine de çalışmaya devam edebilirsiniz. pek çok başka sistemde bunları yapmak ya imk^ansız ya da zahmetlidir. Söz gelimi Perforce'ta, bir sunucuya bağlı değilseniz fazlaca bir şey yapamazsınız; Subversion ve CVS'te dosyaları değiştirebilirsiniz, ama veritabanına kayıt yapamazsınız (çünkü veritabanına bağlantınız yoktur). Bu, çok önemli bir sorun gibi görünmeyebilir, ama ne kadar fark yaratabileceğini gördüğünüzde şaşırabilirsiniz. ### Git Bütünlüklüdür ### Git'te her şey depolanmadan önce sınama toplamından geçirilir (_checksum_) ve daha sonra bu sınama toplamı kullanılarak ifade edilir. Bu da demek oluyor ki, Git fark etmeden bir dosyanın ya da klasörün içeriğini değiştirmek mümkün değildir. Bu işlev Git'in merkezi işlevlerinden biridir ve felsefesiyle bir bütünlük oluşturur. Transfer sırasında veri kaybı ya da doysa arızası olmuşsa, Git bunu mutlaka fark edecektir. -Git'in sınama toplamı için kullandığı mekanizmaya SHA-1 özeti denir. Bu, on altılı sayı sisteminin (_hexadecimal_) sembolleriyle gösterilen (0-9 ve A-F) ve dosya ve klasör düzenini temel alan bir hesaplamayla elde deilen 40 karakterlik bir karakter dizisidir. Bir SHA-1 özeti şuna benzer: +Git'in sınama toplamı için kullandığı mekanizmaya SHA-1 özeti denir. Bu, on altılı sayı sisteminin (_hexadecimal_) sembolleriyle gösterilen (0-9 ve A-F) ve dosya ve klasör düzenini temel alan bir hesaplamayla elde denilen 40 karakterlik bir karakter dizisidir. Bir SHA-1 özeti şuna benzer: 24b9da6552252987aa493b52f8696cd6d3b00373 @@ -99,7 +99,7 @@ Bu Git kullanmayı keyifli hale getirir, çünkü işleri ciddi biçimde sıkın ### Üç Aşama ### -Şimdi dikkat! Öğrenme sürecinizin pürüzsüz ilerlemesini istiyorsanız, aklınızda bulundurmanız gereken esas şey bu. Git'te, dosyalarınızın içinde bulunabileceği üç aşama (_state_) vardır: kaydedilmiş, değiştirilmiş ve hazırlanmış. Kaydedilmiş, verinin güvenli biçimde veritabanında depolanmış olduğu anlamına gelir. Değiştirilmiş, dosyayı değiştirmiş olduğunuz fakat henüz veritabanına kaydetmediğiniz anlamına gelir. Hazılanmış ise, değiştirilmiş bir dosyayı bir sonraki kayıt işleminde bellek kopyasına alınmak üzere işaretlediğiniz anlamına gelir. +Şimdi dikkat! Öğrenme sürecinizin pürüzsüz ilerlemesini istiyorsanız, aklınızda bulundurmanız gereken esas şey bu. Git'te, dosyalarınızın içinde bulunabileceği üç aşama (_state_) vardır: kaydedilmiş, değiştirilmiş ve hazırlanmış. Kaydedilmiş, verinin güvenli biçimde veritabanında depolanmış olduğu anlamına gelir. Değiştirilmiş, dosyayı değiştirmiş olduğunuz fakat henüz veritabanına kaydetmediğiniz anlamına gelir. Hazırlanmış ise, değiştirilmiş bir dosyayı bir sonraki kayıt işleminde bellek kopyasına alınmak üzere işaretlediğiniz anlamına gelir. Bu da bizi bir Git projesinin üç ana bölümüne getiriyor: Git klasörü, çalışma klasörü ve hazırlık alanı. @@ -126,7 +126,7 @@ Gelin Git'i kullanmaya başlayalım. Her şeyden önce, Git'i kurmanız gerekiyo ### Kaynak Kodundan Kurulum ### -Yapabiilyorsanız, Git'i kaynak kodundan kurmak kullanışlıdır, çünkü böylece en yeni versiyonunu edinebilirsiniz. Git'in her yeni versiyonu yararlı kullanıcı arayüzü güncellemeleri içerir, dolayısıyla en son versiyonu kurmak, eğer yazılım derlemek konusunda sıkıntı yaşamayacağınızı düşünüyorsanız, en iyi yoldur. Ayrıca kimi zaman, Linux dağıtımları yazılımlaarın çok eski paketlerini içerirler; dolayısıyla, çok güncel bir dağıtıma sahip değilseniz ya da terstaşımalar (_backport_) kullanmıyorsanız, kaynak koddan kurulum en mantıklı seçenek olabilir. +Yapabiliyorsanız, Git'i kaynak kodundan kurmak kullanışlıdır, çünkü böylece en yeni versiyonunu edinebilirsiniz. Git'in her yeni versiyonu yararlı kullanıcı arayüzü güncellemeleri içerir, dolayısıyla en son versiyonu kurmak, eğer yazılım derlemek konusunda sıkıntı yaşamayacağınızı düşünüyorsanız, en iyi yoldur. Ayrıca kimi zaman, Linux dağıtımları yazılımların çok eski paketlerini içerirler; dolayısıyla, çok güncel bir dağıtıma sahip değilseniz ya da terstaşımalar (_backport_) kullanmıyorsanız, kaynak koddan kurulum en mantıklı seçenek olabilir. Git'i kurmak için, Git'in bağımlı olduğu şu kütüphanelerin sisteminizde bulunması gerekiyor: curl, zlib, openssl, expat, ve libiconv. Örneğin, (Fedora gibi) yum aracına ya da (Debian tabanlı sistemler gibi) apt-get aracına sahip bir sistemdeyseniz, bağımlılıkları kurmak için şu komutlardan birini kullanabilirsiniz: @@ -198,7 +198,7 @@ Git, Windows sistemlerde `$HOME` klasöründeki (çoğu kullanıcı için `C:\Do ### Kimliğiniz ### -Git'i kurduğunuzda yapmanız gereken ilk şey adınızı ve e-posta adresinizi ayarlamaktır. Bunun önemli olmasının nedeni herbir Git kaydının bu bilgiyi kullanıyor olması ve bu bilgilerin dolaşıma soktuğunuz kayıtlara değişmez biçimde işlenmesidir. +Git'i kurduğunuzda yapmanız gereken ilk şey adınızı ve e-posta adresinizi ayarlamaktır. Bunun önemli olmasının nedeni her bir Git kaydının bu bilgiyi kullanıyor olması ve bu bilgilerin dolaşıma soktuğunuz kayıtlara değişmez biçimde işlenmesidir. $ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com @@ -207,7 +207,7 @@ Yinelemek gerekirse, `--global` seçeneğini kullandığınızda bunu bir kez ya ### Editörünüz ### -Kimlik ayarlarınızı yaptığınıza göre, Git sizden bir mesaj yazmanızı istediğinde kullanacağınız editörle ilgili düzenlemeyi yapabilirsiniz. Aksi belirtilmedikçe Git sisteminizdeki öntanımlı (_defaul_) editörü kullanır, bu da genellikle Vi ya da Vim'dir. Emacs gibi başka bir metin editörü kullanmak isterseniz, şu komutu kullanabilirsiniz: +Kimlik ayarlarınızı yaptığınıza göre, Git sizden bir mesaj yazmanızı istediğinde kullanacağınız editörle ilgili düzenlemeyi yapabilirsiniz. Aksi belirtilmedikçe Git sisteminizdeki öntanımlı (_default_) editörü kullanır, bu da genellikle Vi ya da Vim'dir. Emacs gibi başka bir metin editörü kullanmak isterseniz, şu komutu kullanabilirsiniz: $ git config --global core.editor emacs From e60af9b40d67bd70d2113b32e6b4f097b7a332df Mon Sep 17 00:00:00 2001 From: Karel Heyse Date: Wed, 27 Nov 2013 01:51:08 +0100 Subject: [PATCH 068/862] [nl] Fix capitalisation of one title --- nl/02-git-basics/01-chapter2.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nl/02-git-basics/01-chapter2.markdown b/nl/02-git-basics/01-chapter2.markdown index 41ddaddc7..b572aff30 100644 --- a/nl/02-git-basics/01-chapter2.markdown +++ b/nl/02-git-basics/01-chapter2.markdown @@ -38,7 +38,7 @@ Dat commando doet hetzelfde als het vorige, maar dan heet de doelmap `mygrit`. Git heeft een aantal verschillende transport protocollen die je kunt gebruiken. Het vorige voorbeeld maakt gebruik van het `git://` protocol, maar je kunt ook `http(s)://` of `gebruiker@server:/pad.git` tegenkomen, dat het SSH transport protocol gebruikt. *Hoofdstuk 4* zal alle beschikbare opties introduceren die de server kan gebruiken om je Git repository aan te kunnen, met daarbij de voors en tegens van elk. -## Wijzigingen Aan Het Repository Vastleggen ## +## Wijzigingen aan het repository vastleggen ## Je hebt een bonafide Git repository en een checkout of werkkopie van de bestanden voor dat project. Je moet wat wijzigingen maken en deze committen in je repository, iedere keer zodra het project een status bereikt die je wilt vastleggen. From 93c8cb5369a8def06d1503c93bf8496ebea61855 Mon Sep 17 00:00:00 2001 From: Volkan Gezer Date: Thu, 12 Dec 2013 17:24:53 +0100 Subject: [PATCH 069/862] Fix typos --- tr/02-git-basics/01-chapter2.markdown | 102 +++++++++++++------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/tr/02-git-basics/01-chapter2.markdown b/tr/02-git-basics/01-chapter2.markdown index e576d0073..fd769f132 100644 --- a/tr/02-git-basics/01-chapter2.markdown +++ b/tr/02-git-basics/01-chapter2.markdown @@ -6,15 +6,15 @@ Git'i kullanmaya başlamak için yalnızca bir bölüm okuyacak kadar zamanını Bir Git projesi edinmenin başlıca iki yolu vardır. Bunlardan ilki, halihazırda varolan bir projeyi Git'e aktarmaktır. İkincisi ise bir sunucuda yer alan bir Git yazılım havuzunu klonlamakdır. -### Varolan Bir Klasörde Yazılım Havuzu Oluşturmak ### +### Var olan Bir Klasörde Yazılım Havuzu Oluşturmak ### -Varolan bir projenizi sürüm kontrolü altına almak istiyorsanız, projenin bulunduğu klasöre gidip aşağıdaki komutu çalıştırmanız gerekir: +Var olan bir projenizi sürüm kontrolü altına almak istiyorsanız, projenin bulunduğu klasöre gidip aşağıdaki komutu çalıştırmanız gerekir: $ git init Bu, gerekli yazılım havuzu dosyalarını —Git iskeletini— içeren `.git` adında bir klasör oluşturur. Bu noktada, projenizdeki hiçbir şey sürüm kontrolüne girmiş değildir. (Oluşturulan `.git` klasöründe tam olarak hangi dosyaların bulunduğu hakkında daha fazla bilgi edinmek için bkz. _9. Bölüm_.) -Varolan dosyalarınızı sürüm kontrolüne almak istiyorsanız, o dosyaları hazırlayıp kayıt etmelisiniz. Bunu, sürüm kontrolüne almak istediğiniz dosyaları belirleyip kayıt altına aldığınız birkaç git komutuyla gerçekleştirebilirsiniz: +Var olan dosyalarınızı sürüm kontrolüne almak istiyorsanız, o dosyaları hazırlayıp kayıt etmelisiniz. Bunu, sürüm kontrolüne almak istediğiniz dosyaları belirleyip kayıt altına aldığınız birkaç git komutuyla gerçekleştirebilirsiniz: $ git add *.c $ git add README @@ -22,9 +22,9 @@ Varolan dosyalarınızı sürüm kontrolüne almak istiyorsanız, o dosyaları h Birazdan bu komutların üzerinde duracağız. Bu noktada, sürüm kontrolüne aldığınız dosyaları içeren bir Git yazılım havuzunuz var. -### Varolan Bir Yazılım Havuzunu Klonlamak ### +### Var olan Bir Yazılım Havuzunu Klonlamak ### -Varolan bir Git yazılım havuzunu klonlamak istiyorsanız —söz gelimi, katkıda bulunmak istediğiniz bir proje varsa- ihtiyacınız olan komut `git clone`. Subversion gibi başka SKS'lere aşinaysanız, komutun `checkout` değil `clone` olduğunu fark etmişsinizdir. Bu önemli bir ayrımdır —Git, sunucuda bulunan neredeyse bütün veriyi kopyalar. `git clone` komutunu çalıştırdığınızda her dosyanın proje tarihçesinde bulunan her sürümü istemciye indirilir. Hatta, sunucunuzun diski bozulacak olsa, herhangi bir istemcideki herhangi bir klonu, sunucuyu klonlandığı zamanki haline geri getirmek için kullanabilirsiniz (sunucunuzdaki bazı çengel betikleri (_hook_) kaybedebilirsiniz, ama sürümlenmiş verinin tamamı elinizin altında olacaktır —daha fazla ayrıntı için bkz. _4. Bölüm_) +Var olan bir Git yazılım havuzunu klonlamak istiyorsanız —söz gelimi, katkıda bulunmak istediğiniz bir proje varsa- ihtiyacınız olan komut `git clone`. Subversion gibi başka SKS'lere aşinaysanız, komutun `checkout` değil `clone` olduğunu fark etmişsinizdir. Bu önemli bir ayrımdır —Git, sunucuda bulunan neredeyse bütün veriyi kopyalar. `git clone` komutunu çalıştırdığınızda her dosyanın proje tarihçesinde bulunan her sürümü istemciye indirilir. Hatta, sunucunuzun diski bozulacak olsa, herhangi bir istemcideki herhangi bir klonu, sunucuyu klonlandığı zamanki haline geri getirmek için kullanabilirsiniz (sunucunuzdaki bazı çengel betikleri (_hook_) kaybedebilirsiniz, ama sürümlenmiş verinin tamamı elinizin altında olacaktır —daha fazla ayrıntı için bkz. _4. Bölüm_) Bir yazılım havuzu `git clone [url]` komutuyla klonlanır. Örneğin, Grit adlı Ruby Git kütüphanesini klonlamak isterseniz, bunu şu şekilde yapabilirsiniz: @@ -42,9 +42,9 @@ Git'in bir dizi farklı transfer protokolü vardır. Yukarıdaki örnek `git://` Gerçek bir Git yazılım havuzuna ve söz konusu proje için gerekli olan bir dosya seçmesine sahipsiniz. Bu proje üzerinde değişiklikler yapmanız ve proje kaydetmek istediğiniz bir seviyeye geldiğinde bu değişikliklerin bir bellek kopyasını kaydetmeniz gerekecek. -Unutmayın, çalışma klasörünüzdeki dosyalar iki halden birinde bulunurlar: _izlenenler_ (_tracked_) ve _izlenmeyenler_ (_untracked_). _İzlenen_ dosyalar, bir önceki bellek kopyasında bulunan dosyalardır; bunlar _değişmemiş_, _değişmiş_ ya da _hazırlanmış_ olabilirler. Geri kalan her şey —çalışma klasörünüzde bulunan ve bir önceki bellek kopyasında ya da hazırlama alanında bulumayan dosyalar— _izlenmeyen_ dosyalardır. Bir yazılım havuzunu yeni kopyalamışsanız, bütün dosyalar, henüz yeni seçme yaptığınız ve hiçbir şeyi değiştirmediğiniz için, izlenen ve değişmemiş olacaktır. +Unutmayın, çalışma klasörünüzdeki dosyalar iki halden birinde bulunurlar: _izlenenler_ (_tracked_) ve _izlenmeyenler_ (_untracked_). _İzlenen_ dosyalar, bir önceki bellek kopyasında bulunan dosyalardır; bunlar _değişmemiş_, _değişmiş_ ya da _hazırlanmış_ olabilirler. Geri kalan her şey —çalışma klasörünüzde bulunan ve bir önceki bellek kopyasında ya da hazırlama alanında bulunmayan dosyalar— _izlenmeyen_ dosyalardır. Bir yazılım havuzunu yeni kopyalamışsanız, bütün dosyalar, henüz yeni seçme yaptığınız ve hiçbir şeyi değiştirmediğiniz için, izlenen ve değişmemiş olacaktır. -Dosyaları düzenlemeye başladığınzıda, Git onları değişmiş olarak görecektir, çünkü son kaydınızdan beri üzerlerinde değişiklik yapmış olacaksınız. Değiştirdiğiniz bu dosyaları önce _hazırlayıp_ sonra bütün _hazırlanmış_ değişiklikleri kaydedeceksiniz ve bu döngü böyle sürüp gidecek. Bu döngü, Figür 2-1'de gösteriliyor. +Dosyaları düzenlemeye başladığınızda, Git onları değişmiş olarak görecektir, çünkü son kaydınızdan beri üzerlerinde değişiklik yapmış olacaksınız. Değiştirdiğiniz bu dosyaları önce _hazırlayıp_ sonra bütün _hazırlanmış_ değişiklikleri kaydedeceksiniz ve bu döngü böyle sürüp gidecek. Bu döngü, Figür 2-1'de gösteriliyor. Insert 18333fig0201.png @@ -89,11 +89,11 @@ Yeni bir dosyayı izlemeye almak için `git add` komutunu kullanmalısınız. RE # new file: README # -Hazırlık alanında olduğunu “Changes to be committed” başlığının altında olmasına bakarak söyleyebilirsiniz. Eğer bu noktada bir kayıt (_commit_) yapacak olursanız, dosyanın `git add` komutunu çalıştırdığınız andaki hali bellek kopyasına kaydedilecektir. Daha önce `git init` komutunu çalıştırdıktan sonra projenize dosya eklemek için `git add (dosya)` komutunu çalıştırdığınızı hatırlayacaksınız —bunun amacı klasörünüzdeki dosyaları izlemeye almaktı. `git add` komutu bir dosya ya da klasörün konumuyla çalışır; eğer söz konusu olan br klasörse, klasördeki bütün dosyaları tekrarlamalı olarak projeye ekler. +Hazırlık alanında olduğunu “Changes to be committed” başlığının altında olmasına bakarak söyleyebilirsiniz. Eğer bu noktada bir kayıt (_commit_) yapacak olursanız, dosyanın `git add` komutunu çalıştırdığınız andaki hali bellek kopyasına kaydedilecektir. Daha önce `git init` komutunu çalıştırdıktan sonra projenize dosya eklemek için `git add (dosya)` komutunu çalıştırdığınızı hatırlayacaksınız —bunun amacı klasörünüzdeki dosyaları izlemeye almaktı. `git add` komutu bir dosya ya da klasörün konumuyla çalışır; eğer söz konusu olan bir klasörse, klasördeki bütün dosyaları tekrarlamalı olarak projeye ekler. ### Değiştirilen Dosyaları Hazırlamak ### -Gelin şimdi halihazırda izlenmekte olan bir dosyayı değiştirelim. İzlenmekte olan `benchmarks.rb` adındaki bir dosyayı değiştirip `status` komutunu çaıştırdığınızda şöyle bir ekran çıktısıyla karşılaşırsınız: +Gelin şimdi halihazırda izlenmekte olan bir dosyayı değiştirelim. İzlenmekte olan `benchmarks.rb` adındaki bir dosyayı değiştirip `status` komutunu çalıştırdığınızda şöyle bir ekran çıktısıyla karşılaşırsınız: $ git status # On branch master @@ -166,7 +166,7 @@ Ne oldu? `benchmarks.rb` dosyası hem kayda hazırlanmış hem de kayda hazırla * Bir klasörü belirtmek üzere örüntüleri bir eğik çizgi (`/`) ile sonlandırabilirsiniz. * Bir örüntüyü ünlem işaretiyle (`!`) başlattığınızda, örüntünün tersi gereçli olur. -_Glob_ örüntüleri _shell_'ler tarafından kullanılan basitleştirilmiş kurallı ifadelerdir (_regular expression_). Bir asterisk işareti (`*`) sıfır ya da daha fazla karakterle eşleşir; `[abc]` köşeli parantezin içindeki herhangi bir karakterle eşleşir (buradaki örnekte `a`, `b`, ya da `c` ile); soru işareti (`?`) bir karakterle eşleşir; tireyle ayrılmış karakterleri içine alan bir köşeli parantez (`[0-9]`) bu aralıktaki bütün karakterlerle eşleşir (bu örnekte 0'dan 9'a kadar olan karakterler). +_Glob_ örüntüleri _shell_'ler tarafından kullanılan basitleştirilmiş kurallı ifadelerdir (_regular expression_). Bir yıldız işareti (`*`) sıfır ya da daha fazla karakterle eşleşir; `[abc]` köşeli parantezin içindeki herhangi bir karakterle eşleşir (buradaki örnekte `a`, `b`, ya da `c` ile); soru işareti (`?`) bir karakterle eşleşir; tireyle ayrılmış karakterleri içine alan bir köşeli parantez (`[0-9]`) bu aralıktaki bütün karakterlerle eşleşir (bu örnekte 0'dan 9'a kadar olan karakterler). Bir `.gitignore` dosyası örneği daha: @@ -184,7 +184,7 @@ Bir `.gitignore` dosyası örneği daha: ### Kayda Hazırlanmış ve Hazırlanmamış Değişiklikleri Görüntülemek ### -`git status` komutunu fazla anlaşılmaz buluyorsanız —yalnızca hangi dosyaların değiştiğini değil, bu dosyalarda tam olarak nelerin değiştiğini görmek istiyorsanız— `git diff` komutunu kullanabilirsiniz. `git diff` komutunu ileride ayrıntılı olarak inceleyeceğiz; ama bu komutu muhtemelen en çok şu iki soruya cevap bulmak için kullanacaksınız: Değiştirip de henüz kayda hazırlamadığınız neler var? Ve kayda olmak üzere hangi değişikliklerin hazırlığını yaptınız? `git status` bu soruları genel biçimde cevaplıyor olsa da `git diff` eklenen ve çıkarılan bütün dosyaları —olduğu gibi yamayı— görsterir. +`git status` komutunu fazla anlaşılmaz buluyorsanız —yalnızca hangi dosyaların değiştiğini değil, bu dosyalarda tam olarak nelerin değiştiğini görmek istiyorsanız— `git diff` komutunu kullanabilirsiniz. `git diff` komutunu ileride ayrıntılı olarak inceleyeceğiz; ama bu komutu muhtemelen en çok şu iki soruya cevap bulmak için kullanacaksınız: Değiştirip de henüz kayda hazırlamadığınız neler var? Ve kayda olmak üzere hangi değişikliklerin hazırlığını yaptınız? `git status` bu soruları genel biçimde cevaplıyor olsa da `git diff` eklenen ve çıkarılan bütün dosyaları —olduğu gibi yamayı— gösterir. Diyelim `README` dosyasını düzenleyip kayda hazırladınız, sonra da `benchmarks.rb` dosyasını düzenlediniz ama kayda hazırlamadınız. `status` komutunu çalıştırdığınızda şöyle bir şey görürsünüz: @@ -222,7 +222,7 @@ Henüz kayda hazırlamadığınız değişiklikleri görmek için `git diff` kom Komut, çalışma klasörünüzün içeriğiyle kayda hazırlık alanının içeriğini karşılaştırır. Sonuç size henüz kayda hazırlamadığınız değişiklikleri gösterir. -Kayda hazırlamış olduğunuz değişiklikleri görmek için `git diff --cache` komutunu kullanabilirsiniz. (1.6.1'den sonraki Git sürümlerinde hatırlaması daha kolay olabilecek `git diff --staged` komutunu da kullanabilirsiniz.) Bu komut kayda hazırlanmış değişikliklerle son kaydı karşılatırır. +Kayda hazırlamış olduğunuz değişiklikleri görmek için `git diff --cache` komutunu kullanabilirsiniz. (1.6.1'den sonraki Git sürümlerinde hatırlaması daha kolay olabilecek `git diff --staged` komutunu da kullanabilirsiniz.) Bu komut kayda hazırlanmış değişikliklerle son kaydı karşılaştırır. $ git diff --cached diff --git a/README b/README @@ -312,7 +312,7 @@ Metin editörü aşağıdaki metni görüntüler (bu örnek Vim ekranından): ~ ".git/COMMIT_EDITMSG" 10L, 283C -Gördüğünüz gibi hazır kayıt mesajı `git status` çıktısının `#` kullanılarak devre dışı bırakılmış haliyle en üstte bir boş satırdan oluşur. Bu devre dışı bırakılmış kayıt mesajını silip yerine kendi kayıt mesajınızı yazabilir, ya da neyi kaydettiğinizi size hatırlatması için orada bırakabilirsiniz. (Neyi değiştirdiğinizin daha ayrıntlı olarak hatırlatılmasını isterseniz, `git commit` mesajını `-v` seçeneğiyle kullanabilirsiniz. Bu seçenek kaydetmekte olduğunuz değişikliğin içeriğini de (_diff_) editörde gösterecektir.) Editörü kapattığınızda Git, yazdığınız mesajı kullanarak değişikliği kaydeder (devre dışı bırakılmış bölümü ve değişikliğin içeriğini mesajın dışında bırakır). +Gördüğünüz gibi hazır kayıt mesajı `git status` çıktısının `#` kullanılarak devre dışı bırakılmış haliyle en üstte bir boş satırdan oluşur. Bu devre dışı bırakılmış kayıt mesajını silip yerine kendi kayıt mesajınızı yazabilir, ya da neyi kaydettiğinizi size hatırlatması için orada bırakabilirsiniz. (Neyi değiştirdiğinizin daha ayrıntılı olarak hatırlatılmasını isterseniz, `git commit` mesajını `-v` seçeneğiyle kullanabilirsiniz. Bu seçenek kaydetmekte olduğunuz değişikliğin içeriğini de (_diff_) editörde gösterecektir.) Editörü kapattığınızda Git, yazdığınız mesajı kullanarak değişikliği kaydeder (devre dışı bırakılmış bölümü ve değişikliğin içeriğini mesajın dışında bırakır). Bir başka seçenek de, kayıt mesajınızı `commit` komutunu `-m` seçeneğiyle aşağıdaki gibi kullanmaktır: @@ -340,7 +340,7 @@ Her ne kadar kayıtları tam istediğiniz gibi düzenlemek inanılmaz derecede y [master 83e38c7] added new benchmarks 1 files changed, 5 insertions(+), 0 deletions(-) -Gördünüğüz gibi, kayıt işlemi yapmadan önce `benchmarks.rb` dosyasını `git add` komutundan geçirmek zorunda kalmadınız. +Gördüğünüz gibi, kayıt işlemi yapmadan önce `benchmarks.rb` dosyasını `git add` komutundan geçirmek zorunda kalmadınız. ### Dosyaları Ortadan Kaldırmak ### @@ -523,7 +523,7 @@ Dilerseniz `git log`'u özet bilgiler veren bir dizi seçenekle birlikte kullana lib/simplegit.rb | 25 +++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 0 deletions(-) -Gördüğünüz gibi `--stat` seçeneği, her kaydın altına o kayıtta değişikliğe uğramış dosyaların listesini, kaç tane dosyanın değişikliğe uğradığını ve söz konusu dosyalara kaç satırın eklenip çıkarıldığı bilgisini ekler. Bu bilgilerin bir özetini de kaydın en altına yerleştirir. Oldukça yararlı bir başka seçenek de `--pretty` seçeneğidir. Bu seçenek `log` çıktısının biçimini değiştirmek için kullanılır. Bu seçenekle birlikte kullanacağınız birkaç tane öntanımlı ek seçenek vardır. `oneline` ek seçeneği her bir kaydı tek bir satırda gösterir; bu çok sayıda kayda göz atıyorsanız yararlı olabilir. Ayrıca `short`, `full` ve `fuller`seçenekleri aşağı yukarı aynı miktarda bilgiyi —bazı farklarla— gösterir: +Gördüğünüz gibi `--stat` seçeneği, her kaydın altına o kayıtta değişikliğe uğramış dosyaların listesini, kaç tane dosyanın değişikliğe uğradığını ve söz konusu dosyalara kaç satırın eklenip çıkarıldığı bilgisini ekler. Bu bilgilerin bir özetini de kaydın en altına yerleştirir. Oldukça yararlı bir başka seçenek de `--pretty` seçeneğidir. Bu seçenek `log` çıktısının biçimini değiştirmek için kullanılır. Bu seçenekle birlikte kullanacağınız birkaç tane öntanımlı ek seçenek vardır. `oneline` ek seçeneği her bir kaydı tek bir satırda gösterir; bu çok sayıda kayda göz atıyorsanız yararlı olabilir. Ayrıca `short`, `full` ve `fuller` seçenekleri aşağı yukarı aynı miktarda bilgiyi —bazı farklarla— gösterir: $ git log --pretty=oneline ca82a6dff817ec66f44342007202690a93763949 changed the version number @@ -587,9 +587,9 @@ Bunlar `git log`'la birlikte kullanabileceğiniz seçeneklerden yalnızca birka ### Log Çıktısını Sınırlandırma ### -`git log` komutu, biçimlendirme seçeneklerinin yanı sıra bir dizi sınırlandırma seçeneği de sunar —bu seçenekler kayıtların yalnızca bir alt kümesini gösterir. Bu seçeneklerden birini yukarıda gördünüz —yalnızca son iki kaydı gösteren `-2` seçeneğini. Aslında, son `n` kaydı görmek için `n` yerine herhangi bir tam sayı koyarak bu seçeneği `-` biçiminde kullanabilirsiniz. Bunu muhtemelen çok sık kullanmazsınız, zira Git `log` çıktısını zaten sayfa sayfa gösteriyor, dolayısıyla `git log` komutunu çaıştırdığınızda zaten önce kayıtların birinci sayfasını göreceksiniz. +`git log` komutu, biçimlendirme seçeneklerinin yanı sıra bir dizi sınırlandırma seçeneği de sunar —bu seçenekler kayıtların yalnızca bir alt kümesini gösterir. Bu seçeneklerden birini yukarıda gördünüz —yalnızca son iki kaydı gösteren `-2` seçeneğini. Aslında, son `n` kaydı görmek için `n` yerine herhangi bir tam sayı koyarak bu seçeneği `-` biçiminde kullanabilirsiniz. Bunu muhtemelen çok sık kullanmazsınız, zira Git `log` çıktısını zaten sayfa sayfa gösteriyor, dolayısıyla `git log` komutunu çalıştırdığınızda zaten önce kayıtların birinci sayfasını göreceksiniz. -Öte yandan `--since` ya da `--until` gibi çıktıyı zamanla sınırlayan seçenekler işinizi kolaylaştırabilir. Söz gelimi, şu komut, son iki hafta içinde apılmış kayıtları listeliyor: +Öte yandan `--since` ya da `--until` gibi çıktıyı zamanla sınırlayan seçenekler işinizi kolaylaştırabilir. Söz gelimi, şu komut, son iki hafta içinde yapılmış kayıtları listeliyor: $ git log --since=2.weeks @@ -604,7 +604,7 @@ Tablo 2-3, bu seçenekleri ve birkaç başka yaygın seçeneği listeliyor. Seçenek Açıklama -(n) Yalnızca son n kaydı göster. --since, --after Yalnızca belirli bir tarihten sonra eklenmiş kayıtlları göster. - --until, --before Yalnızca belirli bir tarhten önce yapılmış kayıtları göster. + --until, --before Yalnızca belirli bir tarihten önce yapılmış kayıtları göster. --author Yalnızca yazarın adının belirli bir karakter katarıyla (_string_) eşleşen kayıtları göster. --committer Yalnızca kaydedenin adının belirli bir karakter katarıyla eşleştiği kayıtları göster. @@ -628,7 +628,7 @@ Kayıt tarihçenizi görüntülemek için görselliği daha çok ön planda olan Insert 18333fig0202.png Figür 2-2. gitk grafiklse tarihçe görüntüleyicisi. -Pencerenin üst yarısında bir kalıtım grafiğinin yanısıra kayıt tarihçesini görebilirsiniz. Alttaki kayıt içeriği görüntüleyicisi, tıkladığınız herhangi bir kayıttaki değişiklikleri gösterecektir. +Pencerenin üst yarısında bir kalıtım grafiğinin yanı sıra kayıt tarihçesini görebilirsiniz. Alttaki kayıt içeriği görüntüleyicisi, tıkladığınız herhangi bir kayıttaki değişiklikleri gösterecektir. ## Değişiklikleri Geri Almak ## @@ -708,19 +708,19 @@ Yaptığınız değişiklikleri nasıl çöpe atabileceğinizi açıkça söylü # modified: README.txt # -Gördüğünüz gibi değişiklikler çöpe atıldı. Bunun tehlikeli bir komut olduğunu aklınızdan çıkarmayın: o dosyaya yaptığınız bütün değişiklikler şimdi yok oldu —dosyanın üstüne yeni bir dosya kopyaladınız. Eğer dosyadaki değişiklikleri isteemediğinizden yüzde yüz emin değilseniz asla bu komutu kullanmayın. Eğer sorun bu dosyada yaptığınız değişikliklerin başka işlemler yapmanıza engel olması ise bir sonraki bölümde ele alacağımız zulalama (_stash_) ve dallandırma (_branch_) işlemlerini kullanmanız daha iyi olacaktır. +Gördüğünüz gibi değişiklikler çöpe atıldı. Bunun tehlikeli bir komut olduğunu aklınızdan çıkarmayın: o dosyaya yaptığınız bütün değişiklikler şimdi yok oldu —dosyanın üstüne yeni bir dosya kopyaladınız. Eğer dosyadaki değişiklikleri istemediğinizden yüzde yüz emin değilseniz asla bu komutu kullanmayın. Eğer sorun bu dosyada yaptığınız değişikliklerin başka işlemler yapmanıza engel olması ise bir sonraki bölümde ele alacağımız zulalama (_stash_) ve dallandırma (_branch_) işlemlerini kullanmanız daha iyi olacaktır. Unutmayın, Git'te kaydedilmiş her şey neredeyse her zaman kurtarılabilir. Silinmiş dallardaki kayıtlar ve hatta `--amend` seçeneğiyle üzerine yazılmış kayıtlar bile kurtarılabilirler (veri kurtarma konusunda bkz. _9. Bölüm_). Diğer taraftan, kaydedilmemiş bir değişikliği kaybederseniz büyük olasılıkla onu kurtarmanız mümkün olmaz. ## Uzak Uçbirimlerle Çalışmak ## -Bir Git projesine katkıda bulunabilmek için uzaktaki yazılım havuzlarını nasıl düzenleyeceğinizi bilmeniz gerekir. Uzaktaki yazılım havuzları, projenizin Internet'te ya da başka bir ağda barındırılan sürümleridir. Birden fazla uzak yazılım havuzunuz olabilir, bunlardan herbiri sizin için ya salt okunur ya da okunur/yazılır durumdadır. Başkalarıyla ortak çalışmak, bu yazılım havuzlarını düzenlemeyi, onlardan veri çikip (_pull_) onlara veri iterek (_push_) çalışmalarınızı paylaşmayı gerektirir. +Bir Git projesine katkıda bulunabilmek için uzaktaki yazılım havuzlarını nasıl düzenleyeceğinizi bilmeniz gerekir. Uzaktaki yazılım havuzları, projenizin İnternet'te ya da başka bir ağda barındırılan sürümleridir. Birden fazla uzak yazılım havuzunuz olabilir, bunlardan her biri sizin için ya salt okunur ya da okunur/yazılır durumdadır. Başkalarıyla ortak çalışmak, bu yazılım havuzlarını düzenlemeyi, onlardan veri çekip (_pull_) onlara veri iterek (_push_) çalışmalarınızı paylaşmayı gerektirir. Uzaktaki yazılım havuzlarınızı düzenleyebilmek için, projenize uzak yazılım havuzlarının nasıl ekleneceğini, kullanılmayan havuzların nasıl çıkarılacağını, çeşitli uzak dalları düzenlemeyi ve onların izlenen dallar olarak belirleyip belirlememeyi ve daha başka şeyleri gerektirir. Bu alt bölümde bu uzağı yönetme yeteneklerini inceleyeceğiz. ### Uzak Uçbirimleri Görüntüleme ### -Projenizde hangi uzak sunucuları ayarladığınınızı görme için `git remote` komutunu kullanabilirsiniz. Bu komut, herbir uzak uçbirimin belirlenmiş kısa adını görüntüler. Eğer yazılım havuzunuzu bir yerden klonlamışsanız, en azından _origi_ uzak uçbirimini görmelisiniz —bu Git'in klonlamanın yapıldığı sunucuya verdiği öntanımlı addır. +Projenizde hangi uzak sunucuları ayarladığınızı görme için `git remote` komutunu kullanabilirsiniz. Bu komut, her bir uzak uçbirimin belirlenmiş kısa adını görüntüler. Eğer yazılım havuzunuzu bir yerden klonlamışsanız, en azından _origin_ uzak uçbirimini görmelisiniz —bu Git'in klonlamanın yapıldığı sunucuya verdiği öntanımlı addır. $ git clone git://github.com/schacon/ticgit.git Initialized empty Git repository in /private/tmp/ticgit/.git/ @@ -748,7 +748,7 @@ Projenizde birden çok uzak uçbirim varsa, bu komut hepsini listeleyecektir. Ö koke git://github.com/koke/grit.git origin git@github.com:mojombo/grit.git -Bu demek oluyor ki bu kullanıcıların herhangi birinden kolaylıkla çekme işlemi (_pull_) yapabiliriz. Fakat dikkat ederseniz, yalnızca _origin_ uçbiriminin SSH URL'si var, yani yalnızca o hazuva kod itebilirim (_push_) (niye böyle olduğunu _4. Bölüm_'de inceleyeceğiz) +Bu demek oluyor ki bu kullanıcıların herhangi birinden kolaylıkla çekme işlemi (_pull_) yapabiliriz. Fakat dikkat ederseniz, yalnızca _origin_ uçbiriminin SSH URL'si var, yani yalnızca o havuza kod itebiliriz (_push_) (niye böyle olduğunu _4. Bölüm_'de inceleyeceğiz) ### Uzak Uçbirimler Eklemek ### @@ -778,11 +778,11 @@ Paul'ün `mastertr` dalı sizin yazılım havuzunuzda da `pb/master` olarak eri Biraz önce gördüğünüz gibi, uzaktaki yazılım havuzlarından veri almak için şu komutu kullanabilirsiniz: - $ git fetch [remote-name] + $ git fetch [uzak-sunucu-adı] -Bu komut, söz konusu uzaktaki yazılım havuuzna gidip orada bulunup da sizin projenizde bulunmayan bütün veriyi getirir. Bunu yaptıktan sonra sizin projenizde o uzak yazılım havuzundaki bütün dallarak referanslar oluşur —ki bunları birleştirme yapmak ya da içeriği incelemek için kullanabilirsiniz. (Dalların ne olduğunu ve onları nasıl kullanabileceğinizi _3. Bölüm_'de ayrınlıtı biçimde inceleyeceğiz.) +Bu komut, söz konusu uzaktaki yazılım havuzuna gidip orada bulunup da sizin projenizde bulunmayan bütün veriyi getirir. Bunu yaptıktan sonra sizin projenizde o uzak yazılım havuzundaki bütün dallara referanslar oluşur —ki bunları birleştirme yapmak ya da içeriği incelemek için kullanabilirsiniz. (Dalların ne olduğunu ve onları nasıl kullanabileceğinizi _3. Bölüm_'de ayrıntılı biçimde inceleyeceğiz.) -Bir yazılım havuzunu klonladığınızda, klonlama komutu söz konusu kaynak yazılım havuzunu _origin_ adıyla uzak uçbirimler arasına ekler. Dolayısıya, `git fetch origin` komutu, klonlamayı yaptığınızdan (ya da en son getirme işlemini (_fetch_) yatığınızdan) beri sunucuya itilmiş yeni değişiklikleri getirir. Unutmayın, `fetch` komutu veriyi yeler yazılım havuzunuza indirir —otomatik olarak sizin yaptıklarınızla birleştirmeye, ya da çalıştığınız şeyler üzerinde değişiklik yapmaya kalkışmaz. Hazır olduğunuzda birleştirme işlemini sizin yapmanız gerekir. +Bir yazılım havuzunu klonladığınızda, klonlama komutu söz konusu kaynak yazılım havuzunu _origin_ adıyla uzak uçbirimler arasına ekler. Dolayısıyla, `git fetch origin` komutu, klonlamayı yaptığınızdan (ya da en son getirme işlemini (_fetch_) yatığınızdan) beri sunucuya itilmiş yeni değişiklikleri getirir. Unutmayın, `fetch` komutu veriyi yeler yazılım havuzunuza indirir —otomatik olarak sizin yaptıklarınızla birleştirmeye, ya da çalıştığınız şeyler üzerinde değişiklik yapmaya kalkışmaz. Hazır olduğunuzda birleştirme işlemini sizin yapmanız gerekir. Uzaktaki bir dalı izlemek üzere ayarlanmış bir dalınız varsa (daha fazla bilgi için sonraki alt bölüme ve _3. Bölüm_'e bakınız) bu dal üzerinde `git pull` komutunu kullanarak uzaktaki yazılım havuzundaki veriyi hem getirip hem de mevcut dalınızla birleştirebilirsiniz. Bu çalışması daha kolay bir düzen olabilir; bu arada, `git clone ` komutu, otomatik olarak, yerel yazılım havuzunuzda, uzaktaki yazılım havuzunun `master` dalını takip eden bir `master` dalı oluşturur (uzaktaki yazılım havuzunun `master` adında bir dalı olması koşuluyla). `git pull` komutu genellikle yereldeki yazılım havuzunuza kaynaklık eden sunucudan veriyi getirip otomatik olarak üzerinde çalışmakta olduğunuz dalla birleştirir. @@ -792,7 +792,7 @@ Projeniz paylaşmak istediğiniz bir hale geldiğinde, yaptıklarınızı kayna $ git push origin master -Bu komut, yalnızca yazma yetkisine sahip olduğunuz bir sunucudan klonlama yapmışsanız ve son getirme işleminizden beri hiçkimse itme işlemi yapmamışsa istediğiniz sonucu verir. Eğer sizinle birlikte bir başkası daha klonlama yapmışsa ve o kişi sizden önce itme yapmışsa, sizin itme işleminiz reddedilir. İtmeden önce sizden önce itilmiş değişiklikleri çekip kendi çalışmanızla birleştirmeniz gerekir. Uzaktaki yazılım havuzlarına itme yapmak konusunda daha ayrıntılı bilgi için bkz. _3. Bölüm_. +Bu komut, yalnızca yazma yetkisine sahip olduğunuz bir sunucudan klonlama yapmışsanız ve son getirme işleminizden beri hiç kimse itme işlemi yapmamışsa istediğiniz sonucu verir. Eğer sizinle birlikte bir başkası daha klonlama yapmışsa ve o kişi sizden önce itme yapmışsa, sizin itme işleminiz reddedilir. İtmeden önce sizden önce itilmiş değişiklikleri çekip kendi çalışmanızla birleştirmeniz gerekir. Uzaktaki yazılım havuzlarına itme yapmak konusunda daha ayrıntılı bilgi için bkz. _3. Bölüm_. ### Uzak Uçbirim Hakkında Bilgi Almak ### @@ -833,11 +833,11 @@ Yukarıdaki verdiğimiz, basit bir örnekti. Git'i daha yoğun biçimde kulland Local branch pushed with 'git push' master:master -Bu çıktı, belirli dallarda `git push` komutunu çalıştırdığınızda hangi dalların otomatik olarak itileceğini gösteriyor. Buna ek olarak uzak uçbirimde bulunup da sizin projenizde henüz bulunmayan uzak dalları, uzak uçbirimden silinmiş olduuğu halde sizin projenizde bulunan dalları ve `git pull` komutunu çalıştırdığınızda otomatik olarak birleştirme işlemine uğrayacak birden çok daı gösteriyor. +Bu çıktı, belirli dallarda `git push` komutunu çalıştırdığınızda hangi dalların otomatik olarak itileceğini gösteriyor. Buna ek olarak uzak uçbirimde bulunup da sizin projenizde henüz bulunmayan uzak dalları, uzak uçbirimden silinmiş olduğu halde sizin projenizde bulunan dalları ve `git pull` komutunu çalıştırdığınızda otomatik olarak birleştirme işlemine uğrayacak birden çok dalı gösteriyor. ### Uzan Uçbirimleri Kaldırmak ve Yeniden Adlandırmak ### -Bir uçbirimin kısa adını değiştirmek isterseniz, Git'in yeni sürümlerinde bunu `git remote rename` komutuyla yapabilirsiniz. Örneğin, `pb` uçbirimini `paul` diye yeniden adlandımak isterseniz, bunu `git remote rename`'i kullanarak yapabilirsiniz: +Bir uçbirimin kısa adını değiştirmek isterseniz, Git'in yeni sürümlerinde bunu `git remote rename` komutuyla yapabilirsiniz. Örneğin, `pb` uçbirimini `paul` diye yeniden adlandırmak isterseniz, bunu `git remote rename`'i kullanarak yapabilirsiniz: $ git remote rename pb paul $ git remote @@ -846,7 +846,7 @@ Bir uçbirimin kısa adını değiştirmek isterseniz, Git'in yeni sürümlerind Bu işlemin uçbirim dal adlarını da değiştirdiğini hatırlatmakta yarar var. Bu işlemden önce `pb/master` olan dalın adı artık `paul/master` olacaktır. -Bir uçbirim referansını herhangi bir nedenle —sunucuyu taşımış ya da belirli bir yansısyı artık kullanmıyor olabilirsiniz; ya da belki katılımcılardan birisi artık katkıda bulunmuyordur— kaldırmak isterseniz `git remote rm` komutunu kullanabilirsiniz: +Bir uçbirim referansını herhangi bir nedenle —sunucuyu taşımış ya da belirli bir yansıyı artık kullanmıyor olabilirsiniz; ya da belki katılımcılardan birisi artık katkıda bulunmuyordur— kaldırmak isterseniz `git remote rm` komutunu kullanabilirsiniz: $ git remote rm paul $ git remote @@ -856,7 +856,7 @@ Bir uçbirim referansını herhangi bir nedenle —sunucuyu taşımış ya da be Çoğu SKS gibi Git'in de tarihçedeki belirli noktaları önemli olarak etiketleyebilme özelliği vardır. Genellikle insanlar bu işlevi sürümleri (`v1.0`, vs.) işaretlemek için kullanırlar. Bu alt bölümde mevcut etiketleri nasıl listeleyebileceğinizi, nasıl yeni etiketler oluşturabileceğinizi ve değişik etiket tiplerini öğreneceksiniz. -### Listing Your Tags ### +### Etiketlerinizi Listeleme ### Git'te mevcut etiketleri listeleme işi epeyi kolaydır. `git tag` yazmanız yeterlidir: @@ -876,19 +876,19 @@ Bu komut etiketleri alfabetik biçimde sıralar; etiketlerin sırasının bir ö ### Etiket Oluşturma ### -Git iki başlıca etiket tipi kullanır: hafif ve açıklamalı. Hafif etiketler hiç değişmeyen dallar gibidir —belirli bir kaydı işaret ederler. Öte yandan, açıklamalı etiketler, Git veritabanında bütünlüklü nesneler olarak kaydedilirler. Sınama toplamları alınır; etiketleyenin adını ve e-posta adresini içerirler; bir etiket mesajına sahiptirler ve GNU Privacy Guard (GPG) kullanılarak imzalanıp doğrulanabilirler. Genelllikle bütün bu bilgilere ulaşılabilmesini olanaklı kılabilmek için açıklamalı etiketlerin kullanılması önerilir, ama bütün bu bilgileri depolamadan yalnızca geçici bir etiket oluşturmak istiyorsanız, hafif etiketleri de kullanabilirsiniz. +Git iki başlıca etiket tipi kullanır: hafif ve açıklamalı. Hafif etiketler hiç değişmeyen dallar gibidir —belirli bir kaydı işaret ederler. Öte yandan, açıklamalı etiketler, Git veritabanında bütünlüklü nesneler olarak kaydedilirler. Sınama toplamları alınır; etiketleyenin adını ve e-posta adresini içerirler; bir etiket mesajına sahiptirler ve GNU Privacy Guard (GPG) kullanılarak imzalanıp doğrulanabilirler. Genellikle bütün bu bilgilere ulaşılabilmesini olanaklı kılabilmek için açıklamalı etiketlerin kullanılması önerilir, ama bütün bu bilgileri depolamadan yalnızca geçici bir etiket oluşturmak istiyorsanız, hafif etiketleri de kullanabilirsiniz. ### Açıklamalı Etiketler ### -Git'te açıklamalı etiket oluşturmak basittir. En kolayı `tag` komutunu çalıştırıren `-a` seçeneğini kullanmaktır: +Git'te açıklamalı etiket oluşturmak basittir. En kolayı `tag` komutunu çalıştırırken `-a` seçeneğini kullanmaktır: - $ git tag -a v1.4 -m 'my version 1.4' + $ git tag -a v1.4 -m 'sürümüm 1.4' $ git tag v0.1 v1.3 v1.4 -`-m` seçeneği etketle birlikte depolanacak etiketleme mesajını belirlemek için kullanılır. Açıklamalı bir etiket için mesajı bu şekilde belirlemezseniz, Git mesajı yazabilmeniz için bir editör açacaktır. +`-m` seçeneği etiketle birlikte depolanacak etiketleme mesajını belirlemek için kullanılır. Açıklamalı bir etiket için mesajı bu şekilde belirlemezseniz, Git mesajı yazabilmeniz için bir editör açacaktır. `git show` komutunu kullanarak etiketlenen kayıtla birlikte etikete ilişkin verileri de görebilirsiniz: @@ -905,13 +905,13 @@ Git'te açıklamalı etiket oluşturmak basittir. En kolayı `tag` komutunu çal Merge branch 'experiment' -Bu, kayıt bilgisinden önce etiketlenyenle ilgili bilgileri, kaydın etiketlendiği tarihi ve açıklama mesajını gösterir. +Bu, kayıt bilgisinden önce etiketleyenle ilgili bilgileri, kaydın etiketlendiği tarihi ve açıklama mesajını gösterir. ### İmzalı Etiketler ### Eğer bir kişisel anahtarınız (_private key_) varsa etiketlerinizi GPG ile imzalayabilirsiniz. Yapmanız gereken tek şey `-a` yerine `-s` seçeneğini kullanmaktır: - $ git tag -s v1.5 -m 'my signed 1.5 tag' + $ git tag -s v1.5 -m 'imzalı 1.5 etiketim' You need a passphrase to unlock the secret key for user: "Scott Chacon " 1024-bit DSA key, ID F721C45A, created 2009-02-09 @@ -923,7 +923,7 @@ Bu etiket üzerinde `git show` komutunu çalıştırırsanız, GPG imzasını da Tagger: Scott Chacon Date: Mon Feb 9 15:22:20 2009 -0800 - my signed 1.5 tag + imzalı 1.5 etiketim -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.8 (Darwin) @@ -980,7 +980,7 @@ Kayıtları etiketlemenin bir yolu da hafif etiketler kullanmaktır. Bu, kayıt gpg: aka "[jpeg image of size 1513]" Primary key fingerprint: 3565 2A26 2040 E066 C9A7 4A7D C0C6 D9A4 F311 9B9A -If you don’t have the signer’s public key, you get something like this instead: +Eğer imzalayıcının genel anahtarına sahip değilseniz, bunun yerine aşağıdakine benzer bir şey göreceksiniz: gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A gpg: Can't check signature: public key not found @@ -1031,7 +1031,7 @@ Kaydın etiketlendiğini göreceksiniz: ### Etiketleri Paylaşmak ### -Aksi belirtilmedikçe `git push` komutu etiketleri uzak uçbirimelere aktarmaz. Etiketleri belirtik biçimde bir ortak sunucuya itmeniz gerekir. Bu süreç uçbirim dallarını paylaşmaya benzer —`git push origin [etiket-adi]` komutunu çalıştırabilirsiniz. +Aksi belirtilmedikçe `git push` komutu etiketleri uzak uçbirimlere aktarmaz. Etiketleri belirtik biçimde bir ortak sunucuya itmeniz gerekir. Bu süreç uçbirim dallarını paylaşmaya benzer —`git push origin [etiket-adi]` komutunu çalıştırabilirsiniz. $ git push origin v1.5 Counting objects: 50, done. @@ -1059,11 +1059,11 @@ Artık başka biri sizin yazılım havuzunuzdan çekme yaptığında, bütün et ## İpuçları ## -Git'in temelleri hakkındaki bu bölümü tamamlamadan önce, Git deneyiminizi kolaylaştırabilmek için birkaç ipucu vermekte yarar var. Pekçok insan Git'i bu ipuçlarına başvurmadan kullanıyor; bu ipuçlarından ileride tekrar söz etmeyeceğimiz gibi bunları bilmeniz gereltiğini de varsaymıyoruz; ama yine de bilmeniz yararınıza olacaktır. +Git'in temelleri hakkındaki bu bölümü tamamlamadan önce, Git deneyiminizi kolaylaştırabilmek için birkaç ipucu vermekte yarar var. Pek çok insan Git'i bu ipuçlarına başvurmadan kullanıyor; bu ipuçlarından ileride tekrar söz etmeyeceğimiz gibi bunları bilmeniz gerektiğini de varsaymıyoruz; ama yine de bilmeniz yararınıza olacaktır. ### Otomatik Tamamlama ### -Eğer Bash -shell_'ini kullanıyorsanız, Git'in otomatik tamamlama betiğini (_script_) kullanabilirsiniz. Git kaynak kodunu indirip `contrib/completion` klasörüne bakın; orada `git-completion.bash` adında bir dosya olmalı. Bu dosyayı ana dizininize (_home_) kopyalayıp `.bashrc` dosyanıza ekleyin: +Eğer Bash -shell_'ini kullanıyorsanız, Git'in otomatik tamamlama betiğini (_script_) kullanabilirsiniz. Git kaynak kodunu indirip `contrib/completion` klasörüne bakın; orada `git-completion.bash` adında bir dosya olmalı. Bu dosyayı ev dizininize (_home_) kopyalayıp `.bashrc` dosyanıza ekleyin: source ~/.git-completion.bash @@ -1071,23 +1071,23 @@ Otomatik tamamlama özelliğinin bütün Git kullanıcıları için geçerli olm Eğer bir Windows kullanıcısıysanız ve Git Bash kullanıyorsanız- ki bu msysGit'le kurulum yaptığınızdaki öntanımlı programdır, otomatik tamamlama kendiliğinden gelecektir. -Bir Git komutu yazarken Tab tuşuna bastığınızda, karşınıza bir dizi seçenek getirir: +Bir Git komutu yazarken Sekme tuşuna bastığınızda, karşınıza bir dizi seçenek getirir: - $ git co + $ git co commit config -Bu örnekte, `git co` yazıp Tab tuşuna iki kez basmak `commit` ve `config` komutlarını öneriyor. Komutun devamında `m` yazıp bir kez daha Tab tuşuna basacak olursanız, komut otomatik olarak `git commit`'e tamamlanır. +Bu örnekte, `git co` yazıp Sekme tuşuna iki kez basmak `commit` ve `config` komutlarını öneriyor. Komutun devamında `m` yazıp bir kez daha Sekme tuşuna basacak olursanız, komut otomatik olarak `git commit`'e tamamlanır. -Bu, seçeneklerde de kullanılabilir, ki muhtemelen daha yararlı olacaktır. Örneğin, `git log` komutunu çalıştırıren seçeneklerden birisini hatırlayamadınız, seçeneği yazmaya başlayıp Tab tuşuna basarak eşleşen seçenekleri görebilirsiniz: +Bu, seçeneklerde de kullanılabilir, ki muhtemelen daha yararlı olacaktır. Örneğin, `git log` komutunu çalıştırırken seçeneklerden birisini hatırlayamadınız, seçeneği yazmaya başlayıp Sekme tuşuna basarak eşleşen seçenekleri görebilirsiniz: - $ git log --s + $ git log --s --shortstat --since= --src-prefix= --stat --summary -Bu güzel özellik sizi zaman kazandırabileceği gibi ikide bir dokümantasyona bakma gereğini de ortadan kaldırır. +Bu güzel özellik sizi zaman kazandırabileceği gibi ikide bir belgelendirmeye bakma gereğini de ortadan kaldırır. ### Takma Adlar ### -Bir komutun bir kısmını yazdığınızda Git bunu anlamayacaktır. Komutların uzun adlarını kullanmak istemezseniz, `git cofig` komutunu kullanarak bunların yerine daha kısa takma adlar belirleyebilirsiniz. Kullanmak isteyebileceğiniz bazı takma adları buraya aldık: +Bir komutun bir kısmını yazdığınızda Git bunu anlamayacaktır. Komutların uzun adlarını kullanmak istemezseniz, `git config` komutunu kullanarak bunların yerine daha kısa takma adlar belirleyebilirsiniz. Kullanmak isteyebileceğiniz bazı takma adları buraya aldık: $ git config --global alias.co checkout $ git config --global alias.br branch @@ -1105,7 +1105,7 @@ Bu durumda şu iki komut eşdeğer olacaktır: $ git unstage fileA $ git reset HEAD fileA -Biraz daha temiz değil mi? Bir `last` komutu ekleek de oldukça yaygındır: +Biraz daha temiz değil mi? Bir `last` komutu eklemek de oldukça yaygındır: $ git config --global alias.last 'log -1 HEAD' @@ -1120,7 +1120,7 @@ Böylece son kaydı kolaylıkla görebilirsiniz: Signed-off-by: Scott Chacon -Gördüğünüz gibi Git yeni komutu takma ad olarak belirlediğini şeyin yerine kullanıyor. Ama belki de bir Git komutu çalıştırmak değil de başka br program kullanmak istiyorsunuz. Bu durumda komutun başına `!` karakterini koymalısınız. Bir Git yazılım havuzu üzerinde çalışan kendi araçlarınızı yazıyorsanız bu seçenek yararlı olabilir. Bunu göstermek için ,`gitk`'yi çalıştırmak için `git visual` diye yeni bir takma ad tanımlayabiliriz: +Gördüğünüz gibi Git yeni komutu takma ad olarak belirlediğini şeyin yerine kullanıyor. Ama belki de bir Git komutu çalıştırmak değil de başka bir program kullanmak istiyorsunuz. Bu durumda komutun başına `!` karakterini koymalısınız. Bir Git yazılım havuzu üzerinde çalışan kendi araçlarınızı yazıyorsanız bu seçenek yararlı olabilir. Bunu göstermek için ,`gitk`'yi çalıştırmak için `git visual` diye yeni bir takma ad tanımlayabiliriz: $ git config --global alias.visual '!gitk' From 2e25a156086d27d312cb91284b37c30f9bc34354 Mon Sep 17 00:00:00 2001 From: Volkan Gezer Date: Thu, 12 Dec 2013 17:32:43 +0100 Subject: [PATCH 070/862] Fix typos --- tr/03-git-branching/01-chapter3.markdown | 68 ++++++++++++------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/tr/03-git-branching/01-chapter3.markdown b/tr/03-git-branching/01-chapter3.markdown index f2aedb127..f897e8ea2 100644 --- a/tr/03-git-branching/01-chapter3.markdown +++ b/tr/03-git-branching/01-chapter3.markdown @@ -2,22 +2,22 @@ Neredeyse her SKS'nin bir dallanma (_branching_) işlevi vardır. Dallanma, ana geliştirme çizgisinden sapmak ve işinizi o ana geliştirme çizgisine bulaşmadan devam ettirmek anlamına gelir. Çoğu SKS aracında bu pahalı bir süreçtir; kaynak kod klasörünüzün yeni bir kopyasını yapmanızı gerektirir ve büyük projelerde çok zaman alır. -Bazıları Git'in dallanma modelinin onun "en vurucu özelliği" olduğunu söylerler; bu özelliğin SKS topluluğu içinde Git'i ayrı bir yere koyduğu doğrudur. Onu bu kadar özel yapan nedir? Git'te dallanmalar çok kolay ve neredeyse anlıktır, üstelik farklı dallar arasında gidip gelmek de bir o kadar hızlıdır. Çoğu SKS'den farklı olarak Git dallanma ve birleştirmenin (_merge_) sık (belki de günde birkaç kez) gerçekleşeceği bir iş akışını teşvik eder. Bu özelliği anlayıp bu konuda ustalaşmak size son derece becerikli ve eşsiz bir araç sağlayabileceği gibi çalışma biçiminizi de bütnüyle değiştirebilir. +Bazıları Git'in dallanma modelinin onun "en vurucu özelliği" olduğunu söylerler; bu özelliğin SKS topluluğu içinde Git'i ayrı bir yere koyduğu doğrudur. Onu bu kadar özel yapan nedir? Git'te dallanmalar çok kolay ve neredeyse anlıktır, üstelik farklı dallar arasında gidip gelmek de bir o kadar hızlıdır. Çoğu SKS'den farklı olarak Git dallanma ve birleştirmenin (_merge_) sık (belki de günde birkaç kez) gerçekleşeceği bir iş akışını teşvik eder. Bu özelliği anlayıp bu konuda ustalaşmak size son derece becerikli ve eşsiz bir araç sağlayabileceği gibi çalışma biçiminizi de bütünüyle değiştirebilir. ## Dal Nedir? ## -Git'in dallanma ilemini nasıl yaptığını gerçekten anlayabilmek için geriye doğru bir adım atıp Git'in verilerini nasıl depoladığına bakmamız gerekiyor. 1. Bölüm'den hatırlayabileceğiniz üzere, Git verilerini bir dizi değişiklik olarak değil bir dizi bellek kopyası olarak depolar. +Git'in dallanma işlemini nasıl yaptığını gerçekten anlayabilmek için geriye doğru bir adım atıp Git'in verilerini nasıl depoladığına bakmamız gerekiyor. 1. Bölüm'den hatırlayabileceğiniz üzere, Git verilerini bir dizi değişiklik olarak değil bir dizi bellek kopyası olarak depolar. Git'te bir kayıt yaptığınızda, Git, kayda hazırladığınız içeriğin bellek kopyasına işaret eden imleci, yazar ve mesaj üstverisini ve söz konusu kaydın atalarını gösteren sıfır ya da daha fazla imleci (ilk kayıt için sıfır ata, normal bir kayıt için bir ata, iki ya da daha fazla dalın birleştirilmesinden oluşan bir kayıt için birden çok ata) içeren bir kayıt nesnesini depolar. -Bunu görselleştirmek için, üç dosyadan oluşan bir klasörünüzün olduğunu ve bu üç dosyayı da kayıt için hazırladığınızı varsayalım. Dosyaları kayda hazırlamak herbir dosyanın sınama toplamını alır (1. Bölüm'de söz ettiğimiz SHA-1 özeti), dosyanın o sürümünü Git yazılım havuzunda depolar (Git'te bunlara _blob_ denir (Ç.N. _blob_ Türkçeye damla ya da topak diye çevrileblir, fakat kelimeyi olduğu gibi kullanmanın daha anlaşılır olacağını düşündük.)) ve sınama toplamını hazırlık alanına ekler: +Bunu görselleştirmek için, üç dosyadan oluşan bir klasörünüzün olduğunu ve bu üç dosyayı da kayıt için hazırladığınızı varsayalım. Dosyaları kayda hazırlamak her bir dosyanın sınama toplamını alır (1. Bölüm'de söz ettiğimiz SHA-1 özeti), dosyanın o sürümünü Git yazılım havuzunda depolar (Git'te bunlara _blob_ denir (Ç.N. _blob_ Türkçe'ye damla ya da topak diye çevrilebilir, fakat kelimeyi olduğu gibi kullanmanın daha anlaşılır olacağını düşündük.)) ve sınama toplamını hazırlık alanına ekler: $ git add README test.rb LICENSE $ git commit -m 'initial commit of my project' `git commit` komutunu çalıştırarak bir kayıt oluşturduğunuzda, Git her bir alt klasörün (bu örnekte yalnızca kök klasörün) sınama toplamını alır ve bu ağaç yapısındaki bu nesneleri yazılım havuzunda depolar. Git, daha sonra, üst veriyi ve ihtiyaç duyulduğunda bellek kopyasının yeniden yaratabilmek için ağaç yapısındaki nesneyi gösteren bir imleci içeren bir kayıt nesneyi yaratır. -Şimdi, Git yazılım havuzunuzda beş nesne bulunuyor: üç dosyanızın herbiri için bir içerik _blob_'u, klasörün içeriğini listeleyen ve hangi dosyanın hangi _blob_'da depolandığı bilgisini içeren bir ağaç nesnesi ve o ağaç nesnesini gösteren bir imleci ve bütün kayıt üstverisini içeren bir kayıt nesnesi. Kavramsal olarak, Git yazılım havuzunuzdaki veri Figür 3-1'deki gibi görünür. +Şimdi, Git yazılım havuzunuzda beş nesne bulunuyor: üç dosyanızın her biri için bir içerik _blob_'u, klasörün içeriğini listeleyen ve hangi dosyanın hangi _blob_'da depolandığı bilgisini içeren bir ağaç nesnesi ve o ağaç nesnesini gösteren bir imleci ve bütün kayıt üstverisini içeren bir kayıt nesnesi. Kavramsal olarak, Git yazılım havuzunuzdaki veri Figür 3-1'deki gibi görünür. Insert 18333fig0301.png Figür 3-1. Tek kayıtlı yazılım havuzundaki veri. @@ -27,10 +27,10 @@ Yeniden değişiklik yapıp kaydederseniz, yeni kayıt kendisinden hemen önce g Insert 18333fig0302.png Figür 3-2. Birden çok kayıt sonunda Git nesne verisi. -Git'te bir dal, bu kayıtlardan birine işaret eden, yer değiştirebilen kıvrak bir imleçten ibarettir. Git'teki varsayılan dal adı `master`'dır. İlk kaydı yaptığınızda, son yatığınız kaydı gösteren bir `master` dalına sahip olursunuz. Her kayıt yaptığınızda dal otomatik olarak son kaydı göstermek üzere hareket eder. +Git'te bir dal, bu kayıtlardan birine işaret eden, yer değiştirebilen kıvrak bir imleçten ibarettir. Git'teki varsayılan dal adı `master`'dır. İlk kaydı yaptığınızda, son yaptığınız kaydı gösteren bir `master` dalına sahip olursunuz. Her kayıt yaptığınızda dal otomatik olarak son kaydı göstermek üzere hareket eder. Insert 18333fig0303.png -Figür 3-3. Dalkayıt verisinin tarihçesini gösteriyor. +Figür 3-3. Dal kayıt verisinin tarihçesini gösteriyor. Yeni bir dal oluşturduğunuzda ne olur? Yeni kayıtlarla ilerlemenizi sağlayan yeni bir imleç yaratılır. Söz gelimi, `testing` adında yeni bir dal oluşturalım. Bunu, `git branch` komutuyla yapabilirsiniz: @@ -89,9 +89,9 @@ Figür 3-9. Dal tarihçeleri birbirinden ıraksadı. Git'te bir dal işaret ettiği kaydın 40 karakterlik SHA-1 sınama toplamını içeren basit bir dosyadan ibaret olduğu için dalları yaratmak ve yok etmek oldukça masrafsızdır. Yeni bir dal yaratmak bir dosyaya 41 karakter (40 karakter ve bir satır sonu) yazmak kadar hızlıdır. -Bu, çoğu SKS'nin bütün proje dosyalarını yeni bir klasöre kopyalamayı gerektiren dallanma yaklaşımıyla keskin bir karşıtlık içindedir. Söz konusu yaklaşımda projenin boyutlarına bağlı olarak dallanma saniyeler, hatta dakikalar sürebilir; Git'te ise bu süreç her zaman anlıktır. Ayrıca, kayıt yaparken ata kayıtları da kaydettiğimiz için birleştirme sırasında uygun bir ortak payda bulma işi de otomatik olarak ve genellikle oldukça kolayca halledilir. Bu özellikler yazılımcıları sık sık dal yaratıp kullanmaya teşşvik eder. +Bu, çoğu SKS'nin bütün proje dosyalarını yeni bir klasöre kopyalamayı gerektiren dallanma yaklaşımıyla keskin bir karşıtlık içindedir. Söz konusu yaklaşımda projenin boyutlarına bağlı olarak dallanma saniyeler, hatta dakikalar sürebilir; Git'te ise bu süreç her zaman anlıktır. Ayrıca, kayıt yaparken ata kayıtları da kaydettiğimiz için birleştirme sırasında uygun bir ortak payda bulma işi de otomatik olarak ve genellikle oldukça kolayca halledilir. Bu özellikler yazılımcıları sık sık dal yaratıp kullanmaya teşvik eder. -Neden böyle olması gerektiğine yaından bakalım. +Neden böyle olması gerektiğine yakından bakalım. ## Dallanma ve Birleştirmenin Temelleri ## @@ -145,7 +145,7 @@ Ama, bunu yapmadan önce şunu belirtmekte yarar var: eğer çalışma klasörü $ git checkout master Switched to branch "master" -Bu noktada, çalışma klasörünüz #53 numaralı sorun üzerinde çalışmaya başlamadan hemen önceki halindedir ve yamayı hazırlamaya odaklanabilirsiniz. Burası önemli: Git, çalışma klasörünüzü seçtiğiniz dalın gösterdiği kaydın bellek kopyasıyla aynı olacak şekilde ayarlar. Dal, son kaydınızda nasıl görünüyorsa çalışma klasörünü o hale getirbilmek için otomatik olarak dosyaları ekler, siler ve değiştirir. +Bu noktada, çalışma klasörünüz #53 numaralı sorun üzerinde çalışmaya başlamadan hemen önceki halindedir ve yamayı hazırlamaya odaklanabilirsiniz. Burası önemli: Git, çalışma klasörünüzü seçtiğiniz dalın gösterdiği kaydın bellek kopyasıyla aynı olacak şekilde ayarlar. Dal, son kaydınızda nasıl görünüyorsa çalışma klasörünü o hale getirebilmek için otomatik olarak dosyaları ekler, siler ve değiştirir. Sırada, hazırlanacak yama var. Şimdi yama üzerinde çalışmak için bir `hotfix` dalı oluşturalım (bkz. Figür 3-13): @@ -196,7 +196,7 @@ Figür 3-15. iss53 dalınız bağımsız olarak ilerleyebilir. ### Birleştirmenin Temelleri ### -Diyelim ki #53 numaralı sorunla ilgili çalışmanızı tamamladınız ve `master` dalıyla birleştirmeye hazırsınız. Bunu yapabilmek için `iss53` dalınızı, aynı `hotfiz` dalını yaptığınız gibi birleştireceksiniz. Bütün yapmanız gereken birleştirmeyi gerçekleştirmek istediğiniz dalı seçmek (_checkout_) ve `git merge` komutunu çalıştırmak: +Diyelim ki #53 numaralı sorunla ilgili çalışmanızı tamamladınız ve `master` dalıyla birleştirmeye hazırsınız. Bunu yapabilmek için `iss53` dalınızı, aynı `hotfix` dalını yaptığınız gibi birleştireceksiniz. Bütün yapmanız gereken birleştirmeyi gerçekleştirmek istediğiniz dalı seçmek (_checkout_) ve `git merge` komutunu çalıştırmak: $ git checkout master $ git merge iss53 @@ -204,12 +204,12 @@ Diyelim ki #53 numaralı sorunla ilgili çalışmanızı tamamladınız ve `mast README | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) -Bu daha önce yaptığınız `hotfix` birleştirmesinden biraz farklı görünüyor. Burada, kayıt tarihçeniz daha eski bir noktadan ıraksamıştı. Üzerinde bulunduğunuz dalın gösterdiği kayıt birleştirmekte olduğunuz dalın doğrudan atası olmadığından Git'in biraz iş yapması gerekiyor. Bu örnekte Git, iki dalın en uç noktası ve ikisinin ortak atasının kullanıldığı üç-taraflı basit bir birleştirme yapıyor. Figür 3-16, bu birleştirmede kullanılan üç farklı bellek kopyasını vurguluyor. +Bu daha önce yaptığınız `hotfix` birleştirmesinden biraz farklı görünüyor. Burada, kayıt tarihçeniz daha eski bir noktadan ıraksamıştı. Üzerinde bulunduğunuz dalın gösterdiği kayıt birleştirmekte olduğunuz dalın doğrudan atası olmadığından Git'in biraz iş yapması gerekiyor. Bu örnekte Git, iki dalın en uç noktası ve ikisinin ortak atasının kullanıldığı üç taraflı basit bir birleştirme yapıyor. Figür 3-16, bu birleştirmede kullanılan üç farklı bellek kopyasını vurguluyor. Insert 18333fig0316.png Figür 3-16. Git, dalları birleştirmek için en uygun ortak atayı buluyor. -Git, yalnızca dal imlecini ileri kaydırmak yerine üç-tarafı birleştirmenin sonucunda ortaya çıkan bellek kopyası için otomatik bir kayıt oluşturuyor (bkz. Figür 3-17). Buna birlleştirme kaydı denir ve özelliği birden çok atasının olmasıdır. +Git, yalnızca dal imlecini ileri kaydırmak yerine üç taraflı birleştirmenin sonucunda ortaya çıkan bellek kopyası için otomatik bir kayıt oluşturuyor (bkz. Figür 3-17). Buna birleştirme kaydı denir ve özelliği birden çok atasının olmasıdır. Git'in en uygun ortak atayı otomatik olarak bulduğunu vurgulamakta yarar var; bu kullanıcının en uygun ortak paydayı bulmak zorunda olduğu CVS ve Subversion'daki durumdan (1.5 sürümünden önceki haliyle) farklıdır. Bu Git kullanarak birleştirme yapmayı söz konusu diğer sistemlere göre çok daha kolay bir hale getirir. @@ -222,7 +222,7 @@ Figür 3-17. Git, otomatik olarak, birleştirilmiş çalışmayı içeren yeni b ### Temel Birleştirme Uyuşmazlıkları ### -Zaman zaman bu süreç o kadar da pürüzsüz ilerlemez. Eğer aynı dosyanın aynı bölümünü her iki dalda da değiştirmişseniz, Git temiz bir birleştirme yapamaz. #53 numaları sorun için hazırladığınız düzeltme `hotfix`le aynı yazılım parçasını değiştiriyorsa, şuna benzer bir birleştirme uyuşmazlığıyla karşılaşırsınız: +Zaman zaman bu süreç o kadar da pürüzsüz ilerlemez. Eğer aynı dosyanın aynı bölümünü her iki dalda da değiştirmişseniz, Git temiz bir birleştirme yapamaz. #53 numaraları sorun için hazırladığınız düzeltme `hotfix`le aynı yazılım parçasını değiştiriyorsa, şuna benzer bir birleştirme uyuşmazlığıyla karşılaşırsınız: $ git merge iss53 Auto-merging index.html @@ -241,7 +241,7 @@ Burada Git otomatik olarak yeni bir birleştirme kaydı oluşturmadı. Sizin uyu # unmerged: index.html # -Birleştirme uyuşmazlığı henüz çözümlenmemiş her şey _unmerged_ (birleştirilmemiş) olarak gösterilecektir. Git, dosyaları açıp uyuşmazlıkları çözümleyebilmeniz için standartuyuşmazlık-çözümleme işaretçileri koyar. Dosyanızda şuna benzer bir bölümle karşılaşırsınız: +Birleştirme uyuşmazlığı henüz çözümlenmemiş her şey _unmerged_ (birleştirilmemiş) olarak gösterilecektir. Git, dosyaları açıp uyuşmazlıkları çözümleyebilmeniz için standart uyuşmazlık çözümleme işaretçileri koyar. Dosyanızda şuna benzer bir bölümle karşılaşırsınız: <<<<<<< HEAD:index.html @@ -257,7 +257,7 @@ Burada , `HEAD`deki sürüm (ki bu `master` dalındaki sürümdür çünkü birl please contact us at email.support@github.com -Çözümlemede iki taraftan da bir şeyler var ve `<<<<<<<`, `=======`, ve `>>>>>>>` işaretlerini içeren satırlar tamamen silinmiş durumda. Uyuşmazlık olan herbir dosyadaki herbir uyuşmazlık bloğunu çözümledikten sonra herbir dosya üzerinde `git add` komutunu çalıştırarak, uyuşmazlığın o dosya için çözülmüş olduğunu belirtebilirsiniz. Bir dosyayı ayda hazırlamak o dosyayı uyuşmazlığı çözümlenmiş olarak işaretler. +Çözümlemede iki taraftan da bir şeyler var ve `<<<<<<<`, `=======`, ve `>>>>>>>` işaretlerini içeren satırlar tamamen silinmiş durumda. Uyuşmazlık olan her bir dosyadaki her bir uyuşmazlık bloğunu çözümledikten sonra her dosyanın üzerinde `git add` komutunu çalıştırarak, uyuşmazlığın o dosya için çözülmüş olduğunu belirtebilirsiniz. Bir dosyayı ayda hazırlamak o dosyayı uyuşmazlığı çözümlenmiş olarak işaretler. Uyuşmazlıkları çözümlemek için görsel bir araç kullanmak isterseniz `git mergetool` komutunu çalıştırabilirsiniz; bu komut size tek tek herbir uyuşmazlığı gösterecek uygun bir birleştirme aracını çalıştırır: $ git mergetool @@ -271,7 +271,7 @@ Uyuşmazlıkları çözümlemek için görsel bir araç kullanmak isterseniz `gi Varsayılan aracın dışında bir araç kullanmak isterseniz (Git, Mac'te çalıştığım için bu örnekte `opendiff`'i seçti), Git'in desteklediği bütün birleştirme araçlarının listesini en üstte “merge tool candidates” yazısından hemen sonra görebilirsiniz. Kullanmak istediğiniz aracın adını yazın. 7. Bölüm'de kendi çalışma ortamınız için varsayılan değeri nasıl değiştirebileceğinizi inceleyeceğiz. -Brileştirme aracını kapattıktan sonra, Git size birleştirmenin başarılı olup olmadığını soracaktır. Eğer başarılı olduğunu söylerseniz, sizin yerinize dosyayı kayda hazırlayıp çözümlenmiş olarak işaretler. +Birleştirme aracını kapattıktan sonra, Git size birleştirmenin başarılı olup olmadığını soracaktır. Eğer başarılı olduğunu söylerseniz, sizin yerinize dosyayı kayda hazırlayıp çözümlenmiş olarak işaretler. Bütün uyuşmazlıkların çözümlendiğinden emin olmak için tekrar `git status` komutunu çalıştırabilirsiniz: @@ -296,11 +296,11 @@ Durumdan memnunsanız ve uyuşmazlığı olan bütün dosyaların kayda hazırla # and try again. # -İleride bu bürleştirme işlemini inceleyecek olanlar için yararlı olacağını düşünüyorsanız bu kayıt mesajını ayrıntılandırabilirsiniz —eğer aşikâr değilse, birleştirmeyi neden yaptığınızı, ve birleştirmede neler yaptığınızı açıklayabilirsiniz. +İleride bu birleştirme işlemini inceleyecek olanlar için yararlı olacağını düşünüyorsanız bu kayıt mesajını ayrıntılandırabilirsiniz —eğer aşikâr değilse, birleştirmeyi neden yaptığınızı, ve birleştirmede neler yaptığınızı açıklayabilirsiniz. ## Dal Yönetimi ## -Dal yaratma, birleştirme ve silme işlemlerini yaptığımıza göre, gelin şimdi de dallar üzerinde çalışırken işimize yarayacak kimi dal-yönetim araçlarına gö atalım. +Dal yaratma, birleştirme ve silme işlemlerini yaptığımıza göre, gelin şimdi de dallar üzerinde çalışırken işimize yarayacak kimi dal yönetim araçlarına göz atalım. `git branch` komutu dal yaratmak ve silmekten fazlasını yapar. Bu komutu hiçbir seçenek kullanmadan çalıştırırsanız, mevcut dallarınızın bir listesini görürsünüz: @@ -309,7 +309,7 @@ Dal yaratma, birleştirme ve silme işlemlerini yaptığımıza göre, gelin şi * master testing -`master` dalının önündeki `*` karakterine dikkatinizi çekmiştir: bu, o dalı seçmiş olduğunuzu (_checkout_) gösteriyor. Yani, bu noktada bir kayıt yapacak olursanız, yeni değişikliğiniz `master` dalını ileri götürecek. Herbir dalın en son kaydının ne olduğunu görmek isterseniz `git branch -v` komutunu çalıştırabilirsiniz: +`master` dalının önündeki `*` karakterine dikkatinizi çekmiştir: bu, o dalı seçmiş olduğunuzu (_checkout_) gösteriyor. Yani, bu noktada bir kayıt yapacak olursanız, yeni değişikliğiniz `master` dalını ileri götürecek. Her bir dalın en son kaydının ne olduğunu görmek isterseniz `git branch -v` komutunu çalıştırabilirsiniz: $ git branch -v iss53 93b412c fix javascript issue @@ -322,7 +322,7 @@ Dallarınızın ne durumda olduğunu incelerken yararlı olacak bir başka şey iss53 * master -`iss53` dalını daha önce birleştirdiğiniz için listede görüyorsunuz. Bu listede önünde `*` olmayan dalları `git branch -d` komutula silebilirsiniz; onlardaki değişiklikleri zaten başka bir dalla birleştirdiğiniz için, herhangi bir kaybınız olmaz. +`iss53` dalını daha önce birleştirdiğiniz için listede görüyorsunuz. Bu listede önünde `*` olmayan dalları `git branch -d` komutuyla silebilirsiniz; onlardaki değişiklikleri zaten başka bir dalla birleştirdiğiniz için, herhangi bir kaybınız olmaz. Henüz birleştirmediğiniz değişikliklerin bulunduğu dalları görmek için `git branch --no-merged` komutunu çalıştırabilirsiniz: @@ -342,9 +342,9 @@ Dallanma ve birleştirmenin temellerine hakim olduğunuza göre, şimdi bu bilgi ### Uzun Süreli Dallar ### -Git, basit üç-taraflı birleştirme yaptığı için uzun bir zaman dilimi boyunca bir daldan diğerine çok sayıda birleştirme yapmak genellikle kolaydır. Yani, sürekli açık olan ve geliştirme döngünüzün değşik aşamalarında kullanabileceğiniz birkaç dal bulundurabilirsiniz; düzenli olarak bazılarından diğerlerine birleştirme yapabilirsiniz. +Git, basit üç taraflı birleştirme yaptığı için uzun bir zaman dilimi boyunca bir daldan diğerine çok sayıda birleştirme yapmak genellikle kolaydır. Yani, sürekli açık olan ve geliştirme döngünüzün değişik aşamalarında kullanabileceğiniz birkaç dal bulundurabilirsiniz; düzenli olarak bazılarından diğerlerine birleştirme yapabilirsiniz. -Git'i kullanan pekçok yazılımcı bu yaklaşımı benimser, `master` dalında yalnızca kararlı (_stable_) durumdaki kod bulunur —yalnızca yayımlanmış olan ya da yayımlanacak kod. `develop` ya da `next` adında, kararlılık testlerinin yürütüldüğü bir paralel dalları daha vardır —bu dal o kada kararlı olmayabilir, fakat kararlı duruma getirildiğinde `master` dalına birleştirilir. Kısa ömürlü, belirli bir işlevin geliştirilmesine ayrılmış dalların (sizin `iss53` adlı dalınız gibi) hazır olduklarında birleştirilmeleri için —bütün testlerden geçtiklerinden ve yeni hatalara kapı aralamadıklarından emin olmak amacıyla— kullanılır. +Git'i kullanan pek çok yazılımcı bu yaklaşımı benimser, `master` dalında yalnızca kararlı (_stable_) durumdaki kod bulunur —yalnızca yayımlanmış olan ya da yayımlanacak kod. `develop` ya da `next` adında, kararlılık testlerinin yürütüldüğü bir paralel dalları daha vardır —bu dal o kadar kararlı olmayabilir, fakat kararlı duruma getirildiğinde `master` dalına birleştirilir. Kısa ömürlü, belirli bir işlevin geliştirilmesine ayrılmış dalların (sizin `iss53` adlı dalınız gibi) hazır olduklarında birleştirilmeleri için —bütün testlerden geçtiklerinden ve yeni hatalara kapı aralamadıklarından emin olmak amacıyla— kullanılır. Gerçekte, yazılım tarihçesinde ileri doğru hareket eden imleçlerden söz ediyoruz. Kararlı dallar eski kayıtları, güncel dallar çok daha yenilerini gösterir (bkz. Figür 3-18). @@ -363,14 +363,14 @@ Tekrarlayalım: birden çok uzun ömürlü dal bulundurmak zorunlu değildir, am İşlev dalları, her ölçekte proje için yararlıdır. İşlev dalları, belirli bir özellikle ilgili değişikliklerin geliştirilmesi için kullanılan kısa ömürlü dallardır. Başka SKS'lerde bu çok masraflı olduğu için, muhtemelen bu yaklaşımı daha önce benimsemediniz. Ama Git'te dal yaratmak, o dal üzerinde çalışmak, dalı birleştirmek ve daha sonra silmek, günde birkaç kez yapılan yaygın bir yöntemdir. -Bunu bir önceki alt bölümde `iss53` ve `hotfix` dalları üzerinde çalışırken gördünüz. Bu dallarda birkaç değişiklik yaptınız ve bu değişiklikleri `master` dalına birleştirdikten hemen sonra bu dalları sildiniz. Bu teknik sayesinde, bağlamlar arasında hızlı ve bütünlüklü geçişler yapabilirsiniz —çalışmalarınız belirli bir işlevin geliştirilmesine adanmış farklı ambarlara ayrılmış olduğundan, geçen süre zarfında, diyelim kod gözden geçirmesi sırasında neler olduğunu kolaylıkla görebilirsiniz. Değişikliklerinizi işlev dallarında dakikallarca, günlerce ya da aylarca tutabilir, hazır oldukları zaman, hangisinin dalın daha önce oluşturulduğuna aldırmadan birleştirebilirsiniz. +Bunu bir önceki alt bölümde `iss53` ve `hotfix` dalları üzerinde çalışırken gördünüz. Bu dallarda birkaç değişiklik yaptınız ve bu değişiklikleri `master` dalına birleştirdikten hemen sonra bu dalları sildiniz. Bu teknik sayesinde, bağlamlar arasında hızlı ve bütünlüklü geçişler yapabilirsiniz —çalışmalarınız belirli bir işlevin geliştirilmesine adanmış farklı ambarlara ayrılmış olduğundan, geçen süre zarfında, diyelim kod gözden geçirmesi sırasında neler olduğunu kolaylıkla görebilirsiniz. Değişikliklerinizi işlev dallarında dakikalarca, günlerce ya da aylarca tutabilir, hazır oldukları zaman, hangisinin dalın daha önce oluşturulduğuna aldırmadan birleştirebilirsiniz. -Diyelim ki `master` dalında çalışıyorsunuz, sonra bir hatayı gidermek için yeni bir dal yaratıyorsunuz (`iss91`), derken aynı hatayı başka türlü gidermek için yeni bir dal yaratıyorsunuz (`iss91v2`), sonra `master`'a geri dönüp biraaz daha çalışıyorsunuz, sonra aklınıza gelen ama çok da gerekli olmadığını düşündüğünüz bir şeyle ilgili çalışmak için yeni bir dal yaratıyorsununuz (`dumbidea`)... Kayıt tarihçeniz Figür 3-20'deki gibi görünecektir. +Diyelim ki `master` dalında çalışıyorsunuz, sonra bir hatayı gidermek için yeni bir dal oluşturuyorsunuz (`iss91`), derken aynı hatayı başka türlü gidermek için yeni bir dal oluşturuyorsunuz (`iss91v2`), sonra `master`'a geri dönüp biraz daha çalışıyorsunuz, sonra aklınıza gelen ama çok da gerekli olmadığını düşündüğünüz bir şeyle ilgili çalışmak için yeni bir dal oluşturuyorsunuz (`dumbidea`)... Kayıt tarihçeniz Figür 3-20'deki gibi görünecektir. Insert 18333fig0320.png Figür 3-20. Birden çok işlev dalının bulunduğu kayıt tarihçeniz. -Şimdi diyelim ki, hatanın giderilmesinde ikinci çözümü (`iss91v2`) kullanmaya karar veriyorsunuz ve işarkadaşlarınız `dumbidea` dalında yaptıklarınızı dahice buluyor. `iss91` dalınızı çöpe atabilir (C5 ve C6 kayıtlarını kaybedeceksiniz) diğer iki dalı birleştirebilirsiniz. Bu durumda tarihçeniz Figür 3-21'deki gibi görünecektir. +Şimdi diyelim ki, hatanın giderilmesinde ikinci çözümü (`iss91v2`) kullanmaya karar veriyorsunuz ve iş arkadaşlarınız `dumbidea` dalında yaptıklarınızı dahice buluyor. `iss91` dalınızı çöpe atabilir (C5 ve C6 kayıtlarını kaybedeceksiniz) diğer iki dalı birleştirebilirsiniz. Bu durumda tarihçeniz Figür 3-21'deki gibi görünecektir. Insert 18333fig0321.png Figür 3-21. dumbidea ve iss91v2'yi birleştirdikten sonra kayıt tarihçeniz. @@ -381,24 +381,24 @@ Unutmayın, bütün bunları yerel dallarda yapıyorsunuz. Dal yaratırken ve bi Yerel yazılım havuzunuzdaki uzak uçbirim dalları, uzak uçbirimlerdeki yazılım havuzlarınızın durumlarını gösteren imleçlerdir. Bunlar, hareket ettiremediğiniz yerel dallardır; yalnızca sunucuyla iletişim kurduğunuzda hareket ederler. Bu dallar, son bağlandığınızda sunucudaki yazılım havuzunun ne durumda olduğunu hatırlatan işaretçilerdir. -`(remote)`/`(dal)` biçimindedirler. Örneğin, sunucuya son bağlandığınızda `origin` uzak uçbirimindeki `master` dalının nasıl olduğunu görmek isterseniz, `origin/master` dalına bakmalısınız. Bir hatayı bir işortağıyla birlikte çözüyorsanız ve onlar `iss53` adında bir dalı sunucuya itmişlerse, sizin yerel dalınızın adı `iss53` iken, sunucuya itilmiş olan dalın adı `origin/iss53` olacaktır. +`(remote)`/`(dal)` biçimindedirler. Örneğin, sunucuya son bağlandığınızda `origin` uzak uçbirimindeki `master` dalının nasıl olduğunu görmek isterseniz, `origin/master` dalına bakmalısınız. Bir hatayı bir iş ortağıyla birlikte çözüyorsanız ve onlar `iss53` adında bir dalı sunucuya itmişlerse, sizin yerel dalınızın adı `iss53` iken, sunucuya itilmiş olan dalın adı `origin/iss53` olacaktır. -Bu biraz kafa karıştırıcı olabilir, gelin bir örnekle açıklayalım. Diyelim ki `git.ourcompany.com` adresinde bir Git sunucunuz var. Buradan klonlama yaparsanız, Git bu yazılım havuzunu otomatik olarak `origin` olarak adlandıracak, bütün veriyi indirecek, onun `master` dalının gösterdiği kaydı gösteren `origin/master` adında hareket ettiremeyeceğiniz bir yerel dal oluşturacaktır. Git ayrıca, üzerinde çalışabilmeniz için `origin`in `master` dalının olduğu yeri gösteren `master` adında yerel bir dal da oluşturacaktır (bkz. Figür 3-22). +Bu biraz kafa karıştırıcı olabilir, gelin bir örnekle açıklayalım. Diyelim ki `git.şirketimiz.com` adresinde bir Git sunucunuz var. Buradan klonlama yaparsanız, Git bu yazılım havuzunu otomatik olarak `origin` olarak adlandıracak, bütün veriyi indirecek, onun `master` dalının gösterdiği kaydı gösteren `origin/master` adında hareket ettiremeyeceğiniz bir yerel dal oluşturacaktır. Git ayrıca, üzerinde çalışabilmeniz için `origin`in `master` dalının olduğu yeri gösteren `master` adında yerel bir dal da oluşturacaktır (bkz. Figür 3-22). Insert 18333fig0322.png Figür 3-22. Bir Git klonladığınızda hem yerel bir master dalınız hem de origin'in master dalını gösteren origin/master adında bir dalınız olur. -Eğer siz kendi master dalınızda çalışırken biir başkası `git.ourcompany.com`'a itme yapıp `master` dalını güncellerse, tarihçeleriniz birbiirinden farklılaşacaktır. Üstelik, `origin` sunucusuyla iletişime geçmediğiniz sürece sizin `origin/master` dalınız hareket etmeyecektir (bkz. Figür 3-23). +Eğer siz kendi master dalınızda çalışırken biir başkası `git.şirketimiz.com`'a itme yapıp `master` dalını güncellerse, tarihçeleriniz birbirinden farklılaşacaktır. Üstelik, `origin` sunucusuyla iletişime geçmediğiniz sürece sizin `origin/master` dalınız hareket etmeyecektir (bkz. Figür 3-23). Insert 18333fig0323.png Figür 3-23. Siz yerelde çalışıyorken bir başkası sunucuya itme yaparsa, tarihçeleriniz birbirinden farklı hareket etmeye başlar. -Çalışmalarınızı senkronize etmek için `git fetch origin` komutunu çalıştırabilirsiniz. Bu komut `origin`sunucusunun hangisi olduğuna bakar (bu örnekte `git.ourcompany.com`), orada bulunup da sizde olmayan her türlü veriyi indirir, yerel veritabanınızı güncelleyip yerelinizdeki `origin/master` dalını yeni, güncel konumuna taşır (bkz. Figür 3-24). +Çalışmalarınızı eşitlemek için `git fetch origin` komutunu çalıştırabilirsiniz. Bu komut `origin` sunucusunun hangisi olduğuna bakar (bu örnekte `git.şirketimiz.com`), orada bulunup da sizde olmayan her türlü veriyi indirir, yerel veritabanınızı güncelleyip yerelinizdeki `origin/master` dalını yeni, güncel konumuna taşır (bkz. Figür 3-24). Insert 18333fig0324.png Figür 3-24. git fetch komutu uzak uçbirim imleçlerinizi günceller. -Birden çok uzak uçbirime sahip bir projede uzak uçbirim imleçlerinin nasıl görüneceğini incelemek için, Scrum takımlarınızdan birisi tarafından kullanılan başka bir sunucunuzun daha olduğunu varsayalım. Bu sunucunun adresi `git.team1.ourcompany.com` olsun. 2. Bölüm'de incelediğimiz gibi, bu sunucuyu projenize uzak uçbirim olarak eklemek için `git remote add` komutunu kullanabilirsiniz. Bu uçbirimin adı `teamone` olsun, ki bu adı daha sonra bütün URL yerine kısaltma olarak kullanacaksınız (bkz. Figür 3-25). +Birden çok uzak uçbirime sahip bir projede uzak uçbirim imleçlerinin nasıl görüneceğini incelemek için, Scrum takımlarınızdan birisi tarafından kullanılan başka bir sunucunuzun daha olduğunu varsayalım. Bu sunucunun adresi `git.team1.şirketimiz.com` olsun. 2. Bölüm'de incelediğimiz gibi, bu sunucuyu projenize uzak uçbirim olarak eklemek için `git remote add` komutunu kullanabilirsiniz. Bu uçbirimin adı `teamone` olsun, ki bu adı daha sonra bütün URL yerine kısaltma olarak kullanacaksınız (bkz. Figür 3-25). Insert 18333fig0325.png Figür 3-25. Başka bir sunucuyu uzak uçbirim olarak eklemek. @@ -410,7 +410,7 @@ Figür 3-26. teamone'nin master dalının pozisyonunu gösteren bir yerel imleci ### İtme İşlemi ### -Bir daldaki çalışmalarınızı başkalarıyla paylaşmak istediğinizde, onu yazma yetkinizin olduğu bir uzak uçbirime itmelisiniz (_push_). yerel dallarınız otomatik kolarak sunucuyla senkronize edilmez —paylaşmak istediğiniz dalları açık şekilde itmelisiniz. Böylece, paylaşmak istemediğiniz dallar için özel yerel dallar kullanıp, yalnızca paylaşmak istediğiniz işlev dallarını iteblirsiniz. +Bir daldaki çalışmalarınızı başkalarıyla paylaşmak istediğinizde, onu yazma yetkinizin olduğu bir uzak uçbirime itmelisiniz (_push_). yerel dallarınız otomatik olarak sunucuyla eşitlenmez —paylaşmak istediğiniz dalları açık şekilde itmelisiniz. Böylece, paylaşmak istemediğiniz dallar için özel yerel dallar kullanıp, yalnızca paylaşmak istediğiniz işlev dallarını iteblirsiniz. Başkalarıyla ortaklaşa çalışmak istediğiniz `serverfix` adında bir dalınız varsa, onu da ilk dalınızı ittiğiniz gibi itebilirsiniz. `git push (remote) (branch)` komutunu çalıştırın. @@ -422,7 +422,7 @@ Başkalarıyla ortaklaşa çalışmak istediğiniz `serverfix` adında bir dalı To git@github.com:schacon/simplegit.git * [new branch] serverfix -> serverfix -Bu bir tür kısayol sayılabilir. Git `serverfix` dal adını otomatik olarak `refs/heads/serverfix:refs/heads/serverfix` biçiminde açımlar, bu şu demektir: “yerel `serverfix` dalımı alıp uzak uçbirimin `serverfix` dalını güncellemek için kullan.” `refs/heads/` kısmınz 9. Bölüm'de ayrıntısıyla değineceğiz, ama genellikle bu kısmı kullanmasanız da olur. Aynı amaçla `git push origin serverfix:serverfix` komutunu da çalıştırabilirsiniz —bu da şu demektir: “Yereldeki serverfix'i al, bunu uzak uçbirimin serverfix'i yap.” Bu biçimi, yeredeki dal adıyla uzak uçbirimdeki dal adı farklı ise kullanabilirsiniz. Dal adının uzak uçbirimde `serferfix` olmasını istemezseniz `git push origin serverfix:awesomebranch` komutunu çalıştırarak yereldeki `serverfix` dalını uzak uçbirimdeki `awesomebranch` dalına itebilirsiniz. +Bu bir tür kısayol sayılabilir. Git `serverfix` dal adını otomatik olarak `refs/heads/serverfix:refs/heads/serverfix` biçiminde açımlar, bu şu demektir: “yerel `serverfix` dalımı alıp uzak uçbirimin `serverfix` dalını güncellemek için kullan.” `refs/heads/` kısmınz 9. Bölüm'de ayrıntısıyla değineceğiz, ama genellikle bu kısmı kullanmasanız da olur. Aynı amaçla `git push origin serverfix:serverfix` komutunu da çalıştırabilirsiniz —bu da şu demektir: “Yereldeki serverfix'i al, bunu uzak uçbirimin serverfix'i yap.” Bu biçimi, yereldeki dal adıyla uzak uçbirimdeki dal adı farklı ise kullanabilirsiniz. Dal adının uzak uçbirimde `serferfix` olmasını istemezseniz `git push origin serverfix:awesomebranch` komutunu çalıştırarak yereldeki `serverfix` dalını uzak uçbirimdeki `awesomebranch` dalına itebilirsiniz. Birlikte çalıştığınız insanlar sunucudan getirme işlemi (_fetch_) yaptıklarında, sunucudaki `serverfix` sürümünün bulunduğu yeri gösteren `origin/serverfix` adında bir imlece sahip olacaklar. @@ -446,9 +446,9 @@ Bu, üzerinde çalışabileceğiniz ve `origin/serverfix`in gösterdiği yerden ### İzleme Dalları ### -Bir uzak uçbirim dalından yerel bir dal seçtğinizde (_checkout_), bu işlem otomatik olarak bir _izleme dalı_ (_tracking branch_) oluşturur. İzleme dalları, uzak uçbirim dallarıyla doğrudan ilişkileri bulunan yerel dallardır. Bir izleme dalından `git push` komutunu çalıştırdığınızda , Git hangi sunucudaki hangi dala itme işlemi yapması gerektiğini bilir. Ayrıca, bu dallardan biirinden `git pull` komutunu çalıştırdığınızda, bütün imleçler indirileceği gibi, bu izleme dalına karşılık gelen uzak uçbirim dalı da otomatik olarak bu dalla birleştirilir. +Bir uzak uçbirim dalından yerel bir dal seçtiğinizde (_checkout_), bu işlem otomatik olarak bir _izleme dalı_ (_tracking branch_) oluşturur. İzleme dalları, uzak uçbirim dallarıyla doğrudan ilişkileri bulunan yerel dallardır. Bir izleme dalından `git push` komutunu çalıştırdığınızda , Git hangi sunucudaki hangi dala itme işlemi yapması gerektiğini bilir. Ayrıca, bu dallardan birinden `git pull` komutunu çalıştırdığınızda, bütün imleçler indirileceği gibi, bu izleme dalına karşılık gelen uzak uçbirim dalı da otomatik olarak bu dalla birleştirilir. -Bir yazılım havunuzu klonladığınızda, genellikle `origin/master` dalını izleyen bir `master` dalı yaratılır. Bu nedenle `git push` ve `git pull` komutları bu durumlarda ek argümanlara gerek kalmadan çalışırlar. Öte yandan, isterseniz başka izleme dalları da —`origin`'i ya da `master` dalınız izlemeyen dallar— oluşturabilirsiniz. Yukarıda basit bir örneğini gördük: `git checkout -b [dal] [uzak_ucbirim]/[dal]`. Git'in 1.6.2'den itibaren olan sürümlerinde `--track` kısayolunu da kullanabilirsiniz: +Bir yazılım havuzunu klonladığınızda, genellikle `origin/master` dalını izleyen bir `master` dalı yaratılır. Bu nedenle `git push` ve `git pull` komutları bu durumlarda ek argümanlara gerek kalmadan çalışırlar. Öte yandan, isterseniz başka izleme dalları da —`origin`'i ya da `master` dalınız izlemeyen dallar— oluşturabilirsiniz. Yukarıda basit bir örneğini gördük: `git checkout -b [dal] [uzak_ucbirim]/[dal]`. Git'in 1.6.2'den itibaren olan sürümlerinde `--track` kısayolunu da kullanabilirsiniz: $ git checkout --track origin/serverfix Branch serverfix set up to track remote branch refs/remotes/origin/serverfix. From 67fc8f0869e299c04d10330b3a7b66f87f208aee Mon Sep 17 00:00:00 2001 From: Karel Heyse Date: Thu, 12 Dec 2013 15:46:13 +0100 Subject: [PATCH 071/862] [nl] -dt errors and incorrect conjugation of english verbs in dutch --- nl/02-git-basics/01-chapter2.markdown | 12 +++---- nl/03-git-branching/01-chapter3.markdown | 6 ++-- nl/04-git-server/01-chapter4.markdown | 16 +++++----- nl/05-distributed-git/01-chapter5.markdown | 10 +++--- nl/06-git-tools/01-chapter6.markdown | 14 ++++---- nl/07-customizing-git/01-chapter7.markdown | 32 +++++++++---------- nl/08-git-and-other-scms/01-chapter8.markdown | 20 ++++++------ nl/09-git-internals/01-chapter9.markdown | 10 +++--- 8 files changed, 60 insertions(+), 60 deletions(-) diff --git a/nl/02-git-basics/01-chapter2.markdown b/nl/02-git-basics/01-chapter2.markdown index b572aff30..bb42e8fee 100644 --- a/nl/02-git-basics/01-chapter2.markdown +++ b/nl/02-git-basics/01-chapter2.markdown @@ -26,7 +26,7 @@ We zullen zodadelijk beschrijven wat deze commando's doen. Op dit punt heb je ee Als je een kopie wilt van een bestaande Git repository — bijvoorbeeld een project waaraan je wilt bijdragen — dan is `git clone` het commando wat je nodig hebt. Als je bekend bent met andere versie-beheersystemen zoals Subversion, dan valt je op dat het commando `clone` is en niet `checkout`. Dit is een belangrijk verschil — Git ontvangt een kopie van bijna alle data die de server heeft. Iedere versie van ieder bestand van de hele geschiedenis van een project wordt binnengehaald als je `git clone` doet. In feite kun je, als je disk kapot gaat, iedere clone van iedere client gebruiken om de server terug in de status te brengen op het moment van clonen (al zou je wel wat hooks en dergelijke verliezen, maar alle versies van alle bestanden zouden er zijn — zie *Hoofdstuk 4* voor meer informatie). -Je cloned een repository met `git clone [url]`. Bijvoorbeeld, als je de Ruby Git bibliotheek genaamd Grit wilt clonen, kun je dit als volgt doen: +Je clonet een repository met `git clone [url]`. Bijvoorbeeld, als je de Ruby Git bibliotheek genaamd Grit wilt clonen, kun je dit als volgt doen: $ git clone git://github.com/schacon/grit.git @@ -42,7 +42,7 @@ Git heeft een aantal verschillende transport protocollen die je kunt gebruiken. Je hebt een bonafide Git repository en een checkout of werkkopie van de bestanden voor dat project. Je moet wat wijzigingen maken en deze committen in je repository, iedere keer zodra het project een status bereikt die je wilt vastleggen. -Onthoud dat ieder bestand in je werkmap in twee statussen kan verkeren: *gevolgd (tracked)* of *niet gevolgd (untracked)*. *Gevolgde* bestanden zijn bestanden die in het laatste snapshot zaten; ze kunnen *ongewijzigd*, *gewijzigd* of *staged zijn*. *Niet gevolgde* bestanden zijn al het andere - ieder bestand in je werkmap dat niet in je laatste snapshot en niet in je staging gebied zit. Als je voor het eerst een repository cloned, zullen al je bestanden gevolgd en ongewijzigd zijn, omdat je ze zojuist ge-checkout en niet gewijzigd hebt. +Onthoud dat ieder bestand in je werkmap in twee statussen kan verkeren: *gevolgd (tracked)* of *niet gevolgd (untracked)*. *Gevolgde* bestanden zijn bestanden die in het laatste snapshot zaten; ze kunnen *ongewijzigd*, *gewijzigd* of *staged zijn*. *Niet gevolgde* bestanden zijn al het andere - ieder bestand in je werkmap dat niet in je laatste snapshot en niet in je staging gebied zit. Als je voor het eerst een repository clonet, zullen al je bestanden gevolgd en ongewijzigd zijn, omdat je ze zojuist ge-checkout en niet gewijzigd hebt. Zodra je bestanden wijzigt, ziet Git ze als gewijzigd omdat je ze veranderd hebt sinds je laatste commit. Je *staged* deze gewijzigde bestanden en commit al je ge-stagede wijzigingen, en de cyclus herhaalt zichzelf. Deze cyclus wordt in Figuur 2-1 geïllustreerd. @@ -779,7 +779,7 @@ Zoals je zojuist gezien hebt, kun je om data van je remote projecten te halen di Het commando gaat naar het remote project en haalt alle data van dat remote project dat jij nog niet hebt. Nadat je dit gedaan hebt, zou je references (referenties) naar alle branches van dat remote moeten hebben, die je op ieder tijdstip kunt mergen en bekijken. (We zullen zien wat branches precies zijn, en hoe je ze moet gebruiken in meer detail in *Hoofdstuk 3*.) -Als je een repository cloned, voegt dat commando dat remote repository automatisch toe onder de naam *origin*. Dus `git fetch origin` fetched (haalt) ieder nieuw werk dat gepushed is naar die server sinds je gecloned hebt (of voor het laatst ge-fetched hebt). Het is belangrijk om te weten dat het fetch commando de data naar je locale repository haalt — het merged niet automatisch met je werk of verandert waar je momenteel aan zit te werken. Je kunt het handmatig in je werk mergen als je er klaar voor bent. +Als je een repository clonet, voegt dat commando dat remote repository automatisch toe onder de naam *origin*. Dus `git fetch origin` fetched (haalt) ieder nieuw werk dat gepusht is naar die server sinds je gecloned hebt (of voor het laatst ge-fetched hebt). Het is belangrijk om te weten dat het fetch commando de data naar je locale repository haalt — het merged niet automatisch met je werk of verandert waar je momenteel aan zit te werken. Je kunt het handmatig in je werk mergen als je er klaar voor bent. Als je een branch geconfigureerd hebt om een remote branch te tracken (volgen) (zie de volgende sectie en *Hoofdstuk 3* voor meer informatie), dan kun je het `git pull` commando gebruiken om automatisch een remote branch te fetchen en mergen in je huidige branch. Dit kan makkelijker of meer comfortabel zijn voor je werkwijze; en standaard stelt het `git clone` commando je lokale master branch zo in dat het de remote master branch van de server waarvan je gecloned hebt volgt (aangenomen dat de remote een master branch heeft). Over het algemeen zal een `git pull` dat van de server waarvan je origineel gecloned hebt halen en proberen het automatisch in de code waar je op dat moment aan zit te werken te mergen. @@ -789,7 +789,7 @@ Wanneer je je project op een punt krijgt dat je het wilt delen, dan moet je het $ git push origin master -Dit commando werkt alleen als je gecloned hebt van een server waarop je schrijfrechten hebt, en als niemand in de tussentijd gepushed heeft. Als jij en iemand anders op hetzelfde tijdstip gecloned hebben en zij pushen stroomopwaarts en dan jij, dan zal je push terecht geweigerd worden. Je zult eerst hun werk moeten pullen en in jouw werk verwerken voordat je toegestaan wordt te pushen. Zie *Hoofdstuk 3* voor meer gedetailleerde informatie over hoe je naar remote servers moet pushen. +Dit commando werkt alleen als je gecloned hebt van een server waarop je schrijfrechten hebt, en als niemand in de tussentijd gepusht heeft. Als jij en iemand anders op hetzelfde tijdstip gecloned hebben en zij pushen stroomopwaarts en dan jij, dan zal je push terecht geweigerd worden. Je zult eerst hun werk moeten pullen en in jouw werk verwerken voordat je toegestaan wordt te pushen. Zie *Hoofdstuk 3* voor meer gedetailleerde informatie over hoe je naar remote servers moet pushen. ### Een remote inspecteren ### @@ -830,7 +830,7 @@ Dat is een eenvoudig voorbeeld dat je vaak tegenkomt. Als je Git meer intensief Local branch pushed with 'git push' master:master -Dit commando toont welke branch automatisch gepushed wordt als je `git push` uitvoert op bepaalde branches. Het toont je ook welke remote branches op de server je nog niet hebt, welke remote branches je hebt die verwijderd zijn van de server, en meerdere branches die automatisch gemerged worden als je `git pull` uitvoert. +Dit commando toont welke branch automatisch gepusht wordt als je `git push` uitvoert op bepaalde branches. Het toont je ook welke remote branches op de server je nog niet hebt, welke remote branches je hebt die verwijderd zijn van de server, en meerdere branches die automatisch gemerged worden als je `git pull` uitvoert. ### Remotes verwijderen en hernoemen ### @@ -1052,7 +1052,7 @@ Als je veel tags hebt die je ineens wilt pushen, kun je ook de `--tags` optie aa * [new tag] v1.4-lw -> v1.4-lw * [new tag] v1.5 -> v1.5 -Als nu iemand anders van jouw repository cloned of pulled, dan zullen zij al jouw tags ook krijgen. +Als nu iemand anders van jouw repository clonet of pulled, dan zullen zij al jouw tags ook krijgen. ## Tips en trucs ## diff --git a/nl/03-git-branching/01-chapter3.markdown b/nl/03-git-branching/01-chapter3.markdown index f1e8f5b4e..956fde1be 100644 --- a/nl/03-git-branching/01-chapter3.markdown +++ b/nl/03-git-branching/01-chapter3.markdown @@ -384,7 +384,7 @@ Remote branches zijn referenties naar de staat van de branches op je remote repo Ze hebben de vorm `(remote)/(branch)`. Bijvoorbeeld, als je wil zien hoe de `master` branch op je `origin` er uit zag vanaf de laatste dat je er mee gecommuniceerd hebt, dan zou je de `origin/master` branch bekijken. Als je aan het werk bent aan een probleem met een partner en zij hebben een `iss53` branch teruggezet, dan zou je je eigen lokale `iss53` kunnen hebben; maar de branch op de server zou wijzen naar de commit op `origin/iss53`. -Dit kan wat verwarrend zijn, dus laten we eens naar een voorbeeld kijken. Stel dat je een Git server op je netwerk hebt op `git.ourcompany.com`. Als je hiervan cloned dan wordt die automatisch `origin` voor je genoemd, Git haalt al zijn gegevens binnen, maakt een verwijzing naar waar zijn `master` branch is, en noemt dat lokaal `origin/master`; en je kunt het niet verplaatsen. Git geeft je ook je eigen `master` branch, beginnend op dezelfde plaats als de `master` branch van origin, zodat je iets hebt om vanaf te werken (zie Figuur 3-22). +Dit kan wat verwarrend zijn, dus laten we eens naar een voorbeeld kijken. Stel dat je een Git server op je netwerk hebt op `git.ourcompany.com`. Als je hiervan clonet dan wordt die automatisch `origin` voor je genoemd, Git haalt al zijn gegevens binnen, maakt een verwijzing naar waar zijn `master` branch is, en noemt dat lokaal `origin/master`; en je kunt het niet verplaatsen. Git geeft je ook je eigen `master` branch, beginnend op dezelfde plaats als de `master` branch van origin, zodat je iets hebt om vanaf te werken (zie Figuur 3-22). Insert 18333fig0322.png Figuur 3-22. Een Git clone geeft je je eigen master branch en origin/master wijzend naar de master branch van origin. @@ -449,7 +449,7 @@ Dit geeft je een lokale branch waar je op kunt werken, die begint met waar `orig Een lokale branch uitchecken van een remote branch creëert automatisch een zogenaamde _volg branch_ (_tracking branch_). Volg branches zijn lokale branches die een directe releatie met een remote branch hebben. Als je op een volg branch zit en git push typt, dat weet Git automatisch naar welke server en branch hij moet terugzetten. En, terwijl je op een van die branches zit zal het uitvoeren van `git pull` alle remote referenties ophalen en ze automatisch in de corresponderende remote branch samenvoegen. -Als je een repository cloned, zal het over het algemeen automatisch een `master` branch aanmaken, die `origin/master` volgt. Daarom werken `git push` en `git pull` zo uit het doosje, zonder verdere argumenten. Maar, kun je kunt ook andere volg branches instellen als je dat wilt — anderen die niet branches volgen op `origin` en niet de `master` branch volgen. Het eenvoudige geval is het voorbeeld dat je zojuist zag, `git checkout -b [branch] [remotenaam]/[branch]` uitvoeren. Als je Git versie 1.6.2 of nieuwer hebt, kun je ook de `--track` afkorting gebruiken: +Als je een repository clonet, zal het over het algemeen automatisch een `master` branch aanmaken, die `origin/master` volgt. Daarom werken `git push` en `git pull` zo uit het doosje, zonder verdere argumenten. Maar, kun je kunt ook andere volg branches instellen als je dat wilt — anderen die niet branches volgen op `origin` en niet de `master` branch volgen. Het eenvoudige geval is het voorbeeld dat je zojuist zag, `git checkout -b [branch] [remotenaam]/[branch]` uitvoeren. Als je Git versie 1.6.2 of nieuwer hebt, kun je ook de `--track` afkorting gebruiken: $ git checkout --track origin/serverfix Branch serverfix set up to track remote branch refs/remotes/origin/serverfix. @@ -570,7 +570,7 @@ Als je die richtlijn volgt, dan gebeurt je niets. Als je dat niet doet, zullen m Als je spullen rebaset, laat je bestaande commits achter en maak je nieuwe aan die vergelijkbaar zijn maar anders. Als je commits ergens naartoe zet en andere halen ze binnen en baseren daar werk op, en vervolgens herschrijf je die commits met `git rebase` en zet ze opnieuw terug, dan zullen je medewerkers hun werk opnieuw moeten samenvoegen en zullen de dingen vervelend worden als je hun werk probeert binnen te halen in het jouwe. -Laten we eens kijken naar een voorbeeld of hoe werk rebasen dat je publiekelijk gemaakt hebt problemen kan veroorzaken. Stel dat je van een centrale server cloned en dan daar wat werk vanaf doet. Je commit historie ziet er uit als Figuur 3-36. +Laten we eens kijken naar een voorbeeld of hoe werk rebasen dat je publiekelijk gemaakt hebt problemen kan veroorzaken. Stel dat je van een centrale server clonet en dan daar wat werk vanaf doet. Je commit historie ziet er uit als Figuur 3-36. Insert 18333fig0336.png Figuur 3-36. Clone een repository, en baseer wat werk daarop. diff --git a/nl/04-git-server/01-chapter4.markdown b/nl/04-git-server/01-chapter4.markdown index 66daafe6c..4344ee256 100644 --- a/nl/04-git-server/01-chapter4.markdown +++ b/nl/04-git-server/01-chapter4.markdown @@ -91,7 +91,7 @@ Als laatste hebben we het HTTP protocol. Het mooie aan het HTTP of HTTPS protoco $ mv hooks/post-update.sample hooks/post-update $ chmod a+x hooks/post-update -Dat is alles. De `post-update` hook, die standaard bij Git zit, voert het noodzakelijke commando uit (`git update-server-info`) om HTTP fetching en cloning goed werkend te krijgen. Dit commando wordt uitgevoerd als je naar dit repository via SSH pushed; en dan kunnen andere mensen clonen met behulp van zoiets als +Dat is alles. De `post-update` hook, die standaard bij Git zit, voert het noodzakelijke commando uit (`git update-server-info`) om HTTP fetching en cloning goed werkend te krijgen. Dit commando wordt uitgevoerd als je naar dit repository via SSH pusht; en dan kunnen andere mensen clonen met behulp van zoiets als $ git clone http://example.com/gitproject.git @@ -291,7 +291,7 @@ Wat doet deze `post-update` haak? Het ziet er ongeveer zo uit: #!/bin/sh exec git-update-server-info -Dit betekent dat wanneer je naar de server via SSH pushed, Git dit commando uitvoert om de benodigde bestanden voor HTTP fetching te verversen. +Dit betekent dat wanneer je naar de server via SSH pusht, Git dit commando uitvoert om de benodigde bestanden voor HTTP fetching te verversen. Vervolgens moet je een VirtualHost toevoeging in je Apache configuratie aanmaken, met de document root als de hoofdmap van je Git projecten. Hier nemen we aan dat je joker DNS ingesteld hebt om `*.gitserver` door te sturen naar waar je dit alles draait: @@ -360,7 +360,7 @@ Nogmaals, GitWeb kan geserveerd worden met iedere CGI capabele web server; als j De publieke sleutels van alle gebruikers in een `authorized_keys` bestand bewaren voor toegang werkt slechts tijdelijk goed. Als je honderden gebruikers hebt, dan is het moeizaam om dat proces te beheersen. Je moet iedere keer in de server inloggen, en er is geen toegangscontrole — iedereen in het bestand heeft lees- en schrijftoegang op ieder project. -Op dit punt wil je je misschien wenden tot een veelgebruikt software project genaamd Gitosis. Gitosis is in feite een set scripts die je helpen het `authorized_keys` bestand te beheren en eenvoudige toegangscontrole te implementeren. Het meest interessante gedeelte is dat de gebruikers interface voor deze applicatie om mensen toe te voegen en toegang te bepalen, geen web interface is maar een speciale Git repository. Je stelt de informatie in in dat project; en als je het pushed, dan herconfigureert Gitosis de server op basis van dat project, wat stoer is. +Op dit punt wil je je misschien wenden tot een veelgebruikt software project genaamd Gitosis. Gitosis is in feite een set scripts die je helpen het `authorized_keys` bestand te beheren en eenvoudige toegangscontrole te implementeren. Het meest interessante gedeelte is dat de gebruikers interface voor deze applicatie om mensen toe te voegen en toegang te bepalen, geen web interface is maar een speciale Git repository. Je stelt de informatie in in dat project; en als je het pusht, dan herconfigureert Gitosis de server op basis van dat project, wat stoer is. Gitosis installeren is niet de makkelijkste taak ooit, maar het is ook niet te moeilijk. Het is het makkelijkst om er een Linux server voor te gebruiken — deze voorbeelden gebruiken een standaard Ubuntu 8.10 server. @@ -503,7 +503,7 @@ Nu kan John het project clonen en updates krijgen, maar Gitosis zal hem niet toe writable = another_iphone_project members = @mobile_committers john -Als je problemen hebt, kan het handig zijn om `loglevel=DEBUG` onder de `[gitosis]` sectie te zetten. Als je je push-toegang bent verloren door een kapotte configuratie te pushen, kun je het handmatig repareren in het bestand `/home/git/.gitosis.conf` op de server — het bestand waar Gitosis zijn informatie vandaan haalt. Een push naar het project neemt het `gitosis.conf` bestand dat je zojuist gepushed hebt en stopt het daar. Als je het bestand handmatig aanpast, zal het zo blijven totdat de volgende succesvolle push gedaan wordt naar het `gitosis-admin` project. +Als je problemen hebt, kan het handig zijn om `loglevel=DEBUG` onder de `[gitosis]` sectie te zetten. Als je je push-toegang bent verloren door een kapotte configuratie te pushen, kun je het handmatig repareren in het bestand `/home/git/.gitosis.conf` op de server — het bestand waar Gitosis zijn informatie vandaan haalt. Een push naar het project neemt het `gitosis.conf` bestand dat je zojuist gepusht hebt en stopt het daar. Als je het bestand handmatig aanpast, zal het zo blijven totdat de volgende succesvolle push gedaan wordt naar het `gitosis-admin` project. ## Gitolite ## @@ -603,7 +603,7 @@ Je kunt permissies instellen op "ref" niveau. In het volgende voorbeeld mogen st RW refs/tags/rc[0-9] = @engineers RW+ = @admins -De expressie achter de `RW` of `RW+` is een reguliere expressie (regex), waarmee de ref naam (ref) waarnaar gepushed wordt, wordt gecontroleerd. Dus daarom noemen we het een "refex"! Natuurlijk kan een refex veel krachtiger zijn dan hier getoond wordt, dus overdrijf niet als je niet op je gemak bent met perl regexen. +De expressie achter de `RW` of `RW+` is een reguliere expressie (regex), waarmee de ref naam (ref) waarnaar gepusht wordt, wordt gecontroleerd. Dus daarom noemen we het een "refex"! Natuurlijk kan een refex veel krachtiger zijn dan hier getoond wordt, dus overdrijf niet als je niet op je gemak bent met perl regexen. En, zoals je waarschijnlijk al geraden had, zet Gitolite `refs/heads/` er als een syntactisch gemak voor als de refex niet begint met `refs/`. @@ -725,7 +725,7 @@ Vervolgens zul je je Gitosis server moeten vertellen welke repositories je ongev [repo iphone_project] daemon = yes -Als dat gecommit en gepushed is, dan zou je draaiende daemon verzoeken moeten serveren aan iedereen die toegang heeft op poort 9418 van je server. +Als dat gecommit en gepusht is, dan zou je draaiende daemon verzoeken moeten serveren aan iedereen die toegang heeft op poort 9418 van je server. Als je besluit om Gitosis niet te gebruiken, maar je wilt toch een Git daemon instellen, dan moet je dit op ieder project uitvoeren waarvoor je de Git daemon wilt laten serveren: @@ -747,7 +747,7 @@ Je kunt instellen welke projecten GitWeb gebruikers laat bladeren door een `gitw daemon = yes gitweb = yes -Als je nu het project commit en pushed, start GitWeb automatisch met het tonen van je iphone project. +Als je nu het project commit en pusht, start GitWeb automatisch met het tonen van je iphone project. ## Hosted Git ## @@ -856,7 +856,7 @@ Als je toegang van individuen moet intrekken, dan kun je de "revoke" link klikke ### Je project ### -Nadat je je project gepushed hebt, of geïmporteerd vanuit Subversion, heb je een hoofd project pagina die er uitziet zoals Figuur 4-13. +Nadat je je project gepusht hebt, of geïmporteerd vanuit Subversion, heb je een hoofd project pagina die er uitziet zoals Figuur 4-13. Insert 18333fig0413.png Figuur 4-13. Een GitHub project hoofdpagina. diff --git a/nl/05-distributed-git/01-chapter5.markdown b/nl/05-distributed-git/01-chapter5.markdown index b3404380a..5022c8d40 100644 --- a/nl/05-distributed-git/01-chapter5.markdown +++ b/nl/05-distributed-git/01-chapter5.markdown @@ -17,7 +17,7 @@ Figuur 5-1. Gecentraliseerde Werkwijze. Dit betekent dat als twee ontwikkelaars clonen van het gecentraliseerde punt en beide wijzigingen doen, de eerste ontwikkelaar zijn wijzigingen terug kan zetten zonder problemen. De tweede ontwikkelaar zal het werk van de eerste in het zijne moeten samenvoegen voordat hij het zijne kan terugzetten, om zo niet het werk van de eerste te overschrijven. Dit concept werkt zo in Git zoals het ook werkt in Subversion (of ieder ander CVCS), en dit model werkt perfect in Git. -Als je een klein team hebt, of al vertrouwd bent met een gecentraliseerde werkwijze in je bedrijf of team, dan kun je eenvoudig doorgaan met het gebruiken van die werkwijze met Git. Stel eenvoudigweg een enkel repository in, en geef iedereen in je team terugzettoegang; Git zal gebruikers niet toestaan om elkaars wijzigingen te overschrijven. Als een ontwikkelaar cloned, wijzigingen maakt, en dan probeert zijn wijzigingen terug te zetten terwijl een andere ontwikkelaar de zijne in de tussentijd heeft teruggezet, dan zal de server de wijzigingen van die ontwikkelaar weigeren. "Non-fast-forward-wijzigingen" kunnen niet teruggezet worden alvorens de conflicten worden opgelost. +Als je een klein team hebt, of al vertrouwd bent met een gecentraliseerde werkwijze in je bedrijf of team, dan kun je eenvoudig doorgaan met het gebruiken van die werkwijze met Git. Stel eenvoudigweg een enkel repository in, en geef iedereen in je team terugzettoegang; Git zal gebruikers niet toestaan om elkaars wijzigingen te overschrijven. Als een ontwikkelaar clonet, wijzigingen maakt, en dan probeert zijn wijzigingen terug te zetten terwijl een andere ontwikkelaar de zijne in de tussentijd heeft teruggezet, dan zal de server de wijzigingen van die ontwikkelaar weigeren. "Non-fast-forward-wijzigingen" kunnen niet teruggezet worden alvorens de conflicten worden opgelost. Deze werkwijze is voor een hoop mensen aantrekkelijk omdat het een wijze is waarmee veel mensen bekend zijn en zich op hun gemak bij voelen. ### Integratie-manager werkwijze ### @@ -25,7 +25,7 @@ Deze werkwijze is voor een hoop mensen aantrekkelijk omdat het een wijze is waar Omdat Git je toestaat om meerdere remote repositories te hebben, is het mogelijk om een werkwijze te hebben waarbij iedere ontwikkelaar schrijftoegang heeft tot zijn eigen publieke repository en leestoegang op de andere. Dit scenario heeft vaak een gezagdragend repository dat het "officiële" project voorstelt. Om bij te kunnen dragen tot dat project, maak je je eigen publieke clone van het project en zet je wijzigingen daarin terug. Daarna stuur je een verzoek naar de eigenaar van het hoofdproject om jouw wijzigingen binnen te halen. Hij kan je repository toevoegen als een remote, je wijzigingen lokaal testen, ze in zijn branch samenvoegen, en naar zijn repository terugzetten. Het proces werkt als volgt (zie Figuur 5-2): 1. De projecteigenaar zet terug naar zijn eigen repository. -2. Een bijdrager cloned dat repository en maakt wijzigingen. +2. Een bijdrager clonet dat repository en maakt wijzigingen. 3. De bijdrager zet terug naar zijn eigen publieke kopie. 4. De bijdrager stuurt de eigenaar een e-mail met de vraag om de wijzigingen binnen te halen. 5. De eigenaar voegt het repo van de bijdrager toe als een remote en voegt lokaal samen. @@ -113,7 +113,7 @@ In de volgende voorbeelden, en verder door de rest van dit boek, zal ik omwille De eenvoudigste opzet die je waarschijnlijk zult tegenkomen is een besloten project met één of twee andere ontwikkelaars. Met besloten bedoel ik gesloten broncode – zonder leestoegang voor de buitenwereld. Jij en de andere ontwikkelaars hebben allemaal terugzet toegang op het repository. In deze omgeving kun je een werkwijze aanhouden die vergelijkbaar is met wat je zou doen als je Subversion of een andere gecentraliseerd systeem zou gebruiken. Je hebt nog steeds de voordelen van zaken als offline committen en veel eenvoudiger branchen en samenvoegen, maar de werkwijze kan erg vergelijkbaar zijn; het grote verschil is dat het samenvoegen aan de client-kant gebeurt tijdens het committen in plaats van aan de server-kant. -Laten we eens kijken hoe het er uit zou kunnen zien als twee ontwikkelaars samen beginnen te werken met een gedeelde repository. De eerste ontwikkelaar, John, cloned de repository, maakt een wijziging, en commit lokaal. (Ik vervang de protocol berichten met `...` in deze voorbeelden om ze iets in te korten.) +Laten we eens kijken hoe het er uit zou kunnen zien als twee ontwikkelaars samen beginnen te werken met een gedeelde repository. De eerste ontwikkelaar, John, clonet de repository, maakt een wijziging, en commit lokaal. (Ik vervang de protocol berichten met `...` in deze voorbeelden om ze iets in te korten.) # John's Machine $ git clone john@githost:simplegit.git @@ -125,7 +125,7 @@ Laten we eens kijken hoe het er uit zou kunnen zien als twee ontwikkelaars samen [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) -De tweede ontwikkelaar, Jessica, doet hetzelfde – cloned de repository en commit een wijziging: +De tweede ontwikkelaar, Jessica, doet hetzelfde – clonet de repository en commit een wijziging: # Jessica's Machine $ git clone jessica@githost:simplegit.git @@ -790,7 +790,7 @@ Als de onderwerpen nog werk nodig hebben, dan worden ze in plaats daarvan sameng Insert 18333fig0525.png Figuur 5-25. Bijgedragen onderwerp branches samenvoegen in langlopende integratie branches. -Als een onderwerp branch uiteindelijk is samengevoegd in `master`, dan wordt het verwijderd van het repository. Het Git project heeft ook een `main` branch, die geforked is van de laatste vrijgave om teruggewerkte patches te leveren in het geval een onderhoudsvrijgave benodigd is. Dus, als je het Git repository cloned, dan heb je vier branches die je kunt uitchecken om het project in verschillende stadia van ontwikkeling te evalueren, afhankelijk van hoe nieuw je alles wilt hebben of hoe je wil bijdragen; en de beheerder heeft een gestructureerde werkwijze om ze te helpen nieuwe bijdragen aan de tand te voelen. +Als een onderwerp branch uiteindelijk is samengevoegd in `master`, dan wordt het verwijderd van het repository. Het Git project heeft ook een `main` branch, die geforked is van de laatste vrijgave om teruggewerkte patches te leveren in het geval een onderhoudsvrijgave benodigd is. Dus, als je het Git repository clonet, dan heb je vier branches die je kunt uitchecken om het project in verschillende stadia van ontwikkeling te evalueren, afhankelijk van hoe nieuw je alles wilt hebben of hoe je wil bijdragen; en de beheerder heeft een gestructureerde werkwijze om ze te helpen nieuwe bijdragen aan de tand te voelen. #### Rebasen en cherry pick werkwijzen #### diff --git a/nl/06-git-tools/01-chapter6.markdown b/nl/06-git-tools/01-chapter6.markdown index edd83de41..5db811a76 100644 --- a/nl/06-git-tools/01-chapter6.markdown +++ b/nl/06-git-tools/01-chapter6.markdown @@ -527,7 +527,7 @@ Dat plaatst je in je teksteditor, met je laatste commit bericht erin, klaar voor Als je hebt gecommit en je wilt het snapshot dat je gecommit hebt wijzigen, door het toevoegen of wijzigen van bestanden, misschien omdat je vergeten was een nieuw bestand toe te voegen toen je committe, werkt het proces ongeveer op dezelfde manier. Je staged de wijzigingen die je wilt door een bestand te wijzigen en `git add` er op uit te voeren, of `git rm` op een gevolgd bestand, en de daaropvolgende `git commit --amend` pakt je huidige staging area en maakt dat het snapshot voor de nieuwe commit. -Je moet oppassen met deze techniek, omdat het amenden de SHA-1 van de commit wijzigt. Het is vergelijkbaar met een kleine rebase – niet je laatste commit wijzigen als je die al gepushed hebt. +Je moet oppassen met deze techniek, omdat het amenden de SHA-1 van de commit wijzigt. Het is vergelijkbaar met een kleine rebase – niet je laatste commit wijzigen als je die al gepusht hebt. ### Meerdere commit berichten wijzigen ### @@ -537,7 +537,7 @@ Bijvoorbeeld, als je de laatste drie commit berichten wilt veranderen, of een va $ git rebase -i HEAD~3 -Onthoud ook dat dit een rebase commando is – iedere commit in de serie `HEAD~3..HEAD` zal worden herschreven, of je het bericht wijzigt of niet. Voeg geen commit toe die je al naar een centrale server gepushed hebt – als je dit doet breng je andere gebruikers in de war door ze een alternatieve versie van dezelfde wijziging te geven. +Onthoud ook dat dit een rebase commando is – iedere commit in de serie `HEAD~3..HEAD` zal worden herschreven, of je het bericht wijzigt of niet. Voeg geen commit toe die je al naar een centrale server gepusht hebt – als je dit doet breng je andere gebruikers in de war door ze een alternatieve versie van dezelfde wijziging te geven. Dit commando uitvoeren geeft je een lijst met commits in je tekst editor die er ongeveer zo uit ziet: @@ -669,7 +669,7 @@ Git zal de laatste commit (`a5f4a0d`) in het script toepassen, en je geschiedeni 35cfb2b updated README formatting f3cc40e changed my name a bit -Nogmaals, dit veranderd alle SHA's van alle commits in je lijst, dus zorg er voor dat er geen commit in die lijst zit die je al naar een gedeeld repository gepushed hebt. +Nogmaals, dit veranderd alle SHA's van alle commits in je lijst, dus zorg er voor dat er geen commit in die lijst zit die je al naar een gedeeld repository gepusht hebt. ### De nucleaire optie: filter-branch ### @@ -759,7 +759,7 @@ Dit is heel handig. Normaal krijg je als de originele commit de commit waar je d Een bestand annoteren helpt als je eenmaal weet waar het probleem zit. Als je niet weet wat er kapot is, en er zijn vele dozijnen of honderden commits geweest sinds de laatste staat waarvan je weet dat de code werkte, dan zul je waarschijnlijk bij `git bisect` aankloppen voor hulp. Het `bisect` commando zoekt binair door je commitgeschiedenis om je zo snel als mogelijk te helpen identificeren welke commit het issue introduceerde. -Stel dat je zojuist een release van je code naar een productie omgeving gepushed hebt, en je krijgt bug rapporten terug dat er iets gebeurd dat niet in je development omgeving gebeurde en je kunt je niet voorstellen waarom de code dat aan het doen is. Je gaat terug naar je code, en het blijkt dat je het probleem kunt reproduceren, maar je kunt niet zien wat er verkeerd gaat. Je kunt de code bisecten om het uit te vinden. Als eerste voer je `git bisect start` uit om aan de gang te gaan, en dan gebruik je `git bisect bad` om het systeem te vertellen dat de huidige commit kapot is. Dan moet je bisect vertellen wanneer de laatste goede status was, door `git bisect good [goede_commit]` te gebruiken: +Stel dat je zojuist een release van je code naar een productie omgeving gepusht hebt, en je krijgt bug rapporten terug dat er iets gebeurd dat niet in je development omgeving gebeurde en je kunt je niet voorstellen waarom de code dat aan het doen is. Je gaat terug naar je code, en het blijkt dat je het probleem kunt reproduceren, maar je kunt niet zien wat er verkeerd gaat. Je kunt de code bisecten om het uit te vinden. Als eerste voer je `git bisect start` uit om aan de gang te gaan, en dan gebruik je `git bisect bad` om het systeem te vertellen dat de huidige commit kapot is. Dan moet je bisect vertellen wanneer de laatste goede status was, door `git bisect good [goede_commit]` te gebruiken: $ git bisect start $ git bisect bad @@ -841,7 +841,7 @@ Eerst zie je het `.gitmodules` bestand. Dit is een configuratie bestand dat de m path = rack url = git://github.com/chneukirchen/rack.git -Als je meerdere submodules hebt, zul je meerdere vermeldingen hebben in dit bestand. Het is belangrijk om te zien dat dit bestand net als je andere bestanden ook onder versiebeheer staat, zoals je `.gitignore` bestand. Het wordt gepushed en gepulled samen met de rest van je project. Op deze manier weten andere mensen die je project clonen waar ze de submodule projecten vandaan moeten halen. +Als je meerdere submodules hebt, zul je meerdere vermeldingen hebben in dit bestand. Het is belangrijk om te zien dat dit bestand net als je andere bestanden ook onder versiebeheer staat, zoals je `.gitignore` bestand. Het wordt gepusht en gepulled samen met de rest van je project. Op deze manier weten andere mensen die je project clonen waar ze de submodule projecten vandaan moeten halen. De andere vermelding in de `git status` output is de rack regel. Als je `git diff` daarop uitvoert zul je iets interessants zien: @@ -955,7 +955,7 @@ Dit is het geval omdat de pointer die je hebt voor de submodule niet is wat eige Je moet dit iedere keer dat je een submodule wijziging pulled in het hoofdproject. Het is vreemd, maar het werkt. -Er probleem doet zich voor als een developer een locale wijziging in en submodule doet en die niet naar een publieke server pushed. Dan, zullen ze een pointer naar de niet-publieke status committen en naar het superproject pushen. Als andere developers dan `git submodule update` proberen uit te voeren, dan zal het submodule systeem de commit die gerefereerd wordt niet kunnen vinden, omdat het alleen op het systeem van de eerste developer bestaat. Als dat gebeurd, zul je een foutmelding als deze zien: +Er probleem doet zich voor als een developer een locale wijziging in en submodule doet en die niet naar een publieke server pusht. Dan, zullen ze een pointer naar de niet-publieke status committen en naar het superproject pushen. Als andere developers dan `git submodule update` proberen uit te voeren, dan zal het submodule systeem de commit die gerefereerd wordt niet kunnen vinden, omdat het alleen op het systeem van de eerste developer bestaat. Als dat gebeurd, zul je een foutmelding als deze zien: $ git submodule update fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 @@ -1007,7 +1007,7 @@ Van branches wisselen die submodules bevatten kan ook lastig zijn. Als je een ni # # rack/ -Je moet hem verplaatsen of verwijderen, waarna je hem opnieuw moet clonen als je terug wisselt – en je loopt kans om locale wijzigingen of branches te verliezen die je niet omhoog gepushed hebt. +Je moet hem verplaatsen of verwijderen, waarna je hem opnieuw moet clonen als je terug wisselt – en je loopt kans om locale wijzigingen of branches te verliezen die je niet omhoog gepusht hebt. De laatste grote valkuil waar veel mensen in lopen heeft te maken met het wisselen van submappen naar submodules. Als je bestanden in je project aan het volgen bent, en je wilt ze in een submodule verplaatsen, dan moet je voorzichtig zijn of anders zal Git boos op je worden. Stel dat je de rack bestanden in een submap van je project hebt, en je wilt die naar een submodule wijzigen. Als je de submap weggooit en dan `submodule add` uitvoerd, begint Git naar je te schreeuwen: diff --git a/nl/07-customizing-git/01-chapter7.markdown b/nl/07-customizing-git/01-chapter7.markdown index f0a10bdf4..583a2eaf5 100644 --- a/nl/07-customizing-git/01-chapter7.markdown +++ b/nl/07-customizing-git/01-chapter7.markdown @@ -251,7 +251,7 @@ Of je kunt Git vragen om automatisch deze problemen te repareren alvorens de pat $ git apply --whitespace=fix -Deze opties zijn ook op de git rebase optie van toepassing. Als je witruimte problemen gecommit hebt maar ze nog niet stroomopwaarts gepushed hebt, kun je een `rebase` uitvoeren met de `--whitespace=fix` optie uitvoeren om Git automatisch witruimte problemen te laten repareren zodra het de patches herschrijft. +Deze opties zijn ook op de git rebase optie van toepassing. Als je witruimte problemen gecommit hebt maar ze nog niet stroomopwaarts gepusht hebt, kun je een `rebase` uitvoeren met de `--whitespace=fix` optie uitvoeren om Git automatisch witruimte problemen te laten repareren zodra het de patches herschrijft. ### Server configuratie ### @@ -267,7 +267,7 @@ Nu zal Git de integriteit van je repository controleren voor iedere push geaccep #### receive.denyNonFastForwards #### -Als je commits rebased die je al gepushed hebt en dan nog eens pushed, of op een andere manier een commit probeert te pushen naar een remote branch die niet de commit bevat waarnaar de remote branch op het moment wijst, dan wordt dat afgewezen. Dit is over het algemeen een goed beleid; maar in het geval van de rebase, kun je besluiten dat je weet waar je mee bezig bent en kun je de remote branch geforceerd vernieuwen door een `-f` vlag met je push commando mee te geven. +Als je commits rebased die je al gepusht hebt en dan nog eens pusht, of op een andere manier een commit probeert te pushen naar een remote branch die niet de commit bevat waarnaar de remote branch op het moment wijst, dan wordt dat afgewezen. Dit is over het algemeen een goed beleid; maar in het geval van de rebase, kun je besluiten dat je weet waar je mee bezig bent en kun je de remote branch geforceerd vernieuwen door een `-f` vlag met je push commando mee te geven. Om de mogelijkheid van het geforceerd vernieuwen van remote branches naar niet fast-forward referenties uit te schakelen, stel je `receive.denyNonFastForwards` in: @@ -277,7 +277,7 @@ Een andere manier waarop je dit kunt doen is het instellen van ontvangst haken o #### receive.denyDeletes #### -Een van de wegen om een `denyNonFastForwards` beleid heen is dat de gebruiker de branch verwijderd en het dan opnieuw terug pushed met de nieuwe referentie. In nieuwere versies van Git (beginnend bij versie 1.6.1), kun je `receive.denyDeletes` op true zetten: +Een van de wegen om een `denyNonFastForwards` beleid heen is dat de gebruiker de branch verwijderd en het dan opnieuw terug pusht met de nieuwe referentie. In nieuwere versies van Git (beginnend bij versie 1.6.1), kun je `receive.denyDeletes` op true zetten: $ git config --system receive.denyDeletes true @@ -518,7 +518,7 @@ De laatste haak die uitgevoerd wordt tijdens een `git am` operatie is de `post-a #### Andere client haken #### -De `pre-rebase` haak wordt uitgevoerd voordat je ook maar iets rebased, en kan het proces afbreken door met een waarde anders dan nul te eindigen. Je kunt deze haak gebruiken om tegen te gaan dat commits die al gepushed zijn gerebased worden. De voorbeeld `pre-rebase` haak die Git installeert doet dit, alhoewel deze er vanuit gaat dat next de naam is van de branch die je publiceert. Je zult dat waarschijnlijk moeten veranderen in de naam van je stabiele gepubliceerde branch. +De `pre-rebase` haak wordt uitgevoerd voordat je ook maar iets rebased, en kan het proces afbreken door met een waarde anders dan nul te eindigen. Je kunt deze haak gebruiken om tegen te gaan dat commits die al gepusht zijn gerebased worden. De voorbeeld `pre-rebase` haak die Git installeert doet dit, alhoewel deze er vanuit gaat dat next de naam is van de branch die je publiceert. Je zult dat waarschijnlijk moeten veranderen in de naam van je stabiele gepubliceerde branch. Nadat je een succesvolle `git checkout` uitgevoerd hebt, wordt de `post-checkout` haak uitgevoerd; je kunt het gebruiken om je werkmap goed in te stellen voor je project omgeving. Dit kan het invoegen van grote binaire bestanden die je niet in versie beheer wil hebben betekenen, of het automatisch genereren van documentatie, of iets in die geest. @@ -530,7 +530,7 @@ Naast de client-kant haken, kun je als systeem administrator ook een paar belang #### pre-receive en post-receive #### -Het eerste script dat uitgevoerd wordt tijdens het afhandelen van een push van een client is `pre-receive`. Het aanvaardt een lijst van referenties die worden gepushed op stdin; als het eindigt met een andere waarde dan nul, worden ze allen geweigerd. Je kunt deze haak gebruiken om dingen te doen als valideren dat geen van de vernieuwde referenties een non-fast-forward is; of om te controleren dat de gebruiker die de push doet ook creatie, verwijder, of push toegang of toegang om vernieuwingen te pushen naar alle bestanden die ze proberen aan te passen met de push. +Het eerste script dat uitgevoerd wordt tijdens het afhandelen van een push van een client is `pre-receive`. Het aanvaardt een lijst van referenties die worden gepusht op stdin; als het eindigt met een andere waarde dan nul, worden ze allen geweigerd. Je kunt deze haak gebruiken om dingen te doen als valideren dat geen van de vernieuwde referenties een non-fast-forward is; of om te controleren dat de gebruiker die de push doet ook creatie, verwijder, of push toegang of toegang om vernieuwingen te pushen naar alle bestanden die ze proberen aan te passen met de push. De `post-receive` haak wordt uitgevoerd nadat het hele proces afgerond is, en hij kan gebruikt worden om andere services te vernieuwen of gebruikers te notificeren. Het aanvaardt dezelfde gegevens op stdin als de `pre-receive` haak. Voorbeelden zijn een e-mail sturen naar een lijst, een continue integratie server notificeren, of het vernieuwen van een ticket-volg systeem – je kunt zelfs de commit boodschappen doorlopen om te zien of er nog tickets zijn die moeten worden geopend, aangepast of afgesloten moeten worden. Dit script kan het push proces niet stoppen, maar de client verbreekt de connectie niet totdat het afgerond is; dus ben voorzichtig als je iets probeert te doen dat een lange tijd in beslag neemt. @@ -546,7 +546,7 @@ Ik heb Ruby gebruikt om ze te schrijven, zowel omdat het mijn voorkeur script ta ### Server-kant haak ### -Al het werk aan de server kant zal in het update bestand in je haken map gaan. Het update bestand zal eens per gepushte branch uitgevoerd worden en aanvaardt de referentie waarnaar gepushed wordt, de oude revisie waar die branch was, en de nieuwe gepushte revisie. Je hebt ook toegang tot de gebruiker die de push doet, als de push via SSH gedaan wordt. Als je iedereen hebt toegestaan om connectie te maken als één gebruiker (zoals "git") via publieke sleutel authenticatie, dan moet je misschien die gebruiker een shell wrapper geven die bepaalt welke gebruiker er connectie maakt op basis van de publieke sleutel, en een omgevingsvariabele instelt met daarin die gebruiker. Hier ga ik er vanuit dat de gebruiker in de `$USER` omgevingsvariabele staat, dus begint je update script met het verzamelen van alle gegevens die het nodig heeft: +Al het werk aan de server kant zal in het update bestand in je haken map gaan. Het update bestand zal eens per gepushte branch uitgevoerd worden en aanvaardt de referentie waarnaar gepusht wordt, de oude revisie waar die branch was, en de nieuwe gepushte revisie. Je hebt ook toegang tot de gebruiker die de push doet, als de push via SSH gedaan wordt. Als je iedereen hebt toegestaan om connectie te maken als één gebruiker (zoals "git") via publieke sleutel authenticatie, dan moet je misschien die gebruiker een shell wrapper geven die bepaalt welke gebruiker er connectie maakt op basis van de publieke sleutel, en een omgevingsvariabele instelt met daarin die gebruiker. Hier ga ik er vanuit dat de gebruiker in de `$USER` omgevingsvariabele staat, dus begint je update script met het verzamelen van alle gegevens die het nodig heeft: #!/usr/bin/env ruby @@ -561,9 +561,9 @@ Ja, ik gebruik een globale variabele. Veroordeel me niet – het is makkelijker #### Een specifiek commit-bericht formaat afdwingen #### -Je eerste uitdaging is afdwingen dat ieder commit bericht moet voldoen aan een specifiek formaat. Om maar een doel te hebben, gaan we er vanuit dat ieder bericht een stuk tekst bevat dat eruit ziet asl "ref: 1234", omdat je wil dat iedere commit gekoppeld is aan een werkonderdeel in je ticket systeem. Je moet kijken naar iedere commit die gepushed wordt, zien dat die tekst in de commit boodschap zit, en als de tekst niet in één van de commits zit, met niet nul eindigen zodat de push geweigerd wordt. +Je eerste uitdaging is afdwingen dat ieder commit bericht moet voldoen aan een specifiek formaat. Om maar een doel te hebben, gaan we er vanuit dat ieder bericht een stuk tekst bevat dat eruit ziet asl "ref: 1234", omdat je wil dat iedere commit gekoppeld is aan een werkonderdeel in je ticket systeem. Je moet kijken naar iedere commit die gepusht wordt, zien dat die tekst in de commit boodschap zit, en als de tekst niet in één van de commits zit, met niet nul eindigen zodat de push geweigerd wordt. -Je kunt de lijst met alle SHA-1 waarden van alle commits die gepushed worden verkrijgen door de `$newrev` en `$oldrev` waarden te pakken en ze aan een Git sanitaire voorzieningen commando genaamd `git rev-list` te geven. Dit is eigenlijk het `git log` commando, maar standaard voert het alleen de SHA-1 waarden uit en geen andere informatie. Dus, om een lijst te krijgen van alle commit SHA's die worden geïntroduceerd tussen één commit SHA en een andere, kun je zoiets als dit uitvoeren: +Je kunt de lijst met alle SHA-1 waarden van alle commits die gepusht worden verkrijgen door de `$newrev` en `$oldrev` waarden te pakken en ze aan een Git sanitaire voorzieningen commando genaamd `git rev-list` te geven. Dit is eigenlijk het `git log` commando, maar standaard voert het alleen de SHA-1 waarden uit en geen andere informatie. Dus, om een lijst te krijgen van alle commit SHA's die worden geïntroduceerd tussen één commit SHA en een andere, kun je zoiets als dit uitvoeren: $ git rev-list 538c33..d14fc7 d14fc7c847ab946ec39590d87783c69b031bdfb7 @@ -589,7 +589,7 @@ Een simpele manier om de commit boodschap te krijgen van een commit waarvan je d $ git cat-file commit ca82a6 | sed '1,/^$/d' changed the version number -Je kunt die spreuk gebruiken om de commit boodschap te pakken van iedere commit die probeert te worden gepushed en eindigen als je ziet dat er iets is wat niet past. Om het script te eindigen en de push te weigeren, eindig je met niet nul. De hele methode ziet er zo uit: +Je kunt die spreuk gebruiken om de commit boodschap te pakken van iedere commit die probeert te worden gepusht en eindigen als je ziet dat er iets is wat niet past. Om het script te eindigen en de push te weigeren, eindig je met niet nul. De hele methode ziet er zo uit: $regex = /\[ref: (\d+)\]/ @@ -610,7 +610,7 @@ Door dat in je `update` script te stoppen, zal het updates weigeren die commits #### Een gebruiker-gebaseerd ACL systeem afdwingen #### -Stel dat je een mechanisme wil toevoegen dat gebruik maakt van een toegangscontrole lijst (ACL) die specificeert welke gebruikers zijn toegestaan om wijzigingen te pushen naar welke delen van je project. Sommige mensen hebben volledige toegang, en andere hebben alleen toegang om wijzigingen te pushen naar bepaalde submappen of specifieke bestanden. Om dit af te dwingen zul je die regels schrijven in een bestand genaamd `acl` dat in je bare Git repository op de server leeft. Je zult de `update` haak naar die regels laten kijken, zien welke bestanden worden geïntroduceerd voor alle commits die gepushed worden, en bepalen of de gebruiker die de push doet toegang heeft om al die bestanden te wijzigen. +Stel dat je een mechanisme wil toevoegen dat gebruik maakt van een toegangscontrole lijst (ACL) die specificeert welke gebruikers zijn toegestaan om wijzigingen te pushen naar welke delen van je project. Sommige mensen hebben volledige toegang, en andere hebben alleen toegang om wijzigingen te pushen naar bepaalde submappen of specifieke bestanden. Om dit af te dwingen zul je die regels schrijven in een bestand genaamd `acl` dat in je bare Git repository op de server leeft. Je zult de `update` haak naar die regels laten kijken, zien welke bestanden worden geïntroduceerd voor alle commits die gepusht worden, en bepalen of de gebruiker die de push doet toegang heeft om al die bestanden te wijzigen. Het eerste dat je zult doen is je ACL schrijven. Hier zul je een formaat gebruiken dat erg lijkt op het CVS ACL mechanisme: het gebruikt een serie regels, waarbij het eerste veld `avail` of `unavail` is, het volgende veld een komma gescheiden lijst van de gebruikers is waarvoor de regel geldt, en het laatste veld het pad is waarvoor de regel geldt (leeg betekent open toegang). Alle velden worden gescheiden door een pipe (`|`) karakter. @@ -649,7 +649,7 @@ Op het ACL bestand dat je eerder bekeken hebt, zal deze `get_acl_access_data` me "usinclair"=>["doc"], "ebronte"=>["doc"]} -Nu dat je de rechten bepaald hebt, moet je bepalen welke paden de commits die gepushed worden hebben aangepast, zodat je er zeker van kunt zijn dat de gebruiker die de push doet daar ook toegang tot heeft. +Nu dat je de rechten bepaald hebt, moet je bepalen welke paden de commits die gepusht worden hebben aangepast, zodat je er zeker van kunt zijn dat de gebruiker die de push doet daar ook toegang tot heeft. Je kunt eenvoudig zien welke bestanden gewijzigd zijn in een enkele commit met de `--name-only` optie op het `git log` commando (dat kort genoemd wordt in Hoofdstuk 2): @@ -687,7 +687,7 @@ Als je gebruik maakt van de ACL structuur die wordt teruggegeven door de `get_ac check_directory_perms -Het meeste daarvan zou makkelijk te volgen moeten zijn. Je krijgt een lijst met commits die gepushed worden naar je server met `git rev-list`. Daarna vind je, voor iedere commit, de bestanden die aangepast worden en stelt vast of de gebruiker die pushed toegang heeft tot alle paden die worden aangepast. Een Ruby-isme dat wellicht niet duidelijk is is `path.index(access_path) == 0`, wat waar is als het pad begint met `access_path` – dit zorgt ervoor dat `access_path` niet slechts in één van de toegestane paden zit, maar dat een toegestaan pad begint met ieder aangeraakt pad. +Het meeste daarvan zou makkelijk te volgen moeten zijn. Je krijgt een lijst met commits die gepusht worden naar je server met `git rev-list`. Daarna vind je, voor iedere commit, de bestanden die aangepast worden en stelt vast of de gebruiker die pusht toegang heeft tot alle paden die worden aangepast. Een Ruby-isme dat wellicht niet duidelijk is is `path.index(access_path) == 0`, wat waar is als het pad begint met `access_path` – dit zorgt ervoor dat `access_path` niet slechts in één van de toegestane paden zit, maar dat een toegestaan pad begint met ieder aangeraakt pad. Nu kunnen je gebruikers geen commits pushen met slechte berichten of met aangepaste bestanden buiten hun toegewezen paden. @@ -834,11 +834,11 @@ moet je dit gebruiken files_modified = `git diff-index --cached --name-only HEAD` -Maar dat zijn de enige twee verschillen – voor de rest werkt het script op dezelfde manier. Een instinker is dat het van je verwacht dat je lokaal werkt als dezelfde gebruiker die pushed naar de remote machine. Als dat verschillend is, moet je de `$user` variabele handmatig instellen. +Maar dat zijn de enige twee verschillen – voor de rest werkt het script op dezelfde manier. Een instinker is dat het van je verwacht dat je lokaal werkt als dezelfde gebruiker die pusht naar de remote machine. Als dat verschillend is, moet je de `$user` variabele handmatig instellen. -Het laatste ding dat je moet doen is controleren dat je niet non-fast-forward referenties probeert te pushen, maar dat komt minder voor. Om een referentie te krijgen dat geen fast-forward is, moet je voorbij een commit rebasen die je al gepushed hebt, of een andere lokale branch naar dezelfde remote branch proberen te pushen. +Het laatste ding dat je moet doen is controleren dat je niet non-fast-forward referenties probeert te pushen, maar dat komt minder voor. Om een referentie te krijgen dat geen fast-forward is, moet je voorbij een commit rebasen die je al gepusht hebt, of een andere lokale branch naar dezelfde remote branch proberen te pushen. -Omdat de server je zal vertellen dat je geen non-fast-forward push kunt doen, en de haak de push tegenhoudt, is het enige ongelukkige ding dat je kunt proberen te vangen het rebasen van commits die je al gepushed hebt. +Omdat de server je zal vertellen dat je geen non-fast-forward push kunt doen, en de haak de push tegenhoudt, is het enige ongelukkige ding dat je kunt proberen te vangen het rebasen van commits die je al gepusht hebt. Hier is een voorbeeld pre-rebase script dat daarop controleert. Het haalt een lijst met alle commits die je op het punt staat te herschrijven, en controleert of ze al op een bepaalde manier bestaan in één van je remote referenties. Als het er een ziet die bereikbaar is vanuit een van je remote referenties, dan stopt het de rebase: @@ -865,7 +865,7 @@ Hier is een voorbeeld pre-rebase script dat daarop controleert. Het haalt een li end end -Dit script gebruikt een syntax dat niet behandeld is in de Revisie Selectie sectie van Hoofdstuk 6. Je krijgt een lijst van commits die al gepushed zijn door dit uit te voeren: +Dit script gebruikt een syntax dat niet behandeld is in de Revisie Selectie sectie van Hoofdstuk 6. Je krijgt een lijst van commits die al gepusht zijn door dit uit te voeren: git rev-list ^#{sha}^@ refs/remotes/#{remote_ref} diff --git a/nl/08-git-and-other-scms/01-chapter8.markdown b/nl/08-git-and-other-scms/01-chapter8.markdown index 8939e3033..43d6f8d3d 100644 --- a/nl/08-git-and-other-scms/01-chapter8.markdown +++ b/nl/08-git-and-other-scms/01-chapter8.markdown @@ -52,7 +52,7 @@ Alhoewel deze operatie maar een paar minuten in beslag neemt, zal het kopiëren ### Beginnen ### -Nu dat je een Subversion repository hebt met schrijftoegang, kun je door een typische werkwijze gaan. Je begint met het `git svn clone` commando, wat een volledig Subversion repository in een lokaal Git repository cloned. Onthoud dat als je van een echt beheerd Subversion repository importeert, je de `file:///tmp/test-svn` hier moet vervangen door de URL van je Subversion repository: +Nu dat je een Subversion repository hebt met schrijftoegang, kun je door een typische werkwijze gaan. Je begint met het `git svn clone` commando, wat een volledig Subversion repository in een lokaal Git repository clonet. Onthoud dat als je van een echt beheerd Subversion repository importeert, je de `file:///tmp/test-svn` hier moet vervangen door de URL van je Subversion repository: $ git svn clone file:///tmp/test-svn -T trunk -b branches -t tags Initialized empty Git repository in /Users/schacon/projects/testsvnsync/svn/.git/ @@ -87,7 +87,7 @@ Op dit punt zou je een geldig Git repository moeten hebben, dat je branches en t tags/release-2.0.2rc1 trunk -Het is belangrijk om te zien hoe dit tool je remote references een andere naamruimte toebedeeld. Als je een normaal Git repository cloned, krijg je alle branches op die remote server lokaal beschikbaar in de vorm van `origin/[branch]` – volgens de naamruimte van de remote. Maar, `git svn` gaat er vanuit dan je niet meerdere remotes hebt en bewaard al zijn referentie punten om de remote server zonder naamruimte. Je kunt het Git loodgieters commando `show-ref` gebruiken om naar al je volledige referentie namen te kijken: +Het is belangrijk om te zien hoe dit tool je remote references een andere naamruimte toebedeeld. Als je een normaal Git repository clonet, krijg je alle branches op die remote server lokaal beschikbaar in de vorm van `origin/[branch]` – volgens de naamruimte van de remote. Maar, `git svn` gaat er vanuit dan je niet meerdere remotes hebt en bewaard al zijn referentie punten om de remote server zonder naamruimte. Je kunt het Git loodgieters commando `show-ref` gebruiken om naar al je volledige referentie namen te kijken: $ git show-ref 1cbd4904d9982f386d87f88fce1c24ad7c0f0471 refs/heads/master @@ -171,7 +171,7 @@ Nu dat al jouw werk bovenop hetgeen wat op de Subversion server staat gebracht i No changes between current HEAD and refs/remotes/trunk Resetting to the latest refs/remotes/trunk -Het is belangrijk te onthouden dat `git svn` je dit alleen laat doen als de wijzigingen conflicteren, in tegenstelling tot Git dat je vereist om eerst al het stroomopwaartse werk dat je nog niet lokaal hebt te mergen voordat je kunt pushen. Als iemand anders een verandering naar een bestand pushed en daarna push jij een verandering op een ander bestand, dan zal je `dcommit` prima werken: +Het is belangrijk te onthouden dat `git svn` je dit alleen laat doen als de wijzigingen conflicteren, in tegenstelling tot Git dat je vereist om eerst al het stroomopwaartse werk dat je nog niet lokaal hebt te mergen voordat je kunt pushen. Als iemand anders een verandering naar een bestand pusht en daarna push jij een verandering op een ander bestand, dan zal je `dcommit` prima werken: $ git svn dcommit Committing to file:///tmp/test-svn/trunk ... @@ -202,7 +202,7 @@ Eens in de zoveel tijd `git svn rebase` uitvoeren zorgt er voor dat je code alti ### Git branch problemen ### -Als je je op je gemak voelt met een Git manier van werken, zul je waarschijnlijk onderwerp branches gaan maken, er werk op doen, en ze dan inmergen. Als je naar een Subversion server pushed via git svn, wil je misschien je werk iedere keer in een enkele branch rebasen in plaats van de branches samen mergen. De reden om rebasen te prefereren is dat Subversion een lineaire geschiedenis heeft, en niet omgaat met merges op de manier zoals Git dat doet, dus git svn volgt alleen de eerste ouder op het moment dat de snapshots naar Subversion commits omgezet worden. +Als je je op je gemak voelt met een Git manier van werken, zul je waarschijnlijk onderwerp branches gaan maken, er werk op doen, en ze dan inmergen. Als je naar een Subversion server pusht via git svn, wil je misschien je werk iedere keer in een enkele branch rebasen in plaats van de branches samen mergen. De reden om rebasen te prefereren is dat Subversion een lineaire geschiedenis heeft, en niet omgaat met merges op de manier zoals Git dat doet, dus git svn volgt alleen de eerste ouder op het moment dat de snapshots naar Subversion commits omgezet worden. Stel dat je geschiedenis er zoals volgt uitziet: je hebt een `experiment` branch gemaakt, twee commits gedaan, en ze dan terug in `master` gemerged. Als je dan `dcommit` zie je output zoals dit: @@ -227,7 +227,7 @@ Stel dat je geschiedenis er zoals volgt uitziet: je hebt een `experiment` branch Het uitvoeren van `dcommit` op een branch met gemergede historie werkt prima, behalve wanneer je naar je Git project historie kijkt, het geen van beide commits die je op de `experiment` branch gedaan hebt herschreven heeft – in plaats daarvan verschijnen al die wijzigingen in de SVN versie van de enkele merge commit. -Als iemand anders dat werk cloned, is alles wat ze zien de merge commit met al het werk erin gesquashed; ze zien niet de commit data met waar het vandaan kwam of wanneer het was gecommit. +Als iemand anders dat werk clonet, is alles wat ze zien de merge commit met al het werk erin gesquashed; ze zien niet de commit data met waar het vandaan kwam of wanneer het was gecommit. ### Subversion branchen ### @@ -258,7 +258,7 @@ Als je tegelijk wilt werken op meer dan één branch, dan kun je lokale branches Als je je `opera` branch nu in `trunk` (jouw `master` branch) wilt mergen, kun je dit doen met een normale `git merge`. Maar je moet een beschrijvend commit bericht meegeven (via `-m`), of de merge zal "Merge branch opera" bevatten in plaats van iets bruikbaars. -Onthoud dat, alhoewel je `git merge` gebruikt voor deze operatie, en de merge waarschijnlijk veel makkelijker gaat dan het in Subversion zou gaan (omdat Git automatisch de merge basis voor je zal detecteren), dit geen normale Git merge commit is. Je moet deze data terug pushen naar een Subversion server die geen commit aan kan die meer dan één ouder volgt; dus, nadat je het omhoog gepushed hebt, zal het eruit zien als een enkele commit waarbij al het werk van een andere branch erin gesquashed zit als een enkele commit. Nadat je een branch in een andere gemerged hebt, kun je niet eenvoudig terug gaan en op die branch verder werken, zoals je dat normaal kunt in Git. Het `dcommit` commando dat je uitvoert, wist alle informatie die kan vertellen welke branch erin gemerged was, dus opvolgende merge-basis berekeningen zullen fout gaan – de `dcommit` zal je `git merge` resultaat eruit laten zien alsof je `git merge --squash` uitgevoerd hebt. Helaas is er geen manier om deze situatie te vermijden – Subversion kan deze informatie niet opslaan, dus je zult altijd gelimiteerd zijn door zijn beperkingen zolang als je het als server gebruikt. Om problemen te vermijden, zou je de lokale branch moeten verwijderen (in dit geval `opera`), nadat je hem in trunk gemerged hebt. +Onthoud dat, alhoewel je `git merge` gebruikt voor deze operatie, en de merge waarschijnlijk veel makkelijker gaat dan het in Subversion zou gaan (omdat Git automatisch de merge basis voor je zal detecteren), dit geen normale Git merge commit is. Je moet deze data terug pushen naar een Subversion server die geen commit aan kan die meer dan één ouder volgt; dus, nadat je het omhoog gepusht hebt, zal het eruit zien als een enkele commit waarbij al het werk van een andere branch erin gesquashed zit als een enkele commit. Nadat je een branch in een andere gemerged hebt, kun je niet eenvoudig terug gaan en op die branch verder werken, zoals je dat normaal kunt in Git. Het `dcommit` commando dat je uitvoert, wist alle informatie die kan vertellen welke branch erin gemerged was, dus opvolgende merge-basis berekeningen zullen fout gaan – de `dcommit` zal je `git merge` resultaat eruit laten zien alsof je `git merge --squash` uitgevoerd hebt. Helaas is er geen manier om deze situatie te vermijden – Subversion kan deze informatie niet opslaan, dus je zult altijd gelimiteerd zijn door zijn beperkingen zolang als je het als server gebruikt. Om problemen te vermijden, zou je de lokale branch moeten verwijderen (in dit geval `opera`), nadat je hem in trunk gemerged hebt. ### Subversion commando's ### @@ -304,7 +304,7 @@ Zoals het `git svn log` commando het `svn log` commando offline simuleert, kun j 2 temporal Buffer compiler (protoc) execute the following: 2 temporal -Nogmaals, het toont geen commits die je lokaal in Git gedaan hebt, of die in de tussentijd naar Subversion gepushed zijn. +Nogmaals, het toont geen commits die je lokaal in Git gedaan hebt, of die in de tussentijd naar Subversion gepusht zijn. #### SVN server informatie #### @@ -326,7 +326,7 @@ Dit is vergelijkbaar met `blame` en `log` in dat het offline draait en alleen up #### Negeren wat Subversion negeert #### -Als je een Subversion repository cloned, die ergens `svn:ignore` eigenschappen gezet heeft, dan zul je waarschijnlijk overeenkomende `.gitignore` bestanden in willen stellen zo dat je niet per ongeluk bestanden commit die je niet had moeten committen. `git svn` heeft twee commando's die met dit probleem helpen. De eerste is `git svn create-ignore`, wat automatisch `.gitignore` bestanden voor je genereert zodat je volgende commit ze niet kan bevatten. +Als je een Subversion repository clonet, die ergens `svn:ignore` eigenschappen gezet heeft, dan zul je waarschijnlijk overeenkomende `.gitignore` bestanden in willen stellen zo dat je niet per ongeluk bestanden commit die je niet had moeten committen. `git svn` heeft twee commando's die met dit probleem helpen. De eerste is `git svn create-ignore`, wat automatisch `.gitignore` bestanden voor je genereert zodat je volgende commit ze niet kan bevatten. Het tweede commando is `git svn show-ignore`, want op stdout de regels afdrukt die je in een `.gitignore` bestand moet stoppen zodat je de output in het exclude bestand van je project kunt stoppen: @@ -353,7 +353,7 @@ Je zult leren hoe je data uit twee van de grotere professioneel gebruikte SCM sy ### Subversion ### -Als je de vorige sectie over het gebruik van `git svn` leest, kun je die instructies eenvoudig gebruiken om een `git svn clone` te doen op een repository; daarna stop je met het gebruik van de Subversion server, pushed naar de nieuwe Git server, en ga die gebruiken. Als je de historie wil hebben, kun je dat zo snel als dat je van de server kunt pullen voor elkaar krijgen (wat een tijdje kan duren). +Als je de vorige sectie over het gebruik van `git svn` leest, kun je die instructies eenvoudig gebruiken om een `git svn clone` te doen op een repository; daarna stop je met het gebruik van de Subversion server, pusht naar de nieuwe Git server, en ga die gebruiken. Als je de historie wil hebben, kun je dat zo snel als dat je van de server kunt pullen voor elkaar krijgen (wat een tijdje kan duren). Maar, de import is niet perfect; en omdat het zo lang zal duren, kun je het maar beter goed doen. Het eerste probleem is informatie over de auteurs. In Subversion heeft iedere persoon die commit een gebruikersaccount op het systeem, wat wordt opgenomen in de commit informatie. De voorbeelden in de voorgaande sectie toen `schacon` op bepaalde plaatsen zoals de `blame` output en bij `git svn log`. Als je dit beter wil transleren naar Git auteur data, dan heb je een translatie nodig van de Subversion gebruikers naar de Git auteurs. Maak een bestand genaamd `users.txt`, die deze translatie in dit formaat heeft: @@ -479,7 +479,7 @@ Als je `git log` uitvoert, kun je zien dat alle SHA-1 checksums voor de commits Update derived jamgram.c -Je import is nu klaar om naar je nieuwe Git server gepushed te worden. +Je import is nu klaar om naar je nieuwe Git server gepusht te worden. ### Een eigen importeerder ### diff --git a/nl/09-git-internals/01-chapter9.markdown b/nl/09-git-internals/01-chapter9.markdown index 6c4a0e457..be7e5a45c 100644 --- a/nl/09-git-internals/01-chapter9.markdown +++ b/nl/09-git-internals/01-chapter9.markdown @@ -396,7 +396,7 @@ in de Git broncode. De Linux kernel heeft ook een non-commit-wijzend tag object ### Remotes ### -Het derde soort referentie dat je zult zien is een remote referentie. Als je een remote toevoegt en er naar pushed, slaat Git de laatste waarde van iedere branch op die je gepushed hebt naar die remote in de `refs/remotes` map. Bijvoorbeeld, je kunt een remote genaamd `origin` toevoegen en je master branch hier naar pushen: +Het derde soort referentie dat je zult zien is een remote referentie. Als je een remote toevoegt en er naar pusht, slaat Git de laatste waarde van iedere branch op die je gepusht hebt naar die remote in de `refs/remotes` map. Bijvoorbeeld, je kunt een remote genaamd `origin` toevoegen en je master branch hier naar pushen: $ git remote add origin git@github.com:schacon/simplegit-progit.git $ git push origin master @@ -475,7 +475,7 @@ De blob is nu een andere blob, wat betekent dat alhoewel je slechts een enkele r Je hebt nu twee vrijwel identieke 12K grote objecten op je harde schijf. Zou het niet fijn zijn als Git één van de twee volledig op kon slaan, en het tweede object slechts als delta tussen die en de eerste? -Het blijkt dat dat kan. Het initiële formaat waarin Git objecten opslaat op de harde schijf wordt een los object formaat genoemd. Maar, eens in de zoveel tijd pakt Git een aantal van die objecten in een enkel binair bestand wat een packfile genoemd wordt, om wat ruimte te besparen en efficiënter te zijn. Git doet dit als je teveel losse objecten rond hebt slingeren, als je het `git gc` commando handmatig uitvoert, of als je naar een remote server pushed. Om te zien wat er gebeurd, kun je Git handmatig vragen om de objecten in te pakken met het `git gc` commando: +Het blijkt dat dat kan. Het initiële formaat waarin Git objecten opslaat op de harde schijf wordt een los object formaat genoemd. Maar, eens in de zoveel tijd pakt Git een aantal van die objecten in een enkel binair bestand wat een packfile genoemd wordt, om wat ruimte te besparen en efficiënter te zijn. Git doet dit als je teveel losse objecten rond hebt slingeren, als je het `git gc` commando handmatig uitvoert, of als je naar een remote server pusht. Om te zien wat er gebeurd, kun je Git handmatig vragen om de objecten in te pakken met het `git gc` commando: $ git gc Counting objects: 17, done. @@ -578,14 +578,14 @@ Je kunt geen gedeeltelijke globs in het patroon gebruiken, dus het volgende zou fetch = +refs/heads/qa*:refs/remotes/origin/qa* -Maar je kunt wel naamruimtes gebruiken om zoiets voor elkaar te krijgen. Als je een QA team hebt dat naar een serie branches pushed, en je wilt de master branch en alle QA team branches hebben, maar niets anders, kun je een configuratie sectie zoals dit gebruiken: +Maar je kunt wel naamruimtes gebruiken om zoiets voor elkaar te krijgen. Als je een QA team hebt dat naar een serie branches pusht, en je wilt de master branch en alle QA team branches hebben, maar niets anders, kun je een configuratie sectie zoals dit gebruiken: [remote "origin"] url = git@github.com:schacon/simplegit-progit.git fetch = +refs/heads/master:refs/remotes/origin/master fetch = +refs/heads/qa/*:refs/remotes/origin/qa/* -Als je een ingewikkeld werkproces hebt waarbij het QA team branches pushed, ontwikkelaars branches pushen, en integratie teams pushen en samenwerken op remote branches, kun je ze op deze manier eenvoudig in naamruimten stoppen. +Als je een ingewikkeld werkproces hebt waarbij het QA team branches pusht, ontwikkelaars branches pushen, en integratie teams pushen en samenwerken op remote branches, kun je ze op deze manier eenvoudig in naamruimten stoppen. ### Refspecs pushen ### @@ -916,7 +916,7 @@ Je kunt het `count-objects` commando gebruiken om snel te zien hoeveel ruimte je prune-packable: 0 garbage: 0 -Op de `size-pack` regel staat de grootte van je packfiles in kilobytes, dus je gebruikt 2Mb. Voor de laatste commit gebruikte je bijna 2K – dus het is duidelijk dat het verwijderen van het bestand uit de vorige commit, het niet uit je geschiedenis verwijderd heeft. Iedere keer als iemand dit repository cloned, zullen ze de volle 2Mb moeten clonen alleen maar om dit kleine project te krijgen, omdat jij per ongeluk een groot bestand toegevoegd hebt. Laten we het kwijtraken. +Op de `size-pack` regel staat de grootte van je packfiles in kilobytes, dus je gebruikt 2Mb. Voor de laatste commit gebruikte je bijna 2K – dus het is duidelijk dat het verwijderen van het bestand uit de vorige commit, het niet uit je geschiedenis verwijderd heeft. Iedere keer als iemand dit repository clonet, zullen ze de volle 2Mb moeten clonen alleen maar om dit kleine project te krijgen, omdat jij per ongeluk een groot bestand toegevoegd hebt. Laten we het kwijtraken. Eerst moet je het vinden. In dit geval weet je al welk bestand het is. Maar stel dat je het niet wist; hoe zou je kunnen vinden welk bestand of bestanden zoveel ruimte in beslag nemen? Als je `git gc` uitvoert zitten alle objecten in een packfile; je kunt de grote bestanden identificeren door een ander sanitaire voorzieningen commando genaamd `git verify-pack` uit te voeren en te sorteren op het derde veld in de uitvoer, wat de bestandsgrootte is. Je kunt het ook door het `tail` commando leiden omdat je alleen geïnteresseerd bent in het laatste paar grote bestanden. From 127623e0f399599ca09c4d1dece4ed2a473e8e90 Mon Sep 17 00:00:00 2001 From: Karel Heyse Date: Thu, 12 Dec 2013 16:15:21 +0100 Subject: [PATCH 072/862] =?UTF-8?q?Change=20system('ruby=20makepdfs')=20to?= =?UTF-8?q?=20system('sh=20makepdfs=E2=80=99);=20Fixes=20progit/progit#557?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 03c0bb9e7..c97b6a5fe 100644 --- a/Rakefile +++ b/Rakefile @@ -155,7 +155,7 @@ end namespace :pdf do desc "generate a pdf" task :generate do - system("ruby makepdfs") + system("sh makepdfs") end end From 4e1fd5e7195b119eb25ed5250e06f275cb400c0f Mon Sep 17 00:00:00 2001 From: Karel Heyse Date: Thu, 12 Dec 2013 22:38:58 +0100 Subject: [PATCH 073/862] =?UTF-8?q?changed=20system(=E2=80=9Csh=20makepdfs?= =?UTF-8?q?=E2=80=9D)=20to=20system(=E2=80=9Cbash=20makepdfs=E2=80=9D)=20b?= =?UTF-8?q?ecause=20makepdfs=20is=20a=20bash=20script?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Rakefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index c97b6a5fe..c9b0d9b3f 100644 --- a/Rakefile +++ b/Rakefile @@ -155,7 +155,7 @@ end namespace :pdf do desc "generate a pdf" task :generate do - system("sh makepdfs") + system("bash makepdfs") end end From f714ee7afd310f08b58597504e31d155e058a7df Mon Sep 17 00:00:00 2001 From: Karel Heyse Date: Thu, 12 Dec 2013 15:58:00 +0100 Subject: [PATCH 074/862] =?UTF-8?q?[nl]=20Replace=20all=20occurences=20of?= =?UTF-8?q?=20the=20verb=20=E2=80=98clone=E2=80=99=20by=20its=20dutch=20tr?= =?UTF-8?q?anslation=20=E2=80=98klonen=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nl/02-git-basics/01-chapter2.markdown | 32 +++++++-------- nl/03-git-branching/01-chapter3.markdown | 8 ++-- nl/04-git-server/01-chapter4.markdown | 40 +++++++++---------- nl/05-distributed-git/01-chapter5.markdown | 22 +++++----- nl/06-git-tools/01-chapter6.markdown | 16 ++++---- nl/07-customizing-git/01-chapter7.markdown | 4 +- nl/08-git-and-other-scms/01-chapter8.markdown | 14 +++---- nl/09-git-internals/01-chapter9.markdown | 8 ++-- 8 files changed, 72 insertions(+), 72 deletions(-) diff --git a/nl/02-git-basics/01-chapter2.markdown b/nl/02-git-basics/01-chapter2.markdown index bb42e8fee..4871c86a3 100644 --- a/nl/02-git-basics/01-chapter2.markdown +++ b/nl/02-git-basics/01-chapter2.markdown @@ -22,15 +22,15 @@ Als je de versies van bestaande bestanden wilt gaan beheren (in plaats van een l We zullen zodadelijk beschrijven wat deze commando's doen. Op dit punt heb je een Git repository met gevolgde (tracked) bestanden en een initiële commit. -### Een bestaand repository clonen ### +### Een bestaand repository klonen ### -Als je een kopie wilt van een bestaande Git repository — bijvoorbeeld een project waaraan je wilt bijdragen — dan is `git clone` het commando wat je nodig hebt. Als je bekend bent met andere versie-beheersystemen zoals Subversion, dan valt je op dat het commando `clone` is en niet `checkout`. Dit is een belangrijk verschil — Git ontvangt een kopie van bijna alle data die de server heeft. Iedere versie van ieder bestand van de hele geschiedenis van een project wordt binnengehaald als je `git clone` doet. In feite kun je, als je disk kapot gaat, iedere clone van iedere client gebruiken om de server terug in de status te brengen op het moment van clonen (al zou je wel wat hooks en dergelijke verliezen, maar alle versies van alle bestanden zouden er zijn — zie *Hoofdstuk 4* voor meer informatie). +Als je een kopie wilt van een bestaande Git repository — bijvoorbeeld een project waaraan je wilt bijdragen — dan is `git clone` het commando wat je nodig hebt. Als je bekend bent met andere versie-beheersystemen zoals Subversion, dan valt je op dat het commando `clone` is en niet `checkout`. Dit is een belangrijk verschil — Git ontvangt een kopie van bijna alle data die de server heeft. Iedere versie van ieder bestand van de hele geschiedenis van een project wordt binnengehaald als je `git clone` doet. In feite kun je, als je disk kapot gaat, iedere kloon van iedere client gebruiken om de server terug in de status te brengen op het moment van klonen (al zou je wel wat hooks en dergelijke verliezen, maar alle versies van alle bestanden zouden er zijn — zie *Hoofdstuk 4* voor meer informatie). -Je clonet een repository met `git clone [url]`. Bijvoorbeeld, als je de Ruby Git bibliotheek genaamd Grit wilt clonen, kun je dit als volgt doen: +Je kloont een repository met `git clone [url]`. Bijvoorbeeld, als je de Ruby Git bibliotheek genaamd Grit wilt klonen, kun je dit als volgt doen: $ git clone git://github.com/schacon/grit.git -Dat maakt een map genaamd `grit` aan, initialiseert hierin een `.git` map, haalt alle data voor dat repository binnen, en doet een checkout van een werkkopie van de laatste versie. Als je in de nieuwe `grit` map gaat, zul je de project bestanden vinden, klaar om gebruikt of aan gewerkt te worden. Als je de repository in een map met een andere naam dan grit wilt clonen, dan kun je dit met het volgende commando specificeren: +Dat maakt een map genaamd `grit` aan, initialiseert hierin een `.git` map, haalt alle data voor dat repository binnen, en doet een checkout van een werkkopie van de laatste versie. Als je in de nieuwe `grit` map gaat, zul je de project bestanden vinden, klaar om gebruikt of aan gewerkt te worden. Als je de repository in een map met een andere naam dan grit wilt klonen, dan kun je dit met het volgende commando specificeren: $ git clone git://github.com/schacon/grit.git mygrit @@ -42,7 +42,7 @@ Git heeft een aantal verschillende transport protocollen die je kunt gebruiken. Je hebt een bonafide Git repository en een checkout of werkkopie van de bestanden voor dat project. Je moet wat wijzigingen maken en deze committen in je repository, iedere keer zodra het project een status bereikt die je wilt vastleggen. -Onthoud dat ieder bestand in je werkmap in twee statussen kan verkeren: *gevolgd (tracked)* of *niet gevolgd (untracked)*. *Gevolgde* bestanden zijn bestanden die in het laatste snapshot zaten; ze kunnen *ongewijzigd*, *gewijzigd* of *staged zijn*. *Niet gevolgde* bestanden zijn al het andere - ieder bestand in je werkmap dat niet in je laatste snapshot en niet in je staging gebied zit. Als je voor het eerst een repository clonet, zullen al je bestanden gevolgd en ongewijzigd zijn, omdat je ze zojuist ge-checkout en niet gewijzigd hebt. +Onthoud dat ieder bestand in je werkmap in twee statussen kan verkeren: *gevolgd (tracked)* of *niet gevolgd (untracked)*. *Gevolgde* bestanden zijn bestanden die in het laatste snapshot zaten; ze kunnen *ongewijzigd*, *gewijzigd* of *staged zijn*. *Niet gevolgde* bestanden zijn al het andere - ieder bestand in je werkmap dat niet in je laatste snapshot en niet in je staging gebied zit. Als je voor het eerst een repository kloont, zullen al je bestanden gevolgd en ongewijzigd zijn, omdat je ze zojuist ge-checkout en niet gewijzigd hebt. Zodra je bestanden wijzigt, ziet Git ze als gewijzigd omdat je ze veranderd hebt sinds je laatste commit. Je *staged* deze gewijzigde bestanden en commit al je ge-stagede wijzigingen, en de cyclus herhaalt zichzelf. Deze cyclus wordt in Figuur 2-1 geïllustreerd. @@ -51,7 +51,7 @@ Figuur 2-1. De levenscyclus van de status van je bestanden. ### De status van je bestanden controleren ### -Het hoofdcommando dat je zult gebruiken om te bepalen welk bestand zich in welke status bevindt is `git status`. Als je dit commando direct na een clone uitvoert, dan zul je zoiets als het volgende zien: +Het hoofdcommando dat je zult gebruiken om te bepalen welk bestand zich in welke status bevindt is `git status`. Als je dit commando direct na het klonen uitvoert, dan zul je zoiets als het volgende zien: $ git status # On branch master @@ -59,7 +59,7 @@ Het hoofdcommando dat je zult gebruiken om te bepalen welk bestand zich in welke Dit betekent dat je een schone werkmap hebt — met andere woorden, er zijn geen gevolgde en gewijzigde bestanden. Git ziet ook geen ongevolgde bestanden, anders zouden ze hier getoond worden. Als laatste vertelt het commando op welke tak (branch) je nu zit. Voor nu is dit altijd `master`, dat is de standaard; maak je je hier nog niet druk om. Het volgende hoofdstuk gaat in detail over takken en referenties. -Stel dat je een nieuw bestand toevoegt aan je project, en simpel README bestand. Als het bestand voorheen nog niet bestond, en je doet `git status`, dan zul je je ongevolgde bestand zo zien: +Stel dat je een nieuw bestand toevoegt aan je project, een simpel README bestand. Als het bestand voorheen nog niet bestond, en je doet `git status`, dan zul je je ongevolgde bestand zo zien: $ vim README $ git status @@ -416,7 +416,7 @@ Git komt er impliciet achter dat het om een hernoemd bestand gaat, dus het maakt ## De commit geschiedenis bekijken ## -Nadat je een aantal commits gecreëerd hebt, of als je een repository met een bestaande commit geschiedenis gecloned hebt, zul je waarschijnlijk terug willen zien wat er gebeurd is. Het meest basale en krachtige tool om dit te doen is het `git log` commando. +Nadat je een aantal commits gecreëerd hebt, of als je een repository met een bestaande commit geschiedenis gekloond hebt, zul je waarschijnlijk terug willen zien wat er gebeurd is. Het meest basale en krachtige tool om dit te doen is het `git log` commando. Deze voorbeelden maken gebruik van een eenvoudig project genaamd simplegit dat ik vaak voor demonstraties gebruikt. Om het project op te halen, voer dit uit @@ -686,7 +686,7 @@ Het commando is een beetje vreemd, maar het werkt. Het benchmarks.rb bestand is ### Een gewijzigd bestand ongedaan maken ### -Wat als je je realiseert dat je je wijzigingen aan het `benchmarks.rb` bestand niet wilt behouden? Hoe kun je dit makkelijk ongedaan maken — terug brengen in de staat waarin het was toen je voor het laatst gecommit hebt (of initieel gecloned, of hoe je het ook in je werkmap gekregen hebt)? Gelukkig vertelt `git status` je ook hoe je dat moet doen. In de laatste voorbeeld output, ziet het unstaged gebied er zo uit: +Wat als je je realiseert dat je je wijzigingen aan het `benchmarks.rb` bestand niet wilt behouden? Hoe kun je dit makkelijk ongedaan maken — terug brengen in de staat waarin het was toen je voor het laatst gecommit hebt (of initieel gekloond, of hoe je het ook in je werkmap gekregen hebt)? Gelukkig vertelt `git status` je ook hoe je dat moet doen. In de laatste voorbeeld output, ziet het unstaged gebied er zo uit: # Changes not staged for commit: # (use "git add ..." to update what will be committed) @@ -717,7 +717,7 @@ Remote repositories beheren houdt ook in hoe je ze moet toevoegen, ongeldige rep ### Laat je remotes zien ### -Om te zien welke remote servers je geconfigureerd hebt, kun je het `git remote` commando uitvoeren. Het laat de verkorte namen van iedere remote alias zien die je gespecificeerd hebt. Als je je repository gecloned hebt, dan zul je op z'n minst de *origin* zien — dat is de standaard naam die Git aan de server geeft waarvan je gecloned hebt: +Om te zien welke remote servers je geconfigureerd hebt, kun je het `git remote` commando uitvoeren. Het laat de verkorte namen van iedere remote alias zien die je gespecificeerd hebt. Als je je repository gekloond hebt, dan zul je op z'n minst de *origin* zien — dat is de standaard naam die Git aan de server geeft waarvan je gekloond hebt: $ git clone git://github.com/schacon/ticgit.git Initialized empty Git repository in /private/tmp/ticgit/.git/ @@ -779,17 +779,17 @@ Zoals je zojuist gezien hebt, kun je om data van je remote projecten te halen di Het commando gaat naar het remote project en haalt alle data van dat remote project dat jij nog niet hebt. Nadat je dit gedaan hebt, zou je references (referenties) naar alle branches van dat remote moeten hebben, die je op ieder tijdstip kunt mergen en bekijken. (We zullen zien wat branches precies zijn, en hoe je ze moet gebruiken in meer detail in *Hoofdstuk 3*.) -Als je een repository clonet, voegt dat commando dat remote repository automatisch toe onder de naam *origin*. Dus `git fetch origin` fetched (haalt) ieder nieuw werk dat gepusht is naar die server sinds je gecloned hebt (of voor het laatst ge-fetched hebt). Het is belangrijk om te weten dat het fetch commando de data naar je locale repository haalt — het merged niet automatisch met je werk of verandert waar je momenteel aan zit te werken. Je kunt het handmatig in je werk mergen als je er klaar voor bent. +Als je een repository kloont, voegt dat commando dat remote repository automatisch toe onder de naam *origin*. Dus `git fetch origin` fetched (haalt) ieder nieuw werk dat gepusht is naar die server sinds je gekloond hebt (of voor het laatst ge-fetched hebt). Het is belangrijk om te weten dat het fetch commando de data naar je locale repository haalt — het merged niet automatisch met je werk of verandert waar je momenteel aan zit te werken. Je kunt het handmatig in je werk mergen als je er klaar voor bent. -Als je een branch geconfigureerd hebt om een remote branch te tracken (volgen) (zie de volgende sectie en *Hoofdstuk 3* voor meer informatie), dan kun je het `git pull` commando gebruiken om automatisch een remote branch te fetchen en mergen in je huidige branch. Dit kan makkelijker of meer comfortabel zijn voor je werkwijze; en standaard stelt het `git clone` commando je lokale master branch zo in dat het de remote master branch van de server waarvan je gecloned hebt volgt (aangenomen dat de remote een master branch heeft). Over het algemeen zal een `git pull` dat van de server waarvan je origineel gecloned hebt halen en proberen het automatisch in de code waar je op dat moment aan zit te werken te mergen. +Als je een branch geconfigureerd hebt om een remote branch te tracken (volgen) (zie de volgende sectie en *Hoofdstuk 3* voor meer informatie), dan kun je het `git pull` commando gebruiken om automatisch een remote branch te fetchen en mergen in je huidige branch. Dit kan makkelijker of meer comfortabel zijn voor je werkwijze; en standaard stelt het `git clone` commando je lokale master branch zo in dat het de remote master branch van de server waarvan je gekloond hebt volgt (aangenomen dat de remote een master branch heeft). Over het algemeen zal een `git pull` dat van de server waarvan je origineel gekloond hebt halen en proberen het automatisch in de code waar je op dat moment aan zit te werken te mergen. ### Je remotes pushen ### -Wanneer je je project op een punt krijgt dat je het wilt delen, dan moet je het stroomopwaarts pushen. Het commando hiervoor is simpel: `git push [remote-name] [branch-name]`. Als je je master branch naar je `origin` server wilt pushen (nogmaals, over het algemeen zet clonen beide namen automatisch goed voor je), dan kun je dit uitvoeren om je werk terug op de server te pushen: +Wanneer je je project op een punt krijgt dat je het wilt delen, dan moet je het stroomopwaarts pushen. Het commando hiervoor is simpel: `git push [remote-name] [branch-name]`. Als je je master branch naar je `origin` server wilt pushen (nogmaals, over het algemeen zet klonen beide namen automatisch goed voor je), dan kun je dit uitvoeren om je werk terug op de server te pushen: $ git push origin master -Dit commando werkt alleen als je gecloned hebt van een server waarop je schrijfrechten hebt, en als niemand in de tussentijd gepusht heeft. Als jij en iemand anders op hetzelfde tijdstip gecloned hebben en zij pushen stroomopwaarts en dan jij, dan zal je push terecht geweigerd worden. Je zult eerst hun werk moeten pullen en in jouw werk verwerken voordat je toegestaan wordt te pushen. Zie *Hoofdstuk 3* voor meer gedetailleerde informatie over hoe je naar remote servers moet pushen. +Dit commando werkt alleen als je gekloond hebt van een server waarop je schrijfrechten hebt, en als niemand in de tussentijd gepusht heeft. Als jij en iemand anders op hetzelfde tijdstip gekloond hebben en zij pushen stroomopwaarts en dan jij, dan zal je push terecht geweigerd worden. Je zult eerst hun werk moeten pullen en in jouw werk verwerken voordat je toegestaan wordt te pushen. Zie *Hoofdstuk 3* voor meer gedetailleerde informatie over hoe je naar remote servers moet pushen. ### Een remote inspecteren ### @@ -1052,7 +1052,7 @@ Als je veel tags hebt die je ineens wilt pushen, kun je ook de `--tags` optie aa * [new tag] v1.4-lw -> v1.4-lw * [new tag] v1.5 -> v1.5 -Als nu iemand anders van jouw repository clonet of pulled, dan zullen zij al jouw tags ook krijgen. +Als nu iemand anders van jouw repository kloont of pulled, dan zullen zij al jouw tags ook krijgen. ## Tips en trucs ## @@ -1123,4 +1123,4 @@ Zoals je kunt zien, vervangt Git eenvoudigweg het nieuwe commando met waarvoor j ## Samenvatting ## -Op dit punt kun je alle basis locale Git operaties doen – een repository creëren of clonen, wijzigingen maken, de wijzigingen stagen en committen, en de historie bekijken van alle veranderingen die de repository ondergaan heeft. Als volgende gaan we Gits beste optie bekijken: het branching model. +Op dit punt kun je alle basis locale Git operaties doen – een repository creëren of klonen, wijzigingen maken, de wijzigingen stagen en committen, en de historie bekijken van alle veranderingen die de repository ondergaan heeft. Als volgende gaan we Gits beste optie bekijken: het branching model. diff --git a/nl/03-git-branching/01-chapter3.markdown b/nl/03-git-branching/01-chapter3.markdown index 956fde1be..c850eb23a 100644 --- a/nl/03-git-branching/01-chapter3.markdown +++ b/nl/03-git-branching/01-chapter3.markdown @@ -384,7 +384,7 @@ Remote branches zijn referenties naar de staat van de branches op je remote repo Ze hebben de vorm `(remote)/(branch)`. Bijvoorbeeld, als je wil zien hoe de `master` branch op je `origin` er uit zag vanaf de laatste dat je er mee gecommuniceerd hebt, dan zou je de `origin/master` branch bekijken. Als je aan het werk bent aan een probleem met een partner en zij hebben een `iss53` branch teruggezet, dan zou je je eigen lokale `iss53` kunnen hebben; maar de branch op de server zou wijzen naar de commit op `origin/iss53`. -Dit kan wat verwarrend zijn, dus laten we eens naar een voorbeeld kijken. Stel dat je een Git server op je netwerk hebt op `git.ourcompany.com`. Als je hiervan clonet dan wordt die automatisch `origin` voor je genoemd, Git haalt al zijn gegevens binnen, maakt een verwijzing naar waar zijn `master` branch is, en noemt dat lokaal `origin/master`; en je kunt het niet verplaatsen. Git geeft je ook je eigen `master` branch, beginnend op dezelfde plaats als de `master` branch van origin, zodat je iets hebt om vanaf te werken (zie Figuur 3-22). +Dit kan wat verwarrend zijn, dus laten we eens naar een voorbeeld kijken. Stel dat je een Git server op je netwerk hebt op `git.ourcompany.com`. Als je hiervan kloont dan wordt die automatisch `origin` voor je genoemd, Git haalt al zijn gegevens binnen, maakt een verwijzing naar waar zijn `master` branch is, en noemt dat lokaal `origin/master`; en je kunt het niet verplaatsen. Git geeft je ook je eigen `master` branch, beginnend op dezelfde plaats als de `master` branch van origin, zodat je iets hebt om vanaf te werken (zie Figuur 3-22). Insert 18333fig0322.png Figuur 3-22. Een Git clone geeft je je eigen master branch en origin/master wijzend naar de master branch van origin. @@ -449,7 +449,7 @@ Dit geeft je een lokale branch waar je op kunt werken, die begint met waar `orig Een lokale branch uitchecken van een remote branch creëert automatisch een zogenaamde _volg branch_ (_tracking branch_). Volg branches zijn lokale branches die een directe releatie met een remote branch hebben. Als je op een volg branch zit en git push typt, dat weet Git automatisch naar welke server en branch hij moet terugzetten. En, terwijl je op een van die branches zit zal het uitvoeren van `git pull` alle remote referenties ophalen en ze automatisch in de corresponderende remote branch samenvoegen. -Als je een repository clonet, zal het over het algemeen automatisch een `master` branch aanmaken, die `origin/master` volgt. Daarom werken `git push` en `git pull` zo uit het doosje, zonder verdere argumenten. Maar, kun je kunt ook andere volg branches instellen als je dat wilt — anderen die niet branches volgen op `origin` en niet de `master` branch volgen. Het eenvoudige geval is het voorbeeld dat je zojuist zag, `git checkout -b [branch] [remotenaam]/[branch]` uitvoeren. Als je Git versie 1.6.2 of nieuwer hebt, kun je ook de `--track` afkorting gebruiken: +Als je een repository kloont, zal het over het algemeen automatisch een `master` branch aanmaken, die `origin/master` volgt. Daarom werken `git push` en `git pull` zo uit het doosje, zonder verdere argumenten. Maar, kun je kunt ook andere volg branches instellen als je dat wilt — anderen die niet branches volgen op `origin` en niet de `master` branch volgen. Het eenvoudige geval is het voorbeeld dat je zojuist zag, `git checkout -b [branch] [remotenaam]/[branch]` uitvoeren. Als je Git versie 1.6.2 of nieuwer hebt, kun je ook de `--track` afkorting gebruiken: $ git checkout --track origin/serverfix Branch serverfix set up to track remote branch refs/remotes/origin/serverfix. @@ -570,10 +570,10 @@ Als je die richtlijn volgt, dan gebeurt je niets. Als je dat niet doet, zullen m Als je spullen rebaset, laat je bestaande commits achter en maak je nieuwe aan die vergelijkbaar zijn maar anders. Als je commits ergens naartoe zet en andere halen ze binnen en baseren daar werk op, en vervolgens herschrijf je die commits met `git rebase` en zet ze opnieuw terug, dan zullen je medewerkers hun werk opnieuw moeten samenvoegen en zullen de dingen vervelend worden als je hun werk probeert binnen te halen in het jouwe. -Laten we eens kijken naar een voorbeeld of hoe werk rebasen dat je publiekelijk gemaakt hebt problemen kan veroorzaken. Stel dat je van een centrale server clonet en dan daar wat werk vanaf doet. Je commit historie ziet er uit als Figuur 3-36. +Laten we eens kijken naar een voorbeeld of hoe werk rebasen dat je publiekelijk gemaakt hebt problemen kan veroorzaken. Stel dat je van een centrale server kloont en dan daar wat werk vanaf doet. Je commit historie ziet er uit als Figuur 3-36. Insert 18333fig0336.png -Figuur 3-36. Clone een repository, en baseer wat werk daarop. +Figuur 3-36. Kloon een repository, en baseer wat werk daarop. Nu, doet iemand anders wat meer werk dat een samenvoeging bevat, en zet dat werk terug naar de centrale server. Je pakt dat en voegt de nieuwe remote branch in jouw werk, zodat je historie er uit ziet zoals Figuur 3-37. diff --git a/nl/04-git-server/01-chapter4.markdown b/nl/04-git-server/01-chapter4.markdown index 4344ee256..9d4ff89c3 100644 --- a/nl/04-git-server/01-chapter4.markdown +++ b/nl/04-git-server/01-chapter4.markdown @@ -18,7 +18,7 @@ Het is belangrijk om te zien dat, met uitzondering van de HTTP protocollen, ze a Het meest basale is het _lokale protocol_, waarbij het remote repository in een andere map op de schijf staat. Dit wordt vaak gebruikt als iedereen in je team toegang heeft op een gedeeld bestandssysteem zoals een NFS map, of in het weinig voorkomende geval dat iedereen op dezelfde computer werkt. Het laatste zou niet ideaal zijn, want dan zouden alle repositories zich op dezelfde computer bevinden, zodat de kans op een catastrofaal verlies veel groter wordt. -Als je een gedeeld bestandssysteem hebt, dan kun je clonen, pushen en pullen van een op een lokaal bestand gebaseerde repository. Om een dergelijk repository te clonen, of om er een als een remote aan een bestaand project toe te voegen, moet je het pad naar het repository als URL gebruiken. Bijvoorbeeld, om een lokaal repository te clonen, kun je zoiets als dit uitvoeren: +Als je een gedeeld bestandssysteem hebt, dan kun je klonen, pushen en pullen van een op een lokaal bestand gebaseerde repository. Om een dergelijk repository te klonen, of om er een als een remote aan een bestaand project toe te voegen, moet je het pad naar het repository als URL gebruiken. Bijvoorbeeld, om een lokaal repository te klonen, kun je zoiets als dit uitvoeren: $ git clone /opt/git/project.git @@ -50,7 +50,7 @@ Het is ook belangrijk om te melden dat het niet noodzakelijk de snelste optie is Waarschijnlijk het meest voorkomende protocol voor Git is SSH. Dit is omdat SSH toegang tot servers in veel plaatsen al geconfigureerd is — en als dat niet het geval is, dan is het makkelijk om dat te doen. SSH is ook het enige netwerk gebaseerde protocol waarvan je makkelijk kunt lezen en naartoe kunt schrijven. De andere twee netwerk protocollen (HTTP en Git) zijn over het algemeen alleen-lezen, dus zelfs als je ze al beschikbaar hebt voor de ongewassen massa, dan heb je nog steeds SSH nodig voor je eigen schrijftoegang. SSH is ook een geverifieerd protocol; en omdat het overal voorkomt, is het over het algemeen eenvoudig om in te stellen en te gebruiken. -Om een Git repository via SSH te clonen, kun je een ssh:// URL opgeven zoals: +Om een Git repository via SSH te klonen, kun je een ssh:// URL opgeven zoals: $ git clone ssh://user@server/project.git @@ -70,7 +70,7 @@ Het negatieve aspect van SSH is dat je er geen anonieme toegang over kunt geven. ### Het Git protocol ### -Het volgende is het Git protocol. Dit is een aparte daemon, die samen met Git geleverd wordt; het luistert op een toegewezen poort (9418), dat een vergelijkbare dienst verleend als het SSH protocol, maar dan zonder enige authenticatie. Om een repository te serveren over het Git protocol, moet je het `git-export-daemon-ok` bestand aanmaken — de daemon zal een repository zonder dit bestand erin niet serveren — maar buiten dat is er geen beveiliging. Ofwel het Git repository kan door iedereen gecloned worden, of helemaal niet. Dit betekent dat er over het algemeen geen pushing is via dit protocol. Je kunt push toegang aanzetten; maar gegeven het gebrek aan toegangscontrole als je push toegang aan zet, kan iedereen die de URL van jouw project op het internet vindt, pushen naar jouw project. We volstaan met te zeggen dat dit zeldzaam is. +Het volgende is het Git protocol. Dit is een aparte daemon, die samen met Git geleverd wordt; het luistert op een toegewezen poort (9418), dat een vergelijkbare dienst verleend als het SSH protocol, maar dan zonder enige authenticatie. Om een repository te serveren over het Git protocol, moet je het `git-export-daemon-ok` bestand aanmaken — de daemon zal een repository zonder dit bestand erin niet serveren — maar buiten dat is er geen beveiliging. Ofwel het Git repository kan door iedereen gekloond worden, of helemaal niet. Dit betekent dat over het algemeen pushen niet mogelijk is via dit protocol. Je kunt push toegang aanzetten; maar gegeven het gebrek aan toegangscontrole als je push toegang aan zet, kan iedereen die de URL van jouw project op het internet vindt, pushen naar jouw project. We volstaan met te zeggen dat dit zeldzaam is. #### De voordelen #### @@ -83,7 +83,7 @@ Het is waarschijnlijk ook het meest ingewikkelde protocol om in te stellen. Het ### Het HTTP/S protocol ### -Als laatste hebben we het HTTP protocol. Het mooie aan het HTTP of HTTPS protocol is dat het simpel in te stellen is. Eigenlijk is alles wat je moet doen de kale Git repository in je HTTP document root zetten, en een specifieke `post-update` hook (haak) instellen en je bent klaar (zie hoofdstuk 7 voor details over Git hooks). Vanaf dat moment kan iedereen die toegang heeft tot de webserver waaronder je de repository gezet hebt ook je repository clonen. Om leestoegang tot je repository over HTTP toe te staan, doe je zoiets als het volgende: +Als laatste hebben we het HTTP protocol. Het mooie aan het HTTP of HTTPS protocol is dat het simpel in te stellen is. Eigenlijk is alles wat je moet doen de kale Git repository in je HTTP document root zetten, en een specifieke `post-update` hook (haak) instellen en je bent klaar (zie hoofdstuk 7 voor details over Git hooks). Vanaf dat moment kan iedereen die toegang heeft tot de webserver waaronder je de repository gezet hebt ook je repository klonen. Om leestoegang tot je repository over HTTP toe te staan, doe je zoiets als het volgende: $ cd /var/www/htdocs/ $ git clone --bare /path/to/git_project gitproject.git @@ -91,7 +91,7 @@ Als laatste hebben we het HTTP protocol. Het mooie aan het HTTP of HTTPS protoco $ mv hooks/post-update.sample hooks/post-update $ chmod a+x hooks/post-update -Dat is alles. De `post-update` hook, die standaard bij Git zit, voert het noodzakelijke commando uit (`git update-server-info`) om HTTP fetching en cloning goed werkend te krijgen. Dit commando wordt uitgevoerd als je naar dit repository via SSH pusht; en dan kunnen andere mensen clonen met behulp van zoiets als +Dat is alles. De `post-update` hook, die standaard bij Git zit, voert het noodzakelijke commando uit (`git update-server-info`) om HTTP fetchen en klonen goed werkend te krijgen. Dit commando wordt uitgevoerd als je naar dit repository via SSH pusht; en dan kunnen andere mensen klonen met behulp van zoiets als $ git clone http://example.com/gitproject.git @@ -109,12 +109,12 @@ Een ander fijn ding is dat HTTP zo'n veel voorkomend protocol is dat bedrijfsfir #### De nadelen #### -Het nadeel van je repository serveren via HTTP is dat het relatief inefficiënt voor de client is. Over het algemeen duurt het een stuk langer om te clonen en te fetchen van de repository, en je hebt vaak een stuk meer netwerk belasting en transport volume via HTTP dan met elk van de andere netwerk protocollen. Omdat het niet zo intelligent is om alleen de data te versturen die je nodig hebt — er wordt geen dynamisch werk door de server gedaan in deze transacties — wordt vaak naar het HTTP protocol gerefereerd als zijnde een _dom_ protocol. Voor meer informatie over de verschillen in efficiëntie tussen het HTTP protocol en andere protocollen, zie Hoofdstuk 9. +Het nadeel van je repository serveren via HTTP is dat het relatief inefficiënt voor de client is. Over het algemeen duurt het een stuk langer om te klonen en te fetchen van de repository, en je hebt vaak een stuk meer netwerk belasting en transport volume via HTTP dan met elk van de andere netwerk protocollen. Omdat het niet zo intelligent is om alleen de data te versturen die je nodig hebt — er wordt geen dynamisch werk door de server gedaan in deze transacties — wordt vaak naar het HTTP protocol gerefereerd als zijnde een _dom_ protocol. Voor meer informatie over de verschillen in efficiëntie tussen het HTTP protocol en andere protocollen, zie Hoofdstuk 9. ## Git op een server krijgen ## Om een initiële Git server op te zetten, moet je een bestaande repository in een kale repository exporteren — een repository dat geen werkmap bevat. Dit is over het algemeen eenvoudig te doen. -Om je repository te clonen met als doel het maken van een kale repository, voer je het clone commando uit met de `--bare` optie. Als vaste gewoonte eindigen de namen van kale repository mappen in `.git`, zoals: +Om je repository te klonen met als doel het maken van een kale repository, voer je het `clone` commando uit met de `--bare` optie. Als vaste gewoonte eindigen de namen van kale repository mappen in `.git`, zoals: $ git clone --bare my_project my_project.git Initialized empty Git repository in /opt/projects/my_project.git/ @@ -133,7 +133,7 @@ Nu dat je een kale kopie van je repository hebt, is het enige dat je moet doen h $ scp -r my_project.git user@git.example.com:/opt/git -Op dit punt kunnen andere gebruikers, die SSH toegang hebben tot dezelfde server en lees-toegang hebben tot de `/opt/git` map, jouw repository clonen door dit uit te voeren: +Op dit punt kunnen andere gebruikers, die SSH toegang hebben tot dezelfde server en lees-toegang hebben tot de `/opt/git` map, jouw repository klonen door dit uit te voeren: $ git clone user@git.example.com:/opt/git/my_project.git @@ -243,7 +243,7 @@ Daarna kunnen John, Josie of Jessica de eerste versie van hun project in de repo $ git remote add origin git@gitserver:/opt/git/project.git $ git push origin master -Op dat punt kunnen de anderen het clonen en wijzigingen even gemakkelijk terug pushen: +Op dat punt kunnen de anderen het klonen en wijzigingen even gemakkelijk terug pushen: $ git clone git@gitserver:/opt/git/project.git $ vim README @@ -308,7 +308,7 @@ Je zult ook de Unix gebruikers groep van de `/opt/git` mappen moeten instellen o $ chgrp -R www-data /opt/git -Als je Apache herstart, dan zou je je repositories onder die map moeten kunnen clonen door de URL van je project te specificeren: +Als je Apache herstart, dan zou je je repositories onder die map moeten kunnen klonen door de URL van je project te specificeren: $ git clone http://git.gitserver/project.git @@ -354,7 +354,7 @@ Let op dat je het commando moet vertellen waar het je Git repositories kan vinde -Nogmaals, GitWeb kan geserveerd worden met iedere CGI capabele web server; als je iets anders prefereert zou het niet moeilijk in te stellen moeten zijn. Op dit punt zou je in staat moeten zijn om `http://gitserver/` te bezoeken en je repositories online te zien, en kun je `http://git.gitserver` gebruiken om je repositories over HTTP te clonen en te fetchen. +Nogmaals, GitWeb kan geserveerd worden met iedere CGI capabele web server; als je iets anders prefereert zou het niet moeilijk in te stellen moeten zijn. Op dit punt zou je in staat moeten zijn om `http://gitserver/` te bezoeken en je repositories online te zien, en kun je `http://git.gitserver` gebruiken om je repositories over HTTP te klonen en te fetchen. ## Gitosis ## @@ -368,7 +368,7 @@ Gitosis vereist wat Python applicaties, dus moet je eerst het Python setuptools $ apt-get install python-setuptools -Vervolgens clone en installeer je Gitosis van de hoofdpagina van het project: +Vervolgens kloon en installeer je Gitosis van de hoofdpagina van het project: $ git clone git://eagain.net/gitosis.git $ cd gitosis @@ -408,7 +408,7 @@ Je bent nu klaar om te gaan. Als je alles juist hebt ingesteld, kun je nu met SS fatal: unrecognized command 'gitosis-serve schacon@quaternion' Connection to gitserver closed. -Dat betekent dat Gitosis je herkend heeft, maar je buitensluit omdat je geen Git commando's aan het doen bent. Dus, laten we een echt Git commando doen — je gaat de Gitosis beheer repository clonen: +Dat betekent dat Gitosis je herkend heeft, maar je buitensluit omdat je geen Git commando's aan het doen bent. Dus, laten we een echt Git commando doen — je gaat de Gitosis beheer repository klonen: # op je locale computer $ git clone git@gitserver:gitosis-admin.git @@ -423,7 +423,7 @@ Nu heb je een map genaamd `gitosis-admin`, die twee hoofd gedeeltes heeft: Het `gitosis.conf` bestand is het beheer bestand, dat je zult gebruiken om gebruikers, repositories en permissies te specificeren. De `keydir` map is de plaats waar je de publieke sleutels opslaat van alle gebruikers die een vorm van toegang tot je repositories hebben — één bestand per gebruiker. De naam van het bestand in `keydir` (in het vorige voorbeeld, `scott.pub`) zal anders voor jou zijn — Gitosis haalt de naam uit de beschrijving aan het einde van de publieke sleutel die was geïmporteerd met het `gitosis-init` script. -Als je naar het `gitosis.conf` bestand kijkt, zou het alleen informatie over het zojuist geclonede `gitosis-admin` project mogen bevatten: +Als je naar het `gitosis.conf` bestand kijkt, zou het alleen informatie over het zojuist gekloonde `gitosis-admin` project mogen bevatten: $ cat gitosis.conf [gitosis] @@ -490,7 +490,7 @@ Gitosis heeft ook eenvoudige toegangscontrole. Als je wilt dat John alleen lees readonly = iphone_project members = john -Nu kan John het project clonen en updates krijgen, maar Gitosis zal hem niet toestaan om terug naar het project te pushen. Je kunt zoveel van deze groepen maken als je wilt, waarbij ze allen verschillende gebruikers en projecten mogen bevatten. Je kunt ook een andere groep als een van de leden specificeren (waarbij je `@` als prefix gebruikt), om alle leden automatisch over te erven: +Nu kan John het project klonen en updates krijgen, maar Gitosis zal hem niet toestaan om terug naar het project te pushen. Je kunt zoveel van deze groepen maken als je wilt, waarbij ze allen verschillende gebruikers en projecten mogen bevatten. Je kunt ook een andere groep als een van de leden specificeren (waarbij je `@` als prefix gebruikt), om alle leden automatisch over te erven: [group mobile_committers] members = scott josie jessica @@ -536,7 +536,7 @@ Dit zal je vragen naar het wachtwoord van het gitolite account, en dan toegang m $ ssh gitolite@gitserver pwd /home/gitolite -Vervolgens clone je Gitolite van de hoofdsite van het project en voer je het "easy install" script uit (het derde argument is de naam zoals je wilt verschijnen in het resulterende gitolite-admin repository): +Vervolgens kloon je Gitolite van de hoofdsite van het project en voer je het "easy install" script uit (het derde argument is de naam zoals je wilt verschijnen in het resulterende gitolite-admin repository): $ git clone git://github.com/sitaramc/gitolite $ cd gitolite/src @@ -546,12 +546,12 @@ En dan ben je klaar! Gitolite is nu geïnstalleerd op de server, en je hebt nu e Dat laatste commando zorgt wel voor een flinke hoeveelheid uitvoer, dat interessant kan zijn om te lezen. Daarnaast wordt de eerste keer dat je dit uitvoert een nieuw sleutelpaar gegenereerd; je zult hiervoor een wachtzin moeten kiezen of enter drukken om zonder te werken. Waarom een tweede paar nodig is, en hoe het gebruikt wordt, wordt uitgelegd in het "ssh troubleshooting" document dat bij Gitolite zit. (He, de documentatie moet toch *ergens* goed voor zijn!) -Standaard worden de `testing` en `gitolite-admin` repositories aangemaakt. Als je een van deze lokaal wilt clonen (vanaf een account dat SSH console toegang heeft tot het gitolite account via *authorized_keys*), type: +Standaard worden de `testing` en `gitolite-admin` repositories aangemaakt. Als je een van deze lokaal wilt klonen (vanaf een account dat SSH console toegang heeft tot het gitolite account via *authorized_keys*), type: $ git clone gitolite:gitolite-admin $ git clone gitolite:testing -Om dezelfde repos van ieder ander account te clonen: +Om dezelfde repos van ieder ander account te klonen: $ git clone gitolite@servername:gitolite-admin $ git clone gitolite@servername:testing @@ -695,7 +695,7 @@ In ieder geval is het Git protocol relatief eenvoudig in te stellen. Eigenlijk i git daemon --reuseaddr --base-path=/opt/git/ /opt/git/ -`--reuseaddr` staat de server toe om te herstarten zonder te wachten tot oude connecties een time out krijgen, de `--base-path` optie staat mensen toe om projecten te clonen zonder het volledige pad te specificeren, en het pad aan het einde vertelt de Git daemon waar hij moet kijken voor de te exporteren repositories. Als je een firewall draait, zul je er ook een gat in moeten maken op poort 9418 op de machine waar je dit op instelt. +`--reuseaddr` staat de server toe om te herstarten zonder te wachten tot oude connecties een time out krijgen, de `--base-path` optie staat mensen toe om projecten te klonen zonder het volledige pad te specificeren, en het pad aan het einde vertelt de Git daemon waar hij moet kijken voor de te exporteren repositories. Als je een firewall draait, zul je er ook een gat in moeten maken op poort 9418 op de machine waar je dit op instelt. Je kunt dit proces op een aantal manieren daemoniseren, afhankelijk van het besturingssysteem waarop je draait. Op een Ubuntu machine, zul je een Upstart script gebruiken. Dus in het volgende bestand @@ -820,7 +820,7 @@ Nu wordt je project beheerd op GitHub, en kun je de URL aan iedereen geven waarm Insert 18333fig0408.png Figuur 4-8. Project met een publieke URL en een privé URL. -De publieke Clone URL is een publieke alleen-lezen Git URL, waarmee iedereen het project kan clonen. Deel deze URL maar gewoon uit en zet 'm op je website of wat je ook hebt. +De publieke Clone URL is een publieke alleen-lezen Git URL, waarmee iedereen het project kan klonen. Deel deze URL maar gewoon uit en zet 'm op je website of wat je ook hebt. De Your Clone URL is een lees/schrijf SSH-gebaseerde URL waar je alleen over kunt lezen of schrijven als je connectie maakt met de privé SSH sleutel die geassocieerd is met de publieke sleutel die je voor jouw gebruiker geüpload hebt. Wanneer andere gebruikers deze project pagina bezoeken, zullen ze die URL niet zien — alleen de publieke. diff --git a/nl/05-distributed-git/01-chapter5.markdown b/nl/05-distributed-git/01-chapter5.markdown index 5022c8d40..1bfb363f2 100644 --- a/nl/05-distributed-git/01-chapter5.markdown +++ b/nl/05-distributed-git/01-chapter5.markdown @@ -15,17 +15,17 @@ In gecentraliseerde systemen is er over het algemeen een enkel samenwerkingsmode Insert 18333fig0501.png Figuur 5-1. Gecentraliseerde Werkwijze. -Dit betekent dat als twee ontwikkelaars clonen van het gecentraliseerde punt en beide wijzigingen doen, de eerste ontwikkelaar zijn wijzigingen terug kan zetten zonder problemen. De tweede ontwikkelaar zal het werk van de eerste in het zijne moeten samenvoegen voordat hij het zijne kan terugzetten, om zo niet het werk van de eerste te overschrijven. Dit concept werkt zo in Git zoals het ook werkt in Subversion (of ieder ander CVCS), en dit model werkt perfect in Git. +Dit betekent dat als twee ontwikkelaars klonen van het gecentraliseerde punt en beide wijzigingen doen, de eerste ontwikkelaar zijn wijzigingen terug kan zetten zonder problemen. De tweede ontwikkelaar zal het werk van de eerste in het zijne moeten samenvoegen voordat hij het zijne kan terugzetten, om zo niet het werk van de eerste te overschrijven. Dit concept werkt zo in Git zoals het ook werkt in Subversion (of ieder ander CVCS), en dit model werkt perfect in Git. -Als je een klein team hebt, of al vertrouwd bent met een gecentraliseerde werkwijze in je bedrijf of team, dan kun je eenvoudig doorgaan met het gebruiken van die werkwijze met Git. Stel eenvoudigweg een enkel repository in, en geef iedereen in je team terugzettoegang; Git zal gebruikers niet toestaan om elkaars wijzigingen te overschrijven. Als een ontwikkelaar clonet, wijzigingen maakt, en dan probeert zijn wijzigingen terug te zetten terwijl een andere ontwikkelaar de zijne in de tussentijd heeft teruggezet, dan zal de server de wijzigingen van die ontwikkelaar weigeren. "Non-fast-forward-wijzigingen" kunnen niet teruggezet worden alvorens de conflicten worden opgelost. +Als je een klein team hebt, of al vertrouwd bent met een gecentraliseerde werkwijze in je bedrijf of team, dan kun je eenvoudig doorgaan met het gebruiken van die werkwijze met Git. Stel eenvoudigweg een enkel repository in, en geef iedereen in je team terugzettoegang; Git zal gebruikers niet toestaan om elkaars wijzigingen te overschrijven. Als een ontwikkelaar kloont, wijzigingen maakt, en dan probeert zijn wijzigingen terug te zetten terwijl een andere ontwikkelaar de zijne in de tussentijd heeft teruggezet, dan zal de server de wijzigingen van die ontwikkelaar weigeren. "Non-fast-forward-wijzigingen" kunnen niet teruggezet worden alvorens de conflicten worden opgelost. Deze werkwijze is voor een hoop mensen aantrekkelijk omdat het een wijze is waarmee veel mensen bekend zijn en zich op hun gemak bij voelen. ### Integratie-manager werkwijze ### -Omdat Git je toestaat om meerdere remote repositories te hebben, is het mogelijk om een werkwijze te hebben waarbij iedere ontwikkelaar schrijftoegang heeft tot zijn eigen publieke repository en leestoegang op de andere. Dit scenario heeft vaak een gezagdragend repository dat het "officiële" project voorstelt. Om bij te kunnen dragen tot dat project, maak je je eigen publieke clone van het project en zet je wijzigingen daarin terug. Daarna stuur je een verzoek naar de eigenaar van het hoofdproject om jouw wijzigingen binnen te halen. Hij kan je repository toevoegen als een remote, je wijzigingen lokaal testen, ze in zijn branch samenvoegen, en naar zijn repository terugzetten. Het proces werkt als volgt (zie Figuur 5-2): +Omdat Git je toestaat om meerdere remote repositories te hebben, is het mogelijk om een werkwijze te hebben waarbij iedere ontwikkelaar schrijftoegang heeft tot zijn eigen publieke repository en leestoegang op de andere. Dit scenario heeft vaak een gezagdragend repository dat het "officiële" project voorstelt. Om bij te kunnen dragen tot dat project, maak je je eigen publieke kloon van het project en zet je wijzigingen daarin terug. Daarna stuur je een verzoek naar de eigenaar van het hoofdproject om jouw wijzigingen binnen te halen. Hij kan je repository toevoegen als een remote, je wijzigingen lokaal testen, ze in zijn branch samenvoegen, en naar zijn repository terugzetten. Het proces werkt als volgt (zie Figuur 5-2): 1. De projecteigenaar zet terug naar zijn eigen repository. -2. Een bijdrager clonet dat repository en maakt wijzigingen. +2. Een bijdrager kloont dat repository en maakt wijzigingen. 3. De bijdrager zet terug naar zijn eigen publieke kopie. 4. De bijdrager stuurt de eigenaar een e-mail met de vraag om de wijzigingen binnen te halen. 5. De eigenaar voegt het repo van de bijdrager toe als een remote en voegt lokaal samen. @@ -113,7 +113,7 @@ In de volgende voorbeelden, en verder door de rest van dit boek, zal ik omwille De eenvoudigste opzet die je waarschijnlijk zult tegenkomen is een besloten project met één of twee andere ontwikkelaars. Met besloten bedoel ik gesloten broncode – zonder leestoegang voor de buitenwereld. Jij en de andere ontwikkelaars hebben allemaal terugzet toegang op het repository. In deze omgeving kun je een werkwijze aanhouden die vergelijkbaar is met wat je zou doen als je Subversion of een andere gecentraliseerd systeem zou gebruiken. Je hebt nog steeds de voordelen van zaken als offline committen en veel eenvoudiger branchen en samenvoegen, maar de werkwijze kan erg vergelijkbaar zijn; het grote verschil is dat het samenvoegen aan de client-kant gebeurt tijdens het committen in plaats van aan de server-kant. -Laten we eens kijken hoe het er uit zou kunnen zien als twee ontwikkelaars samen beginnen te werken met een gedeelde repository. De eerste ontwikkelaar, John, clonet de repository, maakt een wijziging, en commit lokaal. (Ik vervang de protocol berichten met `...` in deze voorbeelden om ze iets in te korten.) +Laten we eens kijken hoe het er uit zou kunnen zien als twee ontwikkelaars samen beginnen te werken met een gedeelde repository. De eerste ontwikkelaar, John, kloont de repository, maakt een wijziging, en commit lokaal. (Ik vervang de protocol berichten met `...` in deze voorbeelden om ze iets in te korten.) # John's Machine $ git clone john@githost:simplegit.git @@ -125,7 +125,7 @@ Laten we eens kijken hoe het er uit zou kunnen zien als twee ontwikkelaars samen [master 738ee87] removed invalid default value 1 files changed, 1 insertions(+), 1 deletions(-) -De tweede ontwikkelaar, Jessica, doet hetzelfde – clonet de repository en commit een wijziging: +De tweede ontwikkelaar, Jessica, doet hetzelfde – kloont de repository en commit een wijziging: # Jessica's Machine $ git clone jessica@githost:simplegit.git @@ -267,7 +267,7 @@ In het volgende scenario zul je kijken naar de rol van de bijdragers in een grot Stel dat John en Jessica samen werken aan een functie, terwijl Jessica en Josie aan een tweede aan het werken zijn. In dit geval gebruikt het bedrijf een integratie-manager achtige werkwijze, waarbij het werk van de individuele groepen alleen wordt geïntegreerd door bepaalde ingenieurs, en de `master` branch van het hoofd repo alleen kan worden vernieuwd door die ingenieurs. In dit scenario, wordt al het werk gedaan in team-gebaseerde branches en later door de integrators samengevoegd. -Laten we Jessica's werkwijze volgen terwijl ze aan haar twee functies werkt, in parallel met twee verschillend ontwikkelaars in deze omgeving. Aangenomen dat ze haar repository al gecloned heeft, besluit ze als eerste te werken aan `featureA`. Ze maakt een nieuwe branch aan voor de functie en doet daar wat werk: +Laten we Jessica's werkwijze volgen terwijl ze aan haar twee functies werkt, in parallel met twee verschillend ontwikkelaars in deze omgeving. Aangenomen dat ze haar repository al gekloond heeft, besluit ze als eerste te werken aan `featureA`. Ze maakt een nieuwe branch aan voor de functie en doet daar wat werk: # Jessica's Machine $ git checkout -b featureA @@ -387,7 +387,7 @@ Figuur 5-15. Basale volgorde van de werkwijze van dit aangestuurde team. Het bijdragen aan publieke projecten gaat wat anders. Omdat je niet de toestemming hebt om de branches van het project te vernieuwen, moet je het werk op een andere manier naar de beheerders krijgen. Dit eerste voorbeeld beschrijft het bijdragen via afsplitsen op Git hosts die eenvoudig afsplitsen ondersteunen. De repo.or.cz en GitHub hosting sites ondersteunen dit allebei, en veel project beheerders verwachten deze soort bijdrage. Het volgende deel behandelt projecten die de voorkeur hebben aan bijgedragen patches via e-mail. -Eerst wil je waarschijnlijk het hoofdrepository clonen, een onderwerp branch maken voor de patch of patch serie die je van plan bent bij te dragen, en je werk daarop doen. De volgorde ziet er in basis zo uit: +Eerst wil je waarschijnlijk het hoofdrepository klonen, een onderwerp branch maken voor de patch of patch serie die je van plan bent bij te dragen, en je werk daarop doen. De volgorde ziet er in basis zo uit: $ git clone (url) $ cd project @@ -775,7 +775,7 @@ Figuur 5-22. Na een samenvoeging van een onderwerp branch. Insert 18333fig0523.png Figuur 5-23. Na een vrijgave van een onderwerp branch. -Als mensen het repository van je project op deze manier clonen, dan kunnen ze of master uit checken om de laatste stabiele versie te bouwen en die eenvoudig te kunnen bijhouden of ze kunnen develop uit checken, wat het nieuwere spul bevat. +Als mensen het repository van je project op deze manier klonen, dan kunnen ze of master uit checken om de laatste stabiele versie te bouwen en die eenvoudig te kunnen bijhouden of ze kunnen develop uit checken, wat het nieuwere spul bevat. Je kunt dit concept ook doortrekken, waarbij je een integratie branch hebt waar al het werk samengevoegd wordt. Als de codebasis op die branch stabiel is en voor de testen slaagt, dan voeg je het in een develop branch; en als dat zichzelf een poosje stabiel heeft bewezen, dan fast-forward je je master branch. #### Werkwijzen met grote samenvoegingen #### @@ -790,7 +790,7 @@ Als de onderwerpen nog werk nodig hebben, dan worden ze in plaats daarvan sameng Insert 18333fig0525.png Figuur 5-25. Bijgedragen onderwerp branches samenvoegen in langlopende integratie branches. -Als een onderwerp branch uiteindelijk is samengevoegd in `master`, dan wordt het verwijderd van het repository. Het Git project heeft ook een `main` branch, die geforked is van de laatste vrijgave om teruggewerkte patches te leveren in het geval een onderhoudsvrijgave benodigd is. Dus, als je het Git repository clonet, dan heb je vier branches die je kunt uitchecken om het project in verschillende stadia van ontwikkeling te evalueren, afhankelijk van hoe nieuw je alles wilt hebben of hoe je wil bijdragen; en de beheerder heeft een gestructureerde werkwijze om ze te helpen nieuwe bijdragen aan de tand te voelen. +Als een onderwerp branch uiteindelijk is samengevoegd in `master`, dan wordt het verwijderd van het repository. Het Git project heeft ook een `main` branch, die geforked is van de laatste vrijgave om teruggewerkte patches te leveren in het geval een onderhoudsvrijgave benodigd is. Dus, als je het Git repository kloont, dan heb je vier branches die je kunt uitchecken om het project in verschillende stadia van ontwikkeling te evalueren, afhankelijk van hoe nieuw je alles wilt hebben of hoe je wil bijdragen; en de beheerder heeft een gestructureerde werkwijze om ze te helpen nieuwe bijdragen aan de tand te voelen. #### Rebasen en cherry pick werkwijzen #### @@ -855,7 +855,7 @@ Omdat Git geen monotone oplopende nummers heeft zoals 'v123' of iets gelijkwaard $ git describe master v1.6.2-rc1-20-g8c5b85c -Op deze manier kun je een snapshot of bouw exporteren en het vernoemen naar iets dat begrijpelijk is voor mensen. In feite, als je Git vanaf broncode bouwt, gecloned van het Git repository, geeft `git --version` je iets dat er zo uitziet. Als je een commit omschrijft die je direct getagged wil hebben, dat geeft het je de tag naam. +Op deze manier kun je een snapshot of bouw exporteren en het vernoemen naar iets dat begrijpelijk is voor mensen. In feite, als je Git vanaf broncode bouwt, gekloond van het Git repository, geeft `git --version` je iets dat er zo uitziet. Als je een commit omschrijft die je direct getagged wil hebben, dat geeft het je de tag naam. Het `git describe` commando heeft de voorkeur voor beschreven tags (tags gecreëerd met de `-a` of `-s` vlag), dus vrijgave tags zouden op deze manier aangemaakt moeten worden als je `git describe` gebruikt, om er zeker van te zijn dat de commit juist benoemd wordt als het omschreven wordt. Je kunt deze tekst gebruiken als het doel van een checkout of show commando, alhoewel het afhangt van de verkorte SHA-1 waarde aan het einde, dus het zou niet voor altijd geldig kunnen zijn. Bijvoorbeeld, de Linux kernel sprong recentelijk van 8 naar 10 karakters om er zeker van de zijn dat de SHA-1 uniek zijn, zodat oudere `git describe` commando's ongeldig werden. diff --git a/nl/06-git-tools/01-chapter6.markdown b/nl/06-git-tools/01-chapter6.markdown index 5db811a76..e0e619490 100644 --- a/nl/06-git-tools/01-chapter6.markdown +++ b/nl/06-git-tools/01-chapter6.markdown @@ -809,11 +809,11 @@ Het gebeurt vaak dat terwijl je zit te werken aan het ene project, je een ander Hier is een voorbeeld. Stel dat je een website aan het ontwikkelen bent en Atom feeds aan het maken bent. In plaats van je eigen Atom feedcode te schrijven, besluit je een library te gebruiken. Je zult deze code waarschijnlijk moeten includen van een gedeelde library zoals een CPAN installatie of een Ruby gem, of de broncode kopiëren naar je eigen projectboom. Het probleem met de library includen is dat het lastig is om de library op enige manier aan te passen, en vaak is het lastiger om het uit te rollen, omdat je zeker moet zijn dat iedere klant die library beschikbaar heeft. Het probleem van de broncode in je project stoppen is dat alle aanpassingen die je maakt lastig te mergen zijn op het moment dat stroomopwaarts veranderingen beschikbaar komen. -Git pakt dit probleem aan door submodules te gebruiken. Submodules geven je de mogelijkheid om een Git repository als een subdirectory van een ander Git repository te gebruiken. Dit staat je toe een ander repository in je project te clonen en je commits gescheiden te houden. +Git pakt dit probleem aan door submodules te gebruiken. Submodules geven je de mogelijkheid om een Git repository als een subdirectory van een ander Git repository te gebruiken. Dit staat je toe een ander repository in je project te klonen en je commits gescheiden te houden. ### Beginnen met submodules ### -Stel dat je de Rack library (een Ruby web server gateway interface) wilt toevoegen aan je project, misschien je eigen veranderingen eraan wilt onderhouden, maar ook veranderingen van stroomopwaarts wilt mergen. Het eerste dat je zou moeten doen is het externe repository clonen in jouw submap. Je voegt externe projecten als submodules toe door middel van het `git submodule add` commando: +Stel dat je de Rack library (een Ruby web server gateway interface) wilt toevoegen aan je project, misschien je eigen veranderingen eraan wilt onderhouden, maar ook veranderingen van stroomopwaarts wilt mergen. Het eerste dat je zou moeten doen is het externe repository klonen in jouw submap. Je voegt externe projecten als submodules toe door middel van het `git submodule add` commando: $ git submodule add git://github.com/chneukirchen/rack.git rack Initialized empty Git repository in /opt/subtest/rack/.git/ @@ -841,7 +841,7 @@ Eerst zie je het `.gitmodules` bestand. Dit is een configuratie bestand dat de m path = rack url = git://github.com/chneukirchen/rack.git -Als je meerdere submodules hebt, zul je meerdere vermeldingen hebben in dit bestand. Het is belangrijk om te zien dat dit bestand net als je andere bestanden ook onder versiebeheer staat, zoals je `.gitignore` bestand. Het wordt gepusht en gepulled samen met de rest van je project. Op deze manier weten andere mensen die je project clonen waar ze de submodule projecten vandaan moeten halen. +Als je meerdere submodules hebt, zul je meerdere vermeldingen hebben in dit bestand. Het is belangrijk om te zien dat dit bestand net als je andere bestanden ook onder versiebeheer staat, zoals je `.gitignore` bestand. Het wordt gepusht en gepulled samen met de rest van je project. Op deze manier weten andere mensen die je project klonen waar ze de submodule projecten vandaan moeten halen. De andere vermelding in de `git status` output is de rack regel. Als je `git diff` daarop uitvoert zul je iets interessants zien: @@ -854,7 +854,7 @@ De andere vermelding in de `git status` output is de rack regel. Als je `git dif @@ -0,0 +1 @@ +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 -Alhoewel `rack` een submap in je werkmap is, ziet Git het als een submodule en zal de inhoud niet volgen als je niet in die map staat. In plaats daarvan slaat Git het als een aparte commit op van dat repository. Als je wijzigingen maakt en in die submap een commit doet, zal het superproject zien dat de HEAD daarin is veranderd en de exacte commit opslaan waarvan je op dat moment zit te werken; op die manier zullen anderen die dit project clonen de omgeving exact kunnen reproduceren. +Alhoewel `rack` een submap in je werkmap is, ziet Git het als een submodule en zal de inhoud niet volgen als je niet in die map staat. In plaats daarvan slaat Git het als een aparte commit op van dat repository. Als je wijzigingen maakt en in die submap een commit doet, zal het superproject zien dat de HEAD daarin is veranderd en de exacte commit opslaan waarvan je op dat moment zit te werken; op die manier zullen anderen die dit project klonen de omgeving exact kunnen reproduceren. Dit is een belangrijk punt met submodules: je slaat ze op als de exacte commit waar ze op staan. Je kunt een submodule niet opslaan als `master` of een andere symbolische referentie. @@ -884,9 +884,9 @@ Je kunt de `rack` map als een apart project behandelen en je superproject van ti Document version change -### Een project met submodules clonen ### +### Een project met submodules klonen ### -Hier zul je een project met een submodule erin clonen. Als je zo'n project ontvangt, krijg je de mappen die submodules bevatten, maar nog niet meteen de bestanden: +Hier zul je een project met een submodule erin klonen. Als je zo'n project ontvangt, krijg je de mappen die submodules bevatten, maar nog niet meteen de bestanden: $ git clone git://github.com/schacon/myproject.git Initialized empty Git repository in /opt/myproject/.git/ @@ -1007,7 +1007,7 @@ Van branches wisselen die submodules bevatten kan ook lastig zijn. Als je een ni # # rack/ -Je moet hem verplaatsen of verwijderen, waarna je hem opnieuw moet clonen als je terug wisselt – en je loopt kans om locale wijzigingen of branches te verliezen die je niet omhoog gepusht hebt. +Je moet hem verplaatsen of verwijderen, waarna je hem opnieuw moet klonen als je terug wisselt – en je loopt kans om locale wijzigingen of branches te verliezen die je niet omhoog gepusht hebt. De laatste grote valkuil waar veel mensen in lopen heeft te maken met het wisselen van submappen naar submodules. Als je bestanden in je project aan het volgen bent, en je wilt ze in een submodule verplaatsen, dan moet je voorzichtig zijn of anders zal Git boos op je worden. Stel dat je de rack bestanden in een submap van je project hebt, en je wilt die naar een submodule wijzigen. Als je de submap weggooit en dan `submodule add` uitvoerd, begint Git naar je te schreeuwen: @@ -1039,7 +1039,7 @@ Je moet de `rack` submodule map verplaatsen voordat je naar een branch kunt wiss $ ls README rack -Als je dan terug wisselt krijg je een lege `rack` map. Je kunt dan nogmaals `git submodule update` uitvoeren om nog eens te clonen, of je kunt je `/tmp/rack` map terug zetten in de lege map. +Als je dan terug wisselt krijg je een lege `rack` map. Je kunt dan nogmaals `git submodule update` uitvoeren om nog eens te klonen, of je kunt je `/tmp/rack` map terug zetten in de lege map. ## Subboom mergen ## diff --git a/nl/07-customizing-git/01-chapter7.markdown b/nl/07-customizing-git/01-chapter7.markdown index 583a2eaf5..7eb2a3a2b 100644 --- a/nl/07-customizing-git/01-chapter7.markdown +++ b/nl/07-customizing-git/01-chapter7.markdown @@ -504,7 +504,7 @@ De `commit-msg` hook accepteert één parameter, wat weer het pad naar een tijde Nadat het hele commit proces afgerond is, zal de `post-commit` haak uitgevoerd worden. Het accepteert geen parameters, maar je kunt de laatste commit eenvoudig ophalen door `git log -1 HEAD` uit te voeren. Over het algemeen wordt dit script gebruikt om notificaties of iets dergelijks uit te sturen. -De commit-werkwijze client-kant scripts kunnen gebruikt worden in vrijwel iedere werkwijze. Ze worden vaak gebruikt om een bepaald beleid af te dwingen, maar het is belangrijk om te weten dat deze scripts niet overgedragen worden tijdens een clone. Je kunt beleid afdwingen op de server kant om pushes of commits te weigeren, die niet voldoen aan een bepaald beleid, maar het is aan de ontwikkelaar om deze scripts aan de client kant te gebruiken. Dus, deze scripts zijn er om ontwikkelaars te helpen, en ze moeten door hen ingesteld en onderhouden worden, alhoewel ze aangepast of omzeilt kunnen worden op ieder tijdstip. +De commit-werkwijze client-kant scripts kunnen gebruikt worden in vrijwel iedere werkwijze. Ze worden vaak gebruikt om een bepaald beleid af te dwingen, maar het is belangrijk om te weten dat deze scripts niet overgedragen worden bij het klonen. Je kunt beleid afdwingen op de server kant om pushes of commits te weigeren, die niet voldoen aan een bepaald beleid, maar het is aan de ontwikkelaar om deze scripts aan de client kant te gebruiken. Dus, deze scripts zijn er om ontwikkelaars te helpen, en ze moeten door hen ingesteld en onderhouden worden, alhoewel ze aangepast of omzeilt kunnen worden op ieder tijdstip. #### E-mail werkwijze haken #### @@ -763,7 +763,7 @@ Dat is alles. Vanaf nu, zolang als het `update` script aanwezig en uitvoerbaar i Het nadeel hiervan is het zeuren dat geheid zal gebeuren zodra de commits van je gebruikers geweigerd worden. Het feit dat hun zorgzaam vervaardigde werk geweigerd wordt op het laatste moment kan enorm frustrerend en verwarrend zijn: daarnaast, zullen ze hun geschiedenis moeten aanpassen om het te corrigeren, wat niet altijd voor de mensen met een zwak hart is. -Het antwoord op dit dilemma is een aantal client-kant haken te leveren, die gebruikers kunnen toepassen om hen te waarschuwen dat ze iets doen dat de server waarschijnlijk gaat weigeren. Op die manier kunnen ze alle problemen corrigeren voordat ze gaan committen en voordat die problemen moeilijk te herstellen zijn. Omdat haken niet overgebracht worden bij een clone van een project, moet je deze scripts op een andere manier distribueren en je gebruikers ze dan in hun `.git/hooks` map laten zetten en ze uitvoerbaar maken. Je kunt deze haken in je project of in een apart project distribueren, maar er is geen manier om ze automatisch in te laten stellen. +Het antwoord op dit dilemma is een aantal client-kant haken te leveren, die gebruikers kunnen toepassen om hen te waarschuwen dat ze iets doen dat de server waarschijnlijk gaat weigeren. Op die manier kunnen ze alle problemen corrigeren voordat ze gaan committen en voordat die problemen moeilijk te herstellen zijn. Omdat haken niet overgebracht worden bij het klonen van een project, moet je deze scripts op een andere manier distribueren en je gebruikers ze dan in hun `.git/hooks` map laten zetten en ze uitvoerbaar maken. Je kunt deze haken in je project of in een apart project distribueren, maar er is geen manier om ze automatisch in te laten stellen. Om te beginnen zou je je commit boodschap moeten controleren, vlak voordat iedere commit opgeslagen wordt, zodat je weet dat de server je wijzigingen niet gaat weigeren omdat de commit boodschap een verkeerd formaat heeft. Om dit te doen, kun je de `commit-msg` haak toevoegen. Als je dat de commit boodschap laat lezen uit het bestand dat als eerste argument opgegeven wordt, en dat vergelijkt met het patroon, dan kun je Git forceren om de commit af te breken als er geen overeenkomst is: diff --git a/nl/08-git-and-other-scms/01-chapter8.markdown b/nl/08-git-and-other-scms/01-chapter8.markdown index 43d6f8d3d..17549bcc7 100644 --- a/nl/08-git-and-other-scms/01-chapter8.markdown +++ b/nl/08-git-and-other-scms/01-chapter8.markdown @@ -38,7 +38,7 @@ Je kunt dit project nu syncen naar je lokale machine door `svnsync init` aan te $ svnsync init file:///tmp/test-svn http://progit-example.googlecode.com/svn/ -Dit stelt de eigenschappen in om de sync uit te voeren. Je kunt de code dan clonen door dit uit te voeren +Dit stelt de eigenschappen in om de sync uit te voeren. Je kunt de code dan klonen door dit uit te voeren $ svnsync sync file:///tmp/test-svn Committed revision 1. @@ -48,11 +48,11 @@ Dit stelt de eigenschappen in om de sync uit te voeren. Je kunt de code dan clon Committed revision 3. ... -Alhoewel deze operatie maar een paar minuten in beslag neemt, zal het kopiëren van het originele repository naar een ander remote repository in plaat van een lokale meer dan een uur duren, terwijl er minder dan 100 commits in zitten. Subversion moet één revisie per keer clonen en dan terug pushen in een ander repository – het is belachelijk inefficiënt, maar het is de enige makkelijke manier om dit te doen. +Alhoewel deze operatie maar een paar minuten in beslag neemt, zal het kopiëren van het originele repository naar een ander remote repository in plaat van een lokale meer dan een uur duren, terwijl er minder dan 100 commits in zitten. Subversion moet één revisie per keer klonen en dan terug pushen in een ander repository – het is belachelijk inefficiënt, maar het is de enige makkelijke manier om dit te doen. ### Beginnen ### -Nu dat je een Subversion repository hebt met schrijftoegang, kun je door een typische werkwijze gaan. Je begint met het `git svn clone` commando, wat een volledig Subversion repository in een lokaal Git repository clonet. Onthoud dat als je van een echt beheerd Subversion repository importeert, je de `file:///tmp/test-svn` hier moet vervangen door de URL van je Subversion repository: +Nu dat je een Subversion repository hebt met schrijftoegang, kun je door een typische werkwijze gaan. Je begint met het `git svn clone` commando, wat een volledig Subversion repository in een lokaal Git repository kloont. Onthoud dat als je van een echt beheerd Subversion repository importeert, je de `file:///tmp/test-svn` hier moet vervangen door de URL van je Subversion repository: $ git svn clone file:///tmp/test-svn -T trunk -b branches -t tags Initialized empty Git repository in /Users/schacon/projects/testsvnsync/svn/.git/ @@ -87,7 +87,7 @@ Op dit punt zou je een geldig Git repository moeten hebben, dat je branches en t tags/release-2.0.2rc1 trunk -Het is belangrijk om te zien hoe dit tool je remote references een andere naamruimte toebedeeld. Als je een normaal Git repository clonet, krijg je alle branches op die remote server lokaal beschikbaar in de vorm van `origin/[branch]` – volgens de naamruimte van de remote. Maar, `git svn` gaat er vanuit dan je niet meerdere remotes hebt en bewaard al zijn referentie punten om de remote server zonder naamruimte. Je kunt het Git loodgieters commando `show-ref` gebruiken om naar al je volledige referentie namen te kijken: +Het is belangrijk om te zien hoe dit tool je remote references een andere naamruimte toebedeeld. Als je een normaal Git repository kloont, krijg je alle branches op die remote server lokaal beschikbaar in de vorm van `origin/[branch]` – volgens de naamruimte van de remote. Maar, `git svn` gaat er vanuit dan je niet meerdere remotes hebt en bewaard al zijn referentie punten om de remote server zonder naamruimte. Je kunt het Git loodgieters commando `show-ref` gebruiken om naar al je volledige referentie namen te kijken: $ git show-ref 1cbd4904d9982f386d87f88fce1c24ad7c0f0471 refs/heads/master @@ -227,7 +227,7 @@ Stel dat je geschiedenis er zoals volgt uitziet: je hebt een `experiment` branch Het uitvoeren van `dcommit` op een branch met gemergede historie werkt prima, behalve wanneer je naar je Git project historie kijkt, het geen van beide commits die je op de `experiment` branch gedaan hebt herschreven heeft – in plaats daarvan verschijnen al die wijzigingen in de SVN versie van de enkele merge commit. -Als iemand anders dat werk clonet, is alles wat ze zien de merge commit met al het werk erin gesquashed; ze zien niet de commit data met waar het vandaan kwam of wanneer het was gecommit. +Als iemand anders dat werk kloont, is alles wat ze zien de merge commit met al het werk erin gesquashed; ze zien niet de commit data met waar het vandaan kwam of wanneer het was gecommit. ### Subversion branchen ### @@ -326,7 +326,7 @@ Dit is vergelijkbaar met `blame` en `log` in dat het offline draait en alleen up #### Negeren wat Subversion negeert #### -Als je een Subversion repository clonet, die ergens `svn:ignore` eigenschappen gezet heeft, dan zul je waarschijnlijk overeenkomende `.gitignore` bestanden in willen stellen zo dat je niet per ongeluk bestanden commit die je niet had moeten committen. `git svn` heeft twee commando's die met dit probleem helpen. De eerste is `git svn create-ignore`, wat automatisch `.gitignore` bestanden voor je genereert zodat je volgende commit ze niet kan bevatten. +Als je een Subversion repository kloont, die ergens `svn:ignore` eigenschappen gezet heeft, dan zul je waarschijnlijk overeenkomende `.gitignore` bestanden in willen stellen zo dat je niet per ongeluk bestanden commit die je niet had moeten committen. `git svn` heeft twee commando's die met dit probleem helpen. De eerste is `git svn create-ignore`, wat automatisch `.gitignore` bestanden voor je genereert zodat je volgende commit ze niet kan bevatten. Het tweede commando is `git svn show-ignore`, want op stdout de regels afdrukt die je in een `.gitignore` bestand moet stoppen zodat je de output in het exclude bestand van je project kunt stoppen: @@ -339,7 +339,7 @@ Op die manier vervuil je het project niet met `.gitignore` bestanden. Dit is een De `git svn` tools zijn bruikbaar als je voorlopig vast zit aan een Subversion server, of op een andere manier in een ontwikkelomgeving zit waar het draaien van een Subversion server noodzakelijk is. Je moet het echter beschouwen als een kreupele Git, of anders loop je tegen problemen in de vertaling aan, die jou en je medewerkers in verwarring kunnen brengen. Om uit de problemen te blijven moet je deze regels volgen: * Houdt een lineaire Git historie aan, die geen merge commits bevat die gedaan zijn door `git merge`. Rebase al het werk dat je buiten je hoofd branch doet er terug in; niet erin mergen. -* Geen aparte Git server instellen en daar op samenwerken. Je kunt er een hebben om clones voor nieuwe developers te versnellen, maar push er niets terug in dat geen `git-svn-id` vermelding heeft. Je zou zelfs een `pre-receive` haak kunnen toevoegen, die ieder commit bericht na kijkt op een `git-svn-id` en pushes weigert die commits zonder bevatten. +* Geen aparte Git server instellen en daar op samenwerken. Je kunt er een hebben om klonen voor nieuwe developers te versnellen, maar push er niets terug in dat geen `git-svn-id` vermelding heeft. Je zou zelfs een `pre-receive` haak kunnen toevoegen, die ieder commit bericht na kijkt op een `git-svn-id` en pushes weigert die commits zonder bevatten. Als je deze regels volgt, dan kan werken met een Subversion server meer dragelijk zijn. Maar, als het mogelijk is om over te gaan naar een echte Git server, dan kan dat je team een hoop meer toevoegen. diff --git a/nl/09-git-internals/01-chapter9.markdown b/nl/09-git-internals/01-chapter9.markdown index be7e5a45c..c73cbd7c1 100644 --- a/nl/09-git-internals/01-chapter9.markdown +++ b/nl/09-git-internals/01-chapter9.markdown @@ -748,7 +748,7 @@ In beide gevallen stuurt `upload-pack`, nadat `fetch-pack` verbinding gemaakt he 003e085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 refs/heads/topic 0000 -Dit komt erg overeen met waarmee `receive-pack` antwoord, maar de mogelijkheden zijn verschillend. Daarnaast stuurt het de HEAD referentie zodat de client weet wat er uitgechecked moet worden als dit een clone is. +Dit komt erg overeen met waarmee `receive-pack` antwoord, maar de mogelijkheden zijn verschillend. Daarnaast stuurt het de HEAD referentie zodat de client weet wat er uitgechecked moet worden als dit een kloon is. Op dit punt kijkt het `fetch-pack` proces naar welk objecten dat het heeft en antwoord met de objecten die het nodig heeft door "want" te sturen, gevolgd door de SHA die het wil. Het stuurt al de objecten die het al heeft met "have" en dan de SHA. Aan het einde van deze lijst, schrijft het "done" om het `upload-pack` proces te starten met het sturen van de packfile van de gegevens die het nodig heeft: @@ -872,7 +872,7 @@ In dit geval, kun je je vermiste commit zien na de hangende commit. Je kunt het ### Objecten verwijderen ### -Er zijn een hoop geweldige dingen aan Git, maar één eigenschap die problemen kan geven is het feit dat `git clone` de hele historie van het project download, inclusief alle versies van alle bestanden. Dat is geen probleem als het hele ding broncode is, omdat Git zeer geoptimaliseerd is om die gegevens optimaal te comprimeren. Maar, als iemand op een bepaald punt in de geschiedenis een enkel enorm bestand heeft toegevoegd, zal iedere clone voor altijd gedwongen worden om dat grote bestand te downloaden, zelfs als het uit het project was verwijderd in de volgende commit. Omdat het bereikbaar is vanuit de geschiedenis, zal het er altijd zijn. +Er zijn een hoop geweldige dingen aan Git, maar één eigenschap die problemen kan geven is het feit dat `git clone` de hele historie van het project download, inclusief alle versies van alle bestanden. Dat is geen probleem als het hele ding broncode is, omdat Git zeer geoptimaliseerd is om die gegevens optimaal te comprimeren. Maar, als iemand op een bepaald punt in de geschiedenis een enkel enorm bestand heeft toegevoegd, zal iedere kloon voor altijd gedwongen worden om dat grote bestand te downloaden, zelfs als het uit het project was verwijderd in de volgende commit. Omdat het bereikbaar is vanuit de geschiedenis, zal het er altijd zijn. Dit kan een groot probleem zijn als je Subversion of Perforce repositories omzet naar Git. Omdat je niet de hele geschiedenis download in die systemen, zal dit soort toevoeging een paar gevolgen met zich meebrengen. Als je een import vanuit een ander systeem deed, of om een andere reden vindt dat je repository veel groter is dan het zou moeten zijn, kun je hier zien hoe je grote objecten kunt vinden en verwijderen. @@ -916,7 +916,7 @@ Je kunt het `count-objects` commando gebruiken om snel te zien hoeveel ruimte je prune-packable: 0 garbage: 0 -Op de `size-pack` regel staat de grootte van je packfiles in kilobytes, dus je gebruikt 2Mb. Voor de laatste commit gebruikte je bijna 2K – dus het is duidelijk dat het verwijderen van het bestand uit de vorige commit, het niet uit je geschiedenis verwijderd heeft. Iedere keer als iemand dit repository clonet, zullen ze de volle 2Mb moeten clonen alleen maar om dit kleine project te krijgen, omdat jij per ongeluk een groot bestand toegevoegd hebt. Laten we het kwijtraken. +Op de `size-pack` regel staat de grootte van je packfiles in kilobytes, dus je gebruikt 2Mb. Voor de laatste commit gebruikte je bijna 2K – dus het is duidelijk dat het verwijderen van het bestand uit de vorige commit, het niet uit je geschiedenis verwijderd heeft. Iedere keer als iemand dit repository kloont, zullen ze de volle 2Mb moeten klonen alleen maar om dit kleine project te krijgen, omdat jij per ongeluk een groot bestand toegevoegd hebt. Laten we het kwijtraken. Eerst moet je het vinden. In dit geval weet je al welk bestand het is. Maar stel dat je het niet wist; hoe zou je kunnen vinden welk bestand of bestanden zoveel ruimte in beslag nemen? Als je `git gc` uitvoert zitten alle objecten in een packfile; je kunt de grote bestanden identificeren door een ander sanitaire voorzieningen commando genaamd `git verify-pack` uit te voeren en te sorteren op het derde veld in de uitvoer, wat de bestandsgrootte is. Je kunt het ook door het `tail` commando leiden omdat je alleen geïnteresseerd bent in het laatste paar grote bestanden. @@ -968,7 +968,7 @@ Laten we eens zien hoeveel ruimte je bespaard hebt. prune-packable: 0 garbage: 0 -De grootte van je ingepakte repository is omlaag gegaan naar 7 K, wat veel beter is dan 2 Mb. Je kunt aan de waarde van size zien dat het grootte object nog steeds in je losse bestanden staat, dus het is niet weg; maar het zal niet meer overgedragen worden bij een push of opvolgende clone, wat het belangrijkste is. Als je het echt zou willen, kun je het object volledig verwijderen door `git prune --expire` uit te voeren. +De grootte van je ingepakte repository is omlaag gegaan naar 7 K, wat veel beter is dan 2 Mb. Je kunt aan de waarde van size zien dat het grootte object nog steeds in je losse bestanden staat, dus het is niet weg; maar het zal niet meer overgedragen worden bij een push of opvolgende kloon, wat het belangrijkste is. Als je het echt zou willen, kun je het object volledig verwijderen door `git prune --expire` uit te voeren. ## Samenvatting ## From 4e922f1449cfc8c36eb0150247af3a46a8ef287c Mon Sep 17 00:00:00 2001 From: Jean-Noel Avila Date: Fri, 13 Dec 2013 22:42:08 +0100 Subject: [PATCH 075/862] format latex longtables Now pandoc uses the package longtable of latex to manage tables. The default setup does not restrict column width. The explanation column must be constrained to fit in the page's width. --- latex/makepdf | 1 + 1 file changed, 1 insertion(+) diff --git a/latex/makepdf b/latex/makepdf index 309ccd4cd..c049c6db3 100755 --- a/latex/makepdf +++ b/latex/makepdf @@ -130,6 +130,7 @@ def post_pandoc(string, config) # Style ctables s /ctable\[pos = H, center, botcap\]\{..\}/ , 'ctable[pos = ht!, caption = ~ ,width = 130mm, center, botcap]{lX}' + s /longtable\}\[c\]\{\@\{\}ll\@\{\}\}/ , 'longtable}[c]{@{}lp{10cm}@{}}' # Shaded verbatim block s /(\\begin\{verbatim\}.*?\\end\{verbatim\})/m, '\begin{shaded}\1\end{shaded}' From bdef6f762f3cc3652c142cc64aa2342f9e0da9da Mon Sep 17 00:00:00 2001 From: Daniel Rosen Date: Mon, 16 Dec 2013 00:35:12 -0500 Subject: [PATCH 076/862] Monospace branch names --- en/03-git-branching/01-chapter3.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/03-git-branching/01-chapter3.markdown b/en/03-git-branching/01-chapter3.markdown index 8924dbe5e..bf0028744 100644 --- a/en/03-git-branching/01-chapter3.markdown +++ b/en/03-git-branching/01-chapter3.markdown @@ -460,7 +460,7 @@ To set up a local branch with a different name than the remote branch, you can e Branch sf set up to track remote branch refs/remotes/origin/serverfix. Switched to a new branch "sf" -Now, your local branch sf will automatically push to and pull from origin/serverfix. +Now, your local branch `sf` will automatically push to and pull from `origin/serverfix`. ### Deleting Remote Branches ### From 21e84addadf2ea58eebfeb77379fc0434aa952a3 Mon Sep 17 00:00:00 2001 From: Jean-Noel Avila Date: Sat, 14 Dec 2013 17:44:02 +0100 Subject: [PATCH 077/862] Direct the reader directly to the git-completion download link This is easier than forking the project. This closes #537 --- en/02-git-basics/01-chapter2.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/en/02-git-basics/01-chapter2.markdown b/en/02-git-basics/01-chapter2.markdown index 0f17912e7..bbf48f64d 100644 --- a/en/02-git-basics/01-chapter2.markdown +++ b/en/02-git-basics/01-chapter2.markdown @@ -1105,9 +1105,9 @@ Before we finish this chapter on basic Git, a few little tips and tricks may mak ### Auto-Completion ### -If you use the Bash shell, Git comes with a nice auto-completion script you can enable. Download the Git source code, and look in the `contrib/completion` directory; there should be a file called `git-completion.bash`. Copy this file to your home directory, and add this to your `.bashrc` file: +If you use the Bash shell, Git comes with a nice auto-completion script you can enable. Download it directly from the Git source code at https://github.com/git/git/blob/master/contrib/completion/git-completion.bash . Copy this file to your home directory, and add this to your `.bashrc` file: - source ~/.git-completion.bash + source ~/git-completion.bash If you want to set up Git to automatically have Bash shell completion for all users, copy this script to the `/opt/local/etc/bash_completion.d` directory on Mac systems or to the `/etc/bash_completion.d/` directory on Linux systems. This is a directory of scripts that Bash will automatically load to provide shell completions. From 1ca5ef1602de99198882a0153b8c3f399317e76f Mon Sep 17 00:00:00 2001 From: Daniel Rosen Date: Mon, 16 Dec 2013 13:53:24 -0500 Subject: [PATCH 078/862] Monospace branch names --- en/05-distributed-git/01-chapter5.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/en/05-distributed-git/01-chapter5.markdown b/en/05-distributed-git/01-chapter5.markdown index 6bf3e1d49..839206022 100644 --- a/en/05-distributed-git/01-chapter5.markdown +++ b/en/05-distributed-git/01-chapter5.markdown @@ -174,7 +174,7 @@ John has a reference to the changes Jessica pushed up, but he has to merge them The merge goes smoothly — John’s commit history now looks like Figure 5-5. Insert 18333fig0505.png -Figure 5-5. John’s repository after merging origin/master. +Figure 5-5. John’s repository after merging `origin/master`. Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: @@ -215,7 +215,7 @@ Jessica thinks her topic branch is ready, but she wants to know what she has to removed invalid default value -Now, Jessica can merge her topic work into her master branch, merge John’s work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her master branch to integrate all this work: +Now, Jessica can merge her topic work into her `master` branch, merge John’s work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her `master` branch to integrate all this work: $ git checkout master Switched to branch "master" @@ -255,7 +255,7 @@ Each developer has committed a few times and merged each other’s work successf Insert 18333fig0510.png Figure 5-10. Jessica’s history after pushing all changes back to the server. -That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it’s ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. +That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your `master` branch when it’s ready to be integrated. When you want to share that work, you merge it into your own `master` branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. Insert 18333fig0511.png Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. From 3b521615096731baac52616a486082669de71b48 Mon Sep 17 00:00:00 2001 From: Joop Kiefte Date: Wed, 18 Dec 2013 11:47:24 +0100 Subject: [PATCH 079/862] Complete the long unfinished paragraph... --- eo/01-introduction/01-chapter1.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eo/01-introduction/01-chapter1.markdown b/eo/01-introduction/01-chapter1.markdown index 0545f8f69..08a3caae9 100644 --- a/eo/01-introduction/01-chapter1.markdown +++ b/eo/01-introduction/01-chapter1.markdown @@ -6,7 +6,7 @@ Kio estas versikontrolo, kaj kial vi okupiĝu pri tio? Versikontrolo estas sistemo kiu registras ŝanĝojn pri dosiero aŭ dosieraro dumtempe por ke vi povu revoki specifajn versiojn poste. Por la ekzemploj en ĉi tiu libro vi uzos programaran fontkodon kiel la dosierojn versikontrolataj, sed vere vi povas fari ĉi tion pri ĉiaj dosieroj komputilaj. -Se vi estas grafika aŭ retpaĝa dizajnisto kaj vi volas If you are a graphic or web designer and want to keep every version of an image or layout (which you would most certainly want to), a Version Control System (VCS) is a very wise thing to use. It allows you to revert files back to a previous state, revert the entire project back to a previous state, compare changes over time, see who last modified something that might be causing a problem, who introduced an issue and when, and more. Using a VCS also generally means that if you screw things up or lose files, you can easily recover. In addition, you get all this for very little overhead. +Se vi estas grafika aŭ retpaĝa dizajnisto kaj vi volas manteni ĉiujn versiojn de bildo aŭ aspekto (kion vi nepre volu), versikontrola sistemo (VCS, version control system en la angla) estas tre uzinda. Ĝi permesas al vi remeti dosierojn al antaŭa stato, kompari ŝanĝojn laŭ la tempo, vidi kiu ŝanĝis ion kio povus kaŭzi problemon, kiu enmetis problemon kaj kiam, kaj pli. Uzante VCSon kutime ankaŭ signifas ke se vi ion fuŝigis aŭ se vi perdis dosierojn, vi facile povas reiri. Aldone, vi ĉion tion havas kun malmulta superŝarĝo. ### Local Version Control Systems ### From 8b268f061c3803a47691a2aebf2e9ab367f22619 Mon Sep 17 00:00:00 2001 From: green-big-frog Date: Thu, 19 Dec 2013 21:02:28 +0100 Subject: [PATCH 080/862] Update 01-chapter1.markdown check for mistakes add "sudo" by ubuntu package installation ... --- de/01-introduction/01-chapter1.markdown | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/de/01-introduction/01-chapter1.markdown b/de/01-introduction/01-chapter1.markdown index 926d7b0e3..c26220525 100644 --- a/de/01-introduction/01-chapter1.markdown +++ b/de/01-introduction/01-chapter1.markdown @@ -10,7 +10,7 @@ In diesem Kapitel wird es darum gehen, wie man mit Git loslegen kann. Wir werden -Was ist Versionskontrolle, und warum solltest Du dich dafür interessieren? Versionskontrollsysteme (VCS) protokollieren Änderungen an einer Datei oder einer Anzahl von Dateien über die Zeit hinweg, so dass man zu jedem Zeitpunkt auf Versionen und Änderungen zugreifen kann. Die Beispiele in diesem Buch verwenden Software Quellcode, tatsächlich aber kannst Du Änderungen an praktisch jeder Art von Datei per Versionskontrolle nachverfolgen. +Was ist die Versionskontrolle, und warum solltest Du dich dafür interessieren? Versionskontrollsysteme (VCS) protokollieren Änderungen an einer Datei oder einer Anzahl von Dateien über die Zeit hinweg, so dass man zu jedem Zeitpunkt auf Versionen und Änderungen zugreifen kann. Die Beispiele in diesem Buch verwenden Software Quellcode, tatsächlich aber kannst Du Änderungen an praktisch jeder Art von Datei per Versionskontrolle nachverfolgen. @@ -50,7 +50,7 @@ Bild 1-2. Diagramm: Zentralisierte Versionskontrollsysteme -Dieser Aufbau hat viele Vorteile gegenüber Lokalen Versionskontrollsystemen. Zum Beispiel weiß jeder mehr oder weniger genau darüber Bescheid, was andere, an einem Projekt Beteiligte gerade tun. Administratoren haben die Möglichkeit, detailliert festzulegen, wer was tun kann. Und es ist sehr viel einfacher, ein CVCS zu administrieren als lokalen Datenbanken auf jedem einzelnen Anwenderrechner zu verwalten. +Dieser Aufbau hat viele Vorteile gegenüber Lokalen Versionskontrollsystemen. Zum Beispiel weiß jeder mehr oder weniger genau darüber Bescheid, was andere, an einem Projekt Beteiligte gerade tun. Administratoren haben die Möglichkeit, detailliert festzulegen, wer was tun kann. Und es ist sehr viel einfacher, ein CVCS zu administrieren als lokale Datenbanken auf jedem einzelnen Anwenderrechner zu verwalten. @@ -61,7 +61,7 @@ Allerdings hat dieser Aufbau auch einige erhebliche Nachteile. Der offensichtlic -Und an dieser Stelle kommen verteilte Versionskontrollsysteme (DVCS) ins Spiel. In einem DVCS (wie z.B. Git, Mercurial, Bazaar oder Darcs) erhalten Anwender nicht einfach den jeweils letzten Snapshot des Projektes von einem Server: sie erhalten statt dessen eine vollständige Kopie des Repositories. Auf diese Weise kann, wenn ein Server beschädigt wird, jedes beliebige Repository von jedem beliebigen Anwenderrechner zurück kopiert und der Server so wieder hergestellt werden. +Und an dieser Stelle kommen verteilte Versionskontrollsysteme (DVCS) ins Spiel. In einem DVCS (wie z.B. Git, Mercurial, Bazaar oder Darcs) erhalten Anwender nicht einfach den jeweils letzten Snapshot des Projektes von einem Server: sie erhalten statt dessen eine vollständige Kopie des Repositories. Auf diese Weise kann, wenn ein Server beschädigt wird, jedes beliebige Repository von jedem beliebigen Anwenderrechner zurück kopiert werden und der Server so wieder hergestellt werden. @@ -81,7 +81,7 @@ Wie viele großartige Dinge im Leben entstand Git aus kreativem Chaos und hitzig -2005 ging die Beziehung zwischen der Community, die den Linux Kernel entwickelte, und des kommerziell ausgerichteten Unternehmens, das BitKeeper entwickelte, dann in die Brüche. Die zuvor ausgesprochene Erlaubnis, BitKeeper kostenlos zu verwenden, wurde widerrufen. Dies war für die Linux Entwickler Community der Auslöser dafür, ein eigenes Tool zu entwickeln, das auf den Erfahrungen mit BitKeeper basierte. Ziele des neuen Systems waren unter anderem: +2005 ging die Beziehung zwischen der Community, die den Linux Kernel entwickelte, und des kommerziell ausgerichteten Unternehmens, das BitKeeper entwickelte, kaputt. Die zuvor ausgesprochene Erlaubnis, BitKeeper kostenlos zu verwenden, wurde widerrufen. Dies war für die Linux Entwickler Community (und besonders für Linus Torvald, der Erfinder von Linux) der Auslöser dafür, ein eigenes Tool zu entwickeln, das auf den Erfahrungen mit BitKeeper basierte. Ziele des neuen Systems waren unter anderem: -Was also ist Git, in kurzen Worten? Es ist wichtig, den folgenden Abschnitt zu verstehen, in dem es um die grundlegenden Konzepte von Git geht. Das wird dich in die Lage versetzen, Git einfacher und effektiver anzuwenden. Versuche dein vorhandenes Wissen über andere Versionskontrollsysteme, wie Subversion oder Perforce, zu ignorieren, während Du Git lernst. Git speichert und konzipiert Information anders als andere Systeme, auch wenn das Interface relativ ähnlich wirkt. Diese Unterschiede zu verstehen wird dir helfen, Verwirrung bei der Anwendung von Git zu vermeiden. +Was also ist Git, in kurzen Worten? Es ist wichtig, den folgenden Abschnitt zu verstehen, in dem es um die grundlegenden Konzepte von Git geht. Das wird dich in die Lage versetzen, Git einfacher und effektiver anzuwenden. Versuche dein vorhandenes Wissen über andere Versionskontrollsysteme, wie Subversion oder Perforce, zu ignorieren, während Du Git kennen lernst. Git speichert und konzipiert Information anders als andere Systeme, auch wenn das Interface relativ ähnlich wirkt. Diese Unterschiede zu verstehen wird dir helfen, Verwirrung bei der Anwendung von Git zu vermeiden. ### Snapshots, nicht Diffs ### @@ -136,7 +136,7 @@ Dies ist ein wichtiger Unterschied zwischen Git und praktisch allen anderen Vers -Die meisten Operationen in Git benötigen nur die lokalen Dateien und Ressourcen auf deinem Rechner, um zu funktionieren. D.h. im Allgemeinen werden keine Informationen von einem anderen Rechner im Netzwerk benötigt. Wenn Du mit einem CVCS gearbeitet hast, das für die meisten Operationen einen Netzwerk Latency Overhead (also Wartezeiten, die das Netzwerk benötigt werden) hat, dann wirst Du den Eindruck haben, dass die Götter der Geschwindigkeit Git mit unaussprechlichen Fähigkeiten ausgestattet haben. Weil man die vollständige Historie lokal auf dem Rechner hat, werden die allermeisten Operationen ohne jede Verzögerung ausgeführt und sind sehr schnell. +Die meisten Operationen in Git benötigen nur die lokalen Dateien und Ressourcen auf deinem Rechner, um zu funktionieren. D.h. im Allgemeinen werden keine Informationen von einem anderen Rechner im Netzwerk benötigt. Wenn Du mit einem CVCS gearbeitet hast, das für die meisten Operationen einen Network Latency Overhead (also Wartezeiten, die das Netzwerk benötigt werden) hat, dann wirst Du den Eindruck haben, dass die Götter der Geschwindigkeit Git mit unaussprechlichen Fähigkeiten ausgestattet haben. Weil man die vollständige Historie lokal auf dem Rechner hat, werden die allermeisten Operationen ohne jede Verzögerung ausgeführt und sind sehr schnell. @@ -144,7 +144,7 @@ Um beispielsweise die Historie des Projektes zu durchsuchen, braucht Git sie nic -Dies bedeutet natürlich außerdem, dass es fast nichts gibt, was Du nicht tun kannst, bloß weil Du gerade offline bist oder keinen Zugriff auf ein VPN hast. Wenn Du im Flugzeug oder Zug ein wenig arbeiten willst, kannst Du problemlos deine Arbeit committen und deine Arbeit erst auf den Server pushen (hochladen), wenn Du wieder mit einem Netzwerk verbunden bist. Wenn Du zu Hause bist aber nicht auf das VPN zugreifen kannst, kannst Du dennoch arbeiten. Perforce z.B. erlaubt dir dagegen nicht sonderlich viel zu tun, solange Du nicht mit dem Server verbunden bist. Und in Subversion und CVS kannst Du Dateien zwar ändern, die Änderungen aber nicht in der Datenbank sichern (weil die Datenbank offline ist). Das mag auf den ersten Blick nicht nach einem großen Problem aussehen, aber Du wirst überrascht sein, was für einen großen Unterschied das ausmachen kann. +Dies bedeutet natürlich außerdem, dass es fast nichts gibt, was Du nicht tun kannst, bloß weil Du gerade offline bist oder keinen Zugriff auf ein VPN hast. Wenn Du im Flugzeug oder Zug ein wenig arbeiten willst, kannst Du problemlos deine Arbeit committen und deine Arbeit erst auf den Server pushen (hochladen), wenn Du wieder mit dem Internet verbunden bist. Wenn Du zu Hause bist aber nicht auf das VPN zugreifen kannst, kannst Du dennoch arbeiten. Perforce z.B. erlaubt dir dagegen nicht sonderlich viel zu tun, solange Du nicht mit dem Server verbunden bist. Und in Subversion und CVS kannst Du Dateien zwar ändern, die Änderungen aber nicht in der Datenbank sichern (weil die Datenbank offline ist). Das mag auf den ersten Blick nicht nach einem großen Problem aussehen, aber Du wirst überrascht sein, was für einen großen Unterschied das ausmachen kann. ### Git stellt Integrität sicher ### @@ -179,7 +179,7 @@ U.a. deshalb macht es so viel Spaß, mit Git zu arbeiten. Man kann mit Änderung -Jetzt aufgepasst. Es folgt die wichtigste Information, die Du dir merken mußt, wenn Du Git lernen und Fallstricke vermeiden willst. Git definiert drei Haupt-Zustände, in denen sich eine Datei befinden kann: committed, modified ("geändert") und staged ("vorgemerkt"). "Committed" bedeutet, dass die Daten in der lokalen Datenbank gesichert sind. "Modified" bedeutet, dass die Datei geändert, diese Änderung aber noch nicht committed wurde. "Staged" bedeutet, dass Du eine geänderte Datei in ihrem gegenwärtigen Zustand für den nächsten Commit vorgemerkt hast. +Jetzt aufgepasst. Es folgt die wichtigste Information, die Du dir merken mußt, wenn Du Git kennen lernen willst und Fallstricke vermeiden willst. Git definiert drei Haupt-Zustände, in denen sich eine Datei befinden kann: committed, modified ("geändert") und staged ("vorgemerkt"). "Committed" bedeutet, dass die Daten in der lokalen Datenbank gesichert sind. "Modified" bedeutet, dass die Datei geändert, diese Änderung aber noch nicht committed wurde. "Staged" bedeutet, dass Du eine geänderte Datei in ihrem gegenwärtigen Zustand für den nächsten Commit vorgemerkt hast. @@ -239,7 +239,7 @@ Um Git zu installieren, benötigst Du die folgenden Bibliotheken, die von Git ve $ yum install curl-devel expat-devel gettext-devel \ openssl-devel zlib-devel - $ apt-get install curl-devel expat-devel gettext-devel \ + $ sudo apt-get install curl-devel expat-devel gettext-devel \ openssl-devel zlib-devel @@ -276,7 +276,7 @@ Wenn Du Git unter Linux mit einem Installationsprogramm installieren willst, kan Auf einem Debian-basierten System wie Ubuntu steht dir apt-get zur Verfügung: - $ apt-get install git + $ sudo apt-get install git ### Installation unter Mac OS X ### @@ -425,7 +425,7 @@ Beispielsweise erhältst Du die Hilfeseite für den `git config` Befehl so: -Die "manpage" Dokumentation ist nützlich, weil Du sie jederzeit anzeigen kannst, auch wenn Du offline bist. Wenn dir die manpages und dieses Buch nicht ausreichen, kannst Du deine Fragen auch in den Chaträumen `#git` oder `#github` auf dem Freenode IRC Server (irc.freenode.net) stellen. Diese Räume sind in der Regel sehr gut besucht. Normalerweise findet sich unter den hunderten von Anwendern, die oft sehr viel Erfahrung mit Git haben, irgendjemand, der deine Fragen gern beantwortet. +Die "manpage" Dokumentation ist nützlich, weil Du sie dir jederzeit anzeigen lassen kannst, auch wenn Du offline bist. Wenn dir die manpages und dieses Buch nicht ausreichen, kannst Du deine Fragen auch in den Chaträumen `#git` oder `#github` auf dem Freenode IRC Server (irc.freenode.net) stellen. Diese Räume sind in der Regel sehr gut besucht. Normalerweise findet sich unter den hunderten von Anwendern, die oft sehr viel Erfahrung mit Git haben, irgendjemand, der deine Fragen gern beantwortet. ## Zusammenfassung ## From d68d21702618b0cb964131cb8257305ef25f0288 Mon Sep 17 00:00:00 2001 From: Tuan Vu Date: Sat, 21 Dec 2013 14:02:56 +0000 Subject: [PATCH 081/862] Add new directory for Vietnamese translation --- vi/01-introduction/01-chapter1.markdown | 259 ++++ vi/02-git-basics/01-chapter2.markdown | 1171 +++++++++++++++++ vi/03-git-branching/01-chapter3.markdown | 598 +++++++++ vi/04-git-server/01-chapter4.markdown | 859 ++++++++++++ vi/05-distributed-git/01-chapter5.markdown | 897 +++++++++++++ vi/06-git-tools/01-chapter6.markdown | 1126 ++++++++++++++++ vi/07-customizing-git/01-chapter7.markdown | 938 +++++++++++++ vi/08-git-and-other-scms/01-chapter8.markdown | 689 ++++++++++ vi/09-git-internals/01-chapter9.markdown | 977 ++++++++++++++ 9 files changed, 7514 insertions(+) create mode 100644 vi/01-introduction/01-chapter1.markdown create mode 100644 vi/02-git-basics/01-chapter2.markdown create mode 100644 vi/03-git-branching/01-chapter3.markdown create mode 100644 vi/04-git-server/01-chapter4.markdown create mode 100644 vi/05-distributed-git/01-chapter5.markdown create mode 100644 vi/06-git-tools/01-chapter6.markdown create mode 100644 vi/07-customizing-git/01-chapter7.markdown create mode 100644 vi/08-git-and-other-scms/01-chapter8.markdown create mode 100644 vi/09-git-internals/01-chapter9.markdown diff --git a/vi/01-introduction/01-chapter1.markdown b/vi/01-introduction/01-chapter1.markdown new file mode 100644 index 000000000..c7f12a2ed --- /dev/null +++ b/vi/01-introduction/01-chapter1.markdown @@ -0,0 +1,259 @@ +# Getting Started # + +This chapter will be about getting started with Git. We will begin at the beginning by explaining some background on version control tools, then move on to how to get Git running on your system and finally how to get it setup to start working with. At the end of this chapter you should understand why Git is around, why you should use it and you should be all setup to do so. + +## About Version Control ## + +What is version control, and why should you care? Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later. Even though the examples in this book show software source code as the files under version control, in reality any type of file on a computer can be placed under version control. + +If you are a graphic or web designer and want to keep every version of an image or layout (which you certainly would), it is very wise to use a Version Control System (VCS). A VCS allows you to: revert files back to a previous state, revert the entire project back to a previous state, review changes made over time, see who last modified something that might be causing a problem, who introduced an issue and when, and more. Using a VCS also means that if you screw things up or lose files, you can generally recover easily. In addition, you get all this for very little overhead. + +### Local Version Control Systems ### + +Many people’s version-control method of choice is to copy files into another directory (perhaps a time-stamped directory, if they’re clever). This approach is very common because it is so simple, but it is also incredibly error prone. It is easy to forget which directory you’re in and accidentally write to the wrong file or copy over files you don’t mean to. + +To deal with this issue, programmers long ago developed local VCSs that had a simple database that kept all the changes to files under revision control (see Figure 1-1). + +Insert 18333fig0101.png +Figure 1-1. Local version control diagram. + +One of the more popular VCS tools was a system called rcs, which is still distributed with many computers today. Even the popular Mac OS X operating system includes the rcs command when you install the Developer Tools. This tool basically works by keeping patch sets (that is, the differences between files) from one revision to another in a special format on disk; it can then recreate what any file looked like at any point in time by adding up all the patches. + +### Centralized Version Control Systems ### + +The next major issue that people encounter is that they need to collaborate with developers on other systems. To deal with this problem, Centralized Version Control Systems (CVCSs) were developed. These systems, such as CVS, Subversion, and Perforce, have a single server that contains all the versioned files, and a number of clients that check out files from that central place. For many years, this has been the standard for version control (see Figure 1-2). + +Insert 18333fig0102.png +Figure 1-2. Centralized version control diagram. + +This setup offers many advantages, especially over local VCSs. For example, everyone knows to a certain degree what everyone else on the project is doing. Administrators have fine-grained control over who can do what; and it’s far easier to administer a CVCS than it is to deal with local databases on every client. + +However, this setup also has some serious downsides. The most obvious is the single point of failure that the centralized server represents. If that server goes down for an hour, then during that hour nobody can collaborate at all or save versioned changes to anything they’re working on. If the hard disk the central database is on becomes corrupted, and proper backups haven’t been kept, you lose absolutely everything—the entire history of the project except whatever single snapshots people happen to have on their local machines. Local VCS systems suffer from this same problem—whenever you have the entire history of the project in a single place, you risk losing everything. + +### Distributed Version Control Systems ### + +This is where Distributed Version Control Systems (DVCSs) step in. In a DVCS (such as Git, Mercurial, Bazaar or Darcs), clients don’t just check out the latest snapshot of the files: they fully mirror the repository. Thus if any server dies, and these systems were collaborating via it, any of the client repositories can be copied back up to the server to restore it. Every checkout is really a full backup of all the data (see Figure 1-3). + +Insert 18333fig0103.png +Figure 1-3. Distributed version control diagram. + +Furthermore, many of these systems deal pretty well with having several remote repositories they can work with, so you can collaborate with different groups of people in different ways simultaneously within the same project. This allows you to set up several types of workflows that aren’t possible in centralized systems, such as hierarchical models. + +## A Short History of Git ## + +As with many great things in life, Git began with a bit of creative destruction and fiery controversy. The Linux kernel is an open source software project of fairly large scope. For most of the lifetime of the Linux kernel maintenance (1991–2002), changes to the software were passed around as patches and archived files. In 2002, the Linux kernel project began using a proprietary DVCS system called BitKeeper. + +In 2005, the relationship between the community that developed the Linux kernel and the commercial company that developed BitKeeper broke down, and the tool’s free-of-charge status was revoked. This prompted the Linux development community (and in particular Linus Torvalds, the creator of Linux) to develop their own tool based on some of the lessons they learned while using BitKeeper. Some of the goals of the new system were as follows: + +* Speed +* Simple design +* Strong support for non-linear development (thousands of parallel branches) +* Fully distributed +* Able to handle large projects like the Linux kernel efficiently (speed and data size) + +Since its birth in 2005, Git has evolved and matured to be easy to use and yet retain these initial qualities. It’s incredibly fast, it’s very efficient with large projects, and it has an incredible branching system for non-linear development (See Chapter 3). + +## Git Basics ## + +So, what is Git in a nutshell? This is an important section to absorb, because if you understand what Git is and the fundamentals of how it works, then using Git effectively will probably be much easier for you. As you learn Git, try to clear your mind of the things you may know about other VCSs, such as Subversion and Perforce; doing so will help you avoid subtle confusion when using the tool. Git stores and thinks about information much differently than these other systems, even though the user interface is fairly similar; understanding those differences will help prevent you from becoming confused while using it. + +### Snapshots, Not Differences ### + +The major difference between Git and any other VCS (Subversion and friends included) is the way Git thinks about its data. Conceptually, most other systems store information as a list of file-based changes. These systems (CVS, Subversion, Perforce, Bazaar, and so on) think of the information they keep as a set of files and the changes made to each file over time, as illustrated in Figure 1-4. + +Insert 18333fig0104.png +Figure 1-4. Other systems tend to store data as changes to a base version of each file. + +Git doesn’t think of or store its data this way. Instead, Git thinks of its data more like a set of snapshots of a mini filesystem. Every time you commit, or save the state of your project in Git, it basically takes a picture of what all your files look like at that moment and stores a reference to that snapshot. To be efficient, if files have not changed, Git doesn’t store the file again—just a link to the previous identical file it has already stored. Git thinks about its data more like Figure 1-5. + +Insert 18333fig0105.png +Figure 1-5. Git stores data as snapshots of the project over time. + +This is an important distinction between Git and nearly all other VCSs. It makes Git reconsider almost every aspect of version control that most other systems copied from the previous generation. This makes Git more like a mini filesystem with some incredibly powerful tools built on top of it, rather than simply a VCS. We’ll explore some of the benefits you gain by thinking of your data this way when we cover Git branching in Chapter 3. + +### Nearly Every Operation Is Local ### + +Most operations in Git only need local files and resources to operate — generally no information is needed from another computer on your network. If you’re used to a CVCS where most operations have that network latency overhead, this aspect of Git will make you think that the gods of speed have blessed Git with unworldly powers. Because you have the entire history of the project right there on your local disk, most operations seem almost instantaneous. + +For example, to browse the history of the project, Git doesn’t need to go out to the server to get the history and display it for you—it simply reads it directly from your local database. This means you see the project history almost instantly. If you want to see the changes introduced between the current version of a file and the file a month ago, Git can look up the file a month ago and do a local difference calculation, instead of having to either ask a remote server to do it or pull an older version of the file from the remote server to do it locally. + +This also means that there is very little you can’t do if you’re offline or off VPN. If you get on an airplane or a train and want to do a little work, you can commit happily until you get to a network connection to upload. If you go home and can’t get your VPN client working properly, you can still work. In many other systems, doing so is either impossible or painful. In Perforce, for example, you can’t do much when you aren’t connected to the server; and in Subversion and CVS, you can edit files, but you can’t commit changes to your database (because your database is offline). This may not seem like a huge deal, but you may be surprised what a big difference it can make. + +### Git Has Integrity ### + +Everything in Git is check-summed before it is stored and is then referred to by that checksum. This means it’s impossible to change the contents of any file or directory without Git knowing about it. This functionality is built into Git at the lowest levels and is integral to its philosophy. You can’t lose information in transit or get file corruption without Git being able to detect it. + +The mechanism that Git uses for this checksumming is called a SHA-1 hash. This is a 40-character string composed of hexadecimal characters (0–9 and a–f) and calculated based on the contents of a file or directory structure in Git. A SHA-1 hash looks something like this: + + 24b9da6552252987aa493b52f8696cd6d3b00373 + +You will see these hash values all over the place in Git because it uses them so much. In fact, Git stores everything not by file name but in the Git database addressable by the hash value of its contents. + +### Git Generally Only Adds Data ### + +When you do actions in Git, nearly all of them only add data to the Git database. It is very difficult to get the system to do anything that is not undoable or to make it erase data in any way. As in any VCS, you can lose or mess up changes you haven’t committed yet; but after you commit a snapshot into Git, it is very difficult to lose, especially if you regularly push your database to another repository. + +This makes using Git a joy because we know we can experiment without the danger of severely screwing things up. For a more in-depth look at how Git stores its data and how you can recover data that seems lost, see Chapter 9. + +### The Three States ### + +Now, pay attention. This is the main thing to remember about Git if you want the rest of your learning process to go smoothly. Git has three main states that your files can reside in: committed, modified, and staged. Committed means that the data is safely stored in your local database. Modified means that you have changed the file but have not committed it to your database yet. Staged means that you have marked a modified file in its current version to go into your next commit snapshot. + +This leads us to the three main sections of a Git project: the Git directory, the working directory, and the staging area. + +Insert 18333fig0106.png +Figure 1-6. Working directory, staging area, and git directory. + +The Git directory is where Git stores the metadata and object database for your project. This is the most important part of Git, and it is what is copied when you clone a repository from another computer. + +The working directory is a single checkout of one version of the project. These files are pulled out of the compressed database in the Git directory and placed on disk for you to use or modify. + +The staging area is a simple file, generally contained in your Git directory, that stores information about what will go into your next commit. It’s sometimes referred to as the index, but it’s becoming standard to refer to it as the staging area. + +The basic Git workflow goes something like this: + +1. You modify files in your working directory. +2. You stage the files, adding snapshots of them to your staging area. +3. You do a commit, which takes the files as they are in the staging area and stores that snapshot permanently to your Git directory. + +If a particular version of a file is in the git directory, it’s considered committed. If it’s modified but has been added to the staging area, it is staged. And if it was changed since it was checked out but has not been staged, it is modified. In Chapter 2, you’ll learn more about these states and how you can either take advantage of them or skip the staged part entirely. + +## Installing Git ## + +Let’s get into using some Git. First things first—you have to install it. You can get it a number of ways; the two major ones are to install it from source or to install an existing package for your platform. + +### Installing from Source ### + +If you can, it’s generally useful to install Git from source, because you’ll get the most recent version. Each version of Git tends to include useful UI enhancements, so getting the latest version is often the best route if you feel comfortable compiling software from source. It is also the case that many Linux distributions contain very old packages; so unless you’re on a very up-to-date distro or are using backports, installing from source may be the best bet. + +To install Git, you need to have the following libraries that Git depends on: curl, zlib, openssl, expat, and libiconv. For example, if you’re on a system that has yum (such as Fedora) or apt-get (such as a Debian based system), you can use one of these commands to install all of the dependencies: + + $ yum install curl-devel expat-devel gettext-devel \ + openssl-devel zlib-devel + + $ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \ + libz-dev libssl-dev + +When you have all the necessary dependencies, you can go ahead and grab the latest snapshot from the Git web site: + + http://git-scm.com/download + +Then, compile and install: + + $ tar -zxf git-1.7.2.2.tar.gz + $ cd git-1.7.2.2 + $ make prefix=/usr/local all + $ sudo make prefix=/usr/local install + +After this is done, you can also get Git via Git itself for updates: + + $ git clone git://git.kernel.org/pub/scm/git/git.git + +### Installing on Linux ### + +If you want to install Git on Linux via a binary installer, you can generally do so through the basic package-management tool that comes with your distribution. If you’re on Fedora, you can use yum: + + $ yum install git-core + +Or if you’re on a Debian-based distribution like Ubuntu, try apt-get: + + $ apt-get install git + +### Installing on Mac ### + +There are two easy ways to install Git on a Mac. The easiest is to use the graphical Git installer, which you can download from the Google Code page (see Figure 1-7): + + http://code.google.com/p/git-osx-installer + +Insert 18333fig0107.png +Figure 1-7. Git OS X installer. + +The other major way is to install Git via MacPorts (`http://www.macports.org`). If you have MacPorts installed, install Git via + + $ sudo port install git-core +svn +doc +bash_completion +gitweb + +You don’t have to add all the extras, but you’ll probably want to include +svn in case you ever have to use Git with Subversion repositories (see Chapter 8). + +### Installing on Windows ### + +Installing Git on Windows is very easy. The msysGit project has one of the easier installation procedures. Simply download the installer exe file from the GitHub page, and run it: + + http://msysgit.github.com/ + +After it’s installed, you have both a command-line version (including an SSH client that will come in handy later) and the standard GUI. + +Note on Windows usage: you should use Git with the provided msysGit shell (Unix style), it allows to use the complex lines of command given in this book. If you need, for some reason, to use the native Windows shell / command line console, you have to use double quotes instead of simple quotes (for parameters with spaces in them) and you must quote the parameters ending with the circumflex accent (^) if they are last on the line, as it is a continuation symbol in Windows. + +## First-Time Git Setup ## + +Now that you have Git on your system, you’ll want to do a few things to customize your Git environment. You should have to do these things only once; they’ll stick around between upgrades. You can also change them at any time by running through the commands again. + +Git comes with a tool called git config that lets you get and set configuration variables that control all aspects of how Git looks and operates. These variables can be stored in three different places: + +* `/etc/gitconfig` file: Contains values for every user on the system and all their repositories. If you pass the option` --system` to `git config`, it reads and writes from this file specifically. +* `~/.gitconfig` file: Specific to your user. You can make Git read and write to this file specifically by passing the `--global` option. +* config file in the git directory (that is, `.git/config`) of whatever repository you’re currently using: Specific to that single repository. Each level overrides values in the previous level, so values in `.git/config` trump those in `/etc/gitconfig`. + +On Windows systems, Git looks for the `.gitconfig` file in the `$HOME` directory (`%USERPROFILE%` in Windows’ environment), which is `C:\Documents and Settings\$USER` or `C:\Users\$USER` for most people, depending on version (`$USER` is `%USERNAME%` in Windows’ environment). It also still looks for /etc/gitconfig, although it’s relative to the MSys root, which is wherever you decide to install Git on your Windows system when you run the installer. + +### Your Identity ### + +The first thing you should do when you install Git is to set your user name and e-mail address. This is important because every Git commit uses this information, and it’s immutably baked into the commits you pass around: + + $ git config --global user.name "John Doe" + $ git config --global user.email johndoe@example.com + +Again, you need to do this only once if you pass the `--global` option, because then Git will always use that information for anything you do on that system. If you want to override this with a different name or e-mail address for specific projects, you can run the command without the `--global` option when you’re in that project. + +### Your Editor ### + +Now that your identity is set up, you can configure the default text editor that will be used when Git needs you to type in a message. By default, Git uses your system’s default editor, which is generally Vi or Vim. If you want to use a different text editor, such as Emacs, you can do the following: + + $ git config --global core.editor emacs + +### Your Diff Tool ### + +Another useful option you may want to configure is the default diff tool to use to resolve merge conflicts. Say you want to use vimdiff: + + $ git config --global merge.tool vimdiff + +Git accepts kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge, and opendiff as valid merge tools. You can also set up a custom tool; see Chapter 7 for more information about doing that. + +### Checking Your Settings ### + +If you want to check your settings, you can use the `git config --list` command to list all the settings Git can find at that point: + + $ git config --list + user.name=Scott Chacon + user.email=schacon@gmail.com + color.status=auto + color.branch=auto + color.interactive=auto + color.diff=auto + ... + +You may see keys more than once, because Git reads the same key from different files (`/etc/gitconfig` and `~/.gitconfig`, for example). In this case, Git uses the last value for each unique key it sees. + +You can also check what Git thinks a specific key’s value is by typing `git config {key}`: + + $ git config user.name + Scott Chacon + +## Getting Help ## + +If you ever need help while using Git, there are three ways to get the manual page (manpage) help for any of the Git commands: + + $ git help + $ git --help + $ man git- + +For example, you can get the manpage help for the config command by running + + $ git help config + +These commands are nice because you can access them anywhere, even offline. +If the manpages and this book aren’t enough and you need in-person help, you can try the `#git` or `#github` channel on the Freenode IRC server (irc.freenode.net). These channels are regularly filled with hundreds of people who are all very knowledgeable about Git and are often willing to help. + +## Summary ## + +You should have a basic understanding of what Git is and how it’s different from the CVCS you may have been using. You should also now have a working version of Git on your system that’s set up with your personal identity. It’s now time to learn some Git basics. diff --git a/vi/02-git-basics/01-chapter2.markdown b/vi/02-git-basics/01-chapter2.markdown new file mode 100644 index 000000000..bbf48f64d --- /dev/null +++ b/vi/02-git-basics/01-chapter2.markdown @@ -0,0 +1,1171 @@ +# Git Basics # + +If you can read only one chapter to get going with Git, this is it. This chapter covers every basic command you need to do the vast majority of the things you’ll eventually spend your time doing with Git. By the end of the chapter, you should be able to configure and initialize a repository, begin and stop tracking files, and stage and commit changes. We’ll also show you how to set up Git to ignore certain files and file patterns, how to undo mistakes quickly and easily, how to browse the history of your project and view changes between commits, and how to push and pull from remote repositories. + +## Getting a Git Repository ## + +You can get a Git project using two main approaches. The first takes an existing project or directory and imports it into Git. The second clones an existing Git repository from another server. + +### Initializing a Repository in an Existing Directory ### + +If you’re starting to track an existing project in Git, you need to go to the project’s directory and type + + $ git init + +This creates a new subdirectory named `.git` that contains all of your necessary repository files — a Git repository skeleton. At this point, nothing in your project is tracked yet. (See *Chapter 9* for more information about exactly what files are contained in the `.git` directory you just created.) + +If you want to start version-controlling existing files (as opposed to an empty directory), you should probably begin tracking those files and do an initial commit. You can accomplish that with a few `git add` commands that specify the files you want to track, followed by a commit: + + $ git add *.c + $ git add README + $ git commit -m 'initial project version' + +We’ll go over what these commands do in just a minute. At this point, you have a Git repository with tracked files and an initial commit. + +### Cloning an Existing Repository ### + +If you want to get a copy of an existing Git repository — for example, a project you’d like to contribute to — the command you need is `git clone`. If you’re familiar with other VCS systems such as Subversion, you’ll notice that the command is `clone` and not `checkout`. This is an important distinction — Git receives a copy of nearly all data that the server has. Every version of every file for the history of the project is pulled down when you run `git clone`. In fact, if your server disk gets corrupted, you can use any of the clones on any client to set the server back to the state it was in when it was cloned (you may lose some server-side hooks and such, but all the versioned data would be there — see *Chapter 4* for more details). + +You clone a repository with `git clone [url]`. For example, if you want to clone the Ruby Git library called Grit, you can do so like this: + + $ git clone git://github.com/schacon/grit.git + +That creates a directory named `grit`, initializes a `.git` directory inside it, pulls down all the data for that repository, and checks out a working copy of the latest version. If you go into the new `grit` directory, you’ll see the project files in there, ready to be worked on or used. If you want to clone the repository into a directory named something other than grit, you can specify that as the next command-line option: + + $ git clone git://github.com/schacon/grit.git mygrit + +That command does the same thing as the previous one, but the target directory is called `mygrit`. + +Git has a number of different transfer protocols you can use. The previous example uses the `git://` protocol, but you may also see `http(s)://` or `user@server:/path.git`, which uses the SSH transfer protocol. *Chapter 4* will introduce all of the available options the server can set up to access your Git repository and the pros and cons of each. + +## Recording Changes to the Repository ## + +You have a bona fide Git repository and a checkout or working copy of the files for that project. You need to make some changes and commit snapshots of those changes into your repository each time the project reaches a state you want to record. + +Remember that each file in your working directory can be in one of two states: *tracked* or *untracked*. *Tracked* files are files that were in the last snapshot; they can be *unmodified*, *modified*, or *staged*. *Untracked* files are everything else — any files in your working directory that were not in your last snapshot and are not in your staging area. When you first clone a repository, all of your files will be tracked and unmodified because you just checked them out and haven’t edited anything. + +As you edit files, Git sees them as modified, because you’ve changed them since your last commit. You *stage* these modified files and then commit all your staged changes, and the cycle repeats. This lifecycle is illustrated in Figure 2-1. + +Insert 18333fig0201.png +Figure 2-1. The lifecycle of the status of your files. + +### Checking the Status of Your Files ### + +The main tool you use to determine which files are in which state is the `git status` command. If you run this command directly after a clone, you should see something like this: + + $ git status + # On branch master + nothing to commit (working directory clean) + +This means you have a clean working directory — in other words, no tracked files are modified. Git also doesn’t see any untracked files, or they would be listed here. Finally, the command tells you which branch you’re on. For now, that is always `master`, which is the default; you won’t worry about it here. The next chapter will go over branches and references in detail. + +Let’s say you add a new file to your project, a simple `README` file. If the file didn’t exist before, and you run `git status`, you see your untracked file like so: + + $ vim README + $ git status + # On branch master + # Untracked files: + # (use "git add ..." to include in what will be committed) + # + # README + nothing added to commit but untracked files present (use "git add" to track) + +You can see that your new `README` file is untracked, because it’s under the “Untracked files” heading in your status output. Untracked basically means that Git sees a file you didn’t have in the previous snapshot (commit); Git won’t start including it in your commit snapshots until you explicitly tell it to do so. It does this so you don’t accidentally begin including generated binary files or other files that you did not mean to include. You do want to start including README, so let’s start tracking the file. + +### Tracking New Files ### + +In order to begin tracking a new file, you use the command `git add`. To begin tracking the `README` file, you can run this: + + $ git add README + +If you run your status command again, you can see that your `README` file is now tracked and staged: + + $ git status + # On branch master + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # new file: README + # + +You can tell that it’s staged because it’s under the “Changes to be committed” heading. If you commit at this point, the version of the file at the time you ran `git add` is what will be in the historical snapshot. You may recall that when you ran `git init` earlier, you then ran `git add (files)` — that was to begin tracking files in your directory. The `git add` command takes a path name for either a file or a directory; if it’s a directory, the command adds all the files in that directory recursively. + +### Staging Modified Files ### + +Let’s change a file that was already tracked. If you change a previously tracked file called `benchmarks.rb` and then run your `status` command again, you get something that looks like this: + + $ git status + # On branch master + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # new file: README + # + # Changes not staged for commit: + # (use "git add ..." to update what will be committed) + # + # modified: benchmarks.rb + # + +The `benchmarks.rb` file appears under a section named “Changes not staged for commit” — which means that a file that is tracked has been modified in the working directory but not yet staged. To stage it, you run the `git add` command (it’s a multipurpose command — you use it to begin tracking new files, to stage files, and to do other things like marking merge-conflicted files as resolved). Let’s run `git add` now to stage the `benchmarks.rb` file, and then run `git status` again: + + $ git add benchmarks.rb + $ git status + # On branch master + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # new file: README + # modified: benchmarks.rb + # + +Both files are staged and will go into your next commit. At this point, suppose you remember one little change that you want to make in `benchmarks.rb` before you commit it. You open it again and make that change, and you’re ready to commit. However, let’s run `git status` one more time: + + $ vim benchmarks.rb + $ git status + # On branch master + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # new file: README + # modified: benchmarks.rb + # + # Changes not staged for commit: + # (use "git add ..." to update what will be committed) + # + # modified: benchmarks.rb + # + +What the heck? Now `benchmarks.rb` is listed as both staged and unstaged. How is that possible? It turns out that Git stages a file exactly as it is when you run the `git add` command. If you commit now, the version of `benchmarks.rb` as it was when you last ran the `git add` command is how it will go into the commit, not the version of the file as it looks in your working directory when you run `git commit`. If you modify a file after you run `git add`, you have to run `git add` again to stage the latest version of the file: + + $ git add benchmarks.rb + $ git status + # On branch master + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # new file: README + # modified: benchmarks.rb + # + +### Ignoring Files ### + +Often, you’ll have a class of files that you don’t want Git to automatically add or even show you as being untracked. These are generally automatically generated files such as log files or files produced by your build system. In such cases, you can create a file listing patterns to match them named `.gitignore`. Here is an example `.gitignore` file: + + $ cat .gitignore + *.[oa] + *~ + +The first line tells Git to ignore any files ending in `.o` or `.a` — *object* and *archive* files that may be the product of building your code. The second line tells Git to ignore all files that end with a tilde (`~`), which is used by many text editors such as Emacs to mark temporary files. You may also include a `log`, `tmp`, or `pid` directory; automatically generated documentation; and so on. Setting up a `.gitignore` file before you get going is generally a good idea so you don’t accidentally commit files that you really don’t want in your Git repository. + +The rules for the patterns you can put in the `.gitignore` file are as follows: + +* Blank lines or lines starting with `#` are ignored. +* Standard glob patterns work. +* You can end patterns with a forward slash (`/`) to specify a directory. +* You can negate a pattern by starting it with an exclamation point (`!`). + +Glob patterns are like simplified regular expressions that shells use. An asterisk (`*`) matches zero or more characters; `[abc]` matches any character inside the brackets (in this case `a`, `b`, or `c`); a question mark (`?`) matches a single character; and brackets enclosing characters separated by a hyphen(`[0-9]`) matches any character in the range (in this case 0 through 9) . + +Here is another example `.gitignore` file: + + # a comment - this is ignored + # no .a files + *.a + # but do track lib.a, even though you're ignoring .a files above + !lib.a + # only ignore the root TODO file, not subdir/TODO + /TODO + # ignore all files in the build/ directory + build/ + # ignore doc/notes.txt, but not doc/server/arch.txt + doc/*.txt + # ignore all .txt files in the doc/ directory + doc/**/*.txt + +A `**/` pattern is available in Git since version 1.8.2. + +### Viewing Your Staged and Unstaged Changes ### + +If the `git status` command is too vague for you — you want to know exactly what you changed, not just which files were changed — you can use the `git diff` command. We’ll cover `git diff` in more detail later; but you’ll probably use it most often to answer these two questions: What have you changed but not yet staged? And what have you staged that you are about to commit? Although `git status` answers those questions very generally, `git diff` shows you the exact lines added and removed — the patch, as it were. + +Let’s say you edit and stage the `README` file again and then edit the `benchmarks.rb` file without staging it. If you run your `status` command, you once again see something like this: + + $ git status + # On branch master + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # new file: README + # + # Changes not staged for commit: + # (use "git add ..." to update what will be committed) + # + # modified: benchmarks.rb + # + +To see what you’ve changed but not yet staged, type `git diff` with no other arguments: + + $ git diff + diff --git a/benchmarks.rb b/benchmarks.rb + index 3cb747f..da65585 100644 + --- a/benchmarks.rb + +++ b/benchmarks.rb + @@ -36,6 +36,10 @@ def main + @commit.parents[0].parents[0].parents[0] + end + + + run_code(x, 'commits 1') do + + git.commits.size + + end + + + run_code(x, 'commits 2') do + log = git.commits('master', 15) + log.size + +That command compares what is in your working directory with what is in your staging area. The result tells you the changes you’ve made that you haven’t yet staged. + +If you want to see what you’ve staged that will go into your next commit, you can use `git diff --cached`. (In Git versions 1.6.1 and later, you can also use `git diff --staged`, which may be easier to remember.) This command compares your staged changes to your last commit: + + $ git diff --cached + diff --git a/README b/README + new file mode 100644 + index 0000000..03902a1 + --- /dev/null + +++ b/README2 + @@ -0,0 +1,5 @@ + +grit + + by Tom Preston-Werner, Chris Wanstrath + + http://github.com/mojombo/grit + + + +Grit is a Ruby library for extracting information from a Git repository + +It’s important to note that `git diff` by itself doesn’t show all changes made since your last commit — only changes that are still unstaged. This can be confusing, because if you’ve staged all of your changes, `git diff` will give you no output. + +For another example, if you stage the `benchmarks.rb` file and then edit it, you can use `git diff` to see the changes in the file that are staged and the changes that are unstaged: + + $ git add benchmarks.rb + $ echo '# test line' >> benchmarks.rb + $ git status + # On branch master + # + # Changes to be committed: + # + # modified: benchmarks.rb + # + # Changes not staged for commit: + # + # modified: benchmarks.rb + # + +Now you can use `git diff` to see what is still unstaged + + $ git diff + diff --git a/benchmarks.rb b/benchmarks.rb + index e445e28..86b2f7c 100644 + --- a/benchmarks.rb + +++ b/benchmarks.rb + @@ -127,3 +127,4 @@ end + main() + + ##pp Grit::GitRuby.cache_client.stats + +# test line + +and `git diff --cached` to see what you’ve staged so far: + + $ git diff --cached + diff --git a/benchmarks.rb b/benchmarks.rb + index 3cb747f..e445e28 100644 + --- a/benchmarks.rb + +++ b/benchmarks.rb + @@ -36,6 +36,10 @@ def main + @commit.parents[0].parents[0].parents[0] + end + + + run_code(x, 'commits 1') do + + git.commits.size + + end + + + run_code(x, 'commits 2') do + log = git.commits('master', 15) + log.size + +### Committing Your Changes ### + +Now that your staging area is set up the way you want it, you can commit your changes. Remember that anything that is still unstaged — any files you have created or modified that you haven’t run `git add` on since you edited them — won’t go into this commit. They will stay as modified files on your disk. +In this case, the last time you ran `git status`, you saw that everything was staged, so you’re ready to commit your changes. The simplest way to commit is to type `git commit`: + + $ git commit + +Doing so launches your editor of choice. (This is set by your shell’s `$EDITOR` environment variable — usually vim or emacs, although you can configure it with whatever you want using the `git config --global core.editor` command as you saw in *Chapter 1*). + +The editor displays the following text (this example is a Vim screen): + + # Please enter the commit message for your changes. Lines starting + # with '#' will be ignored, and an empty message aborts the commit. + # On branch master + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # new file: README + # modified: benchmarks.rb + ~ + ~ + ~ + ".git/COMMIT_EDITMSG" 10L, 283C + +You can see that the default commit message contains the latest output of the `git status` command commented out and one empty line on top. You can remove these comments and type your commit message, or you can leave them there to help you remember what you’re committing. (For an even more explicit reminder of what you’ve modified, you can pass the `-v` option to `git commit`. Doing so also puts the diff of your change in the editor so you can see exactly what you did.) When you exit the editor, Git creates your commit with that commit message (with the comments and diff stripped out). + +Alternatively, you can type your commit message inline with the `commit` command by specifying it after a `-m` flag, like this: + + $ git commit -m "Story 182: Fix benchmarks for speed" + [master]: created 463dc4f: "Fix benchmarks for speed" + 2 files changed, 3 insertions(+), 0 deletions(-) + create mode 100644 README + +Now you’ve created your first commit! You can see that the commit has given you some output about itself: which branch you committed to (`master`), what SHA-1 checksum the commit has (`463dc4f`), how many files were changed, and statistics about lines added and removed in the commit. + +Remember that the commit records the snapshot you set up in your staging area. Anything you didn’t stage is still sitting there modified; you can do another commit to add it to your history. Every time you perform a commit, you’re recording a snapshot of your project that you can revert to or compare to later. + +### Skipping the Staging Area ### + +Although it can be amazingly useful for crafting commits exactly how you want them, the staging area is sometimes a bit more complex than you need in your workflow. If you want to skip the staging area, Git provides a simple shortcut. Providing the `-a` option to the `git commit` command makes Git automatically stage every file that is already tracked before doing the commit, letting you skip the `git add` part: + + $ git status + # On branch master + # + # Changes not staged for commit: + # + # modified: benchmarks.rb + # + $ git commit -a -m 'added new benchmarks' + [master 83e38c7] added new benchmarks + 1 files changed, 5 insertions(+), 0 deletions(-) + +Notice how you don’t have to run `git add` on the `benchmarks.rb` file in this case before you commit. + +### Removing Files ### + +To remove a file from Git, you have to remove it from your tracked files (more accurately, remove it from your staging area) and then commit. The `git rm` command does that and also removes the file from your working directory so you don’t see it as an untracked file next time around. + +If you simply remove the file from your working directory, it shows up under the “Changes not staged for commit” (that is, _unstaged_) area of your `git status` output: + + $ rm grit.gemspec + $ git status + # On branch master + # + # Changes not staged for commit: + # (use "git add/rm ..." to update what will be committed) + # + # deleted: grit.gemspec + # + +Then, if you run `git rm`, it stages the file’s removal: + + $ git rm grit.gemspec + rm 'grit.gemspec' + $ git status + # On branch master + # + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # deleted: grit.gemspec + # + +The next time you commit, the file will be gone and no longer tracked. If you modified the file and added it to the index already, you must force the removal with the `-f` option. This is a safety feature to prevent accidental removal of data that hasn’t yet been recorded in a snapshot and that can’t be recovered from Git. + +Another useful thing you may want to do is to keep the file in your working tree but remove it from your staging area. In other words, you may want to keep the file on your hard drive but not have Git track it anymore. This is particularly useful if you forgot to add something to your `.gitignore` file and accidentally staged it, like a large log file or a bunch of `.a` compiled files. To do this, use the `--cached` option: + + $ git rm --cached readme.txt + +You can pass files, directories, and file-glob patterns to the `git rm` command. That means you can do things such as + + $ git rm log/\*.log + +Note the backslash (`\`) in front of the `*`. This is necessary because Git does its own filename expansion in addition to your shell’s filename expansion. On Windows with the system console, the backslash must be omitted. This command removes all files that have the `.log` extension in the `log/` directory. Or, you can do something like this: + + $ git rm \*~ + +This command removes all files that end with `~`. + +### Moving Files ### + +Unlike many other VCS systems, Git doesn’t explicitly track file movement. If you rename a file in Git, no metadata is stored in Git that tells it you renamed the file. However, Git is pretty smart about figuring that out after the fact — we’ll deal with detecting file movement a bit later. + +Thus it’s a bit confusing that Git has a `mv` command. If you want to rename a file in Git, you can run something like + + $ git mv file_from file_to + +and it works fine. In fact, if you run something like this and look at the status, you’ll see that Git considers it a renamed file: + + $ git mv README.txt README + $ git status + # On branch master + # Your branch is ahead of 'origin/master' by 1 commit. + # + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # renamed: README.txt -> README + # + +However, this is equivalent to running something like this: + + $ mv README.txt README + $ git rm README.txt + $ git add README + +Git figures out that it’s a rename implicitly, so it doesn’t matter if you rename a file that way or with the `mv` command. The only real difference is that `mv` is one command instead of three — it’s a convenience function. More important, you can use any tool you like to rename a file, and address the add/rm later, before you commit. + +## Viewing the Commit History ## + +After you have created several commits, or if you have cloned a repository with an existing commit history, you’ll probably want to look back to see what has happened. The most basic and powerful tool to do this is the `git log` command. + +These examples use a very simple project called `simplegit` that I often use for demonstrations. To get the project, run + + git clone git://github.com/schacon/simplegit-progit.git + +When you run `git log` in this project, you should get output that looks something like this: + + $ git log + commit ca82a6dff817ec66f44342007202690a93763949 + Author: Scott Chacon + Date: Mon Mar 17 21:52:11 2008 -0700 + + changed the version number + + commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 + Author: Scott Chacon + Date: Sat Mar 15 16:40:33 2008 -0700 + + removed unnecessary test code + + commit a11bef06a3f659402fe7563abf99ad00de2209e6 + Author: Scott Chacon + Date: Sat Mar 15 10:31:28 2008 -0700 + + first commit + +By default, with no arguments, `git log` lists the commits made in that repository in reverse chronological order. That is, the most recent commits show up first. As you can see, this command lists each commit with its SHA-1 checksum, the author’s name and e-mail, the date written, and the commit message. + +A huge number and variety of options to the `git log` command are available to show you exactly what you’re looking for. Here, we’ll show you some of the most-used options. + +One of the more helpful options is `-p`, which shows the diff introduced in each commit. You can also use `-2`, which limits the output to only the last two entries: + + $ git log -p -2 + commit ca82a6dff817ec66f44342007202690a93763949 + Author: Scott Chacon + Date: Mon Mar 17 21:52:11 2008 -0700 + + changed the version number + + diff --git a/Rakefile b/Rakefile + index a874b73..8f94139 100644 + --- a/Rakefile + +++ b/Rakefile + @@ -5,5 +5,5 @@ require 'rake/gempackagetask' + spec = Gem::Specification.new do |s| + s.name = "simplegit" + - s.version = "0.1.0" + + s.version = "0.1.1" + s.author = "Scott Chacon" + s.email = "schacon@gee-mail.com + + commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 + Author: Scott Chacon + Date: Sat Mar 15 16:40:33 2008 -0700 + + removed unnecessary test code + + diff --git a/lib/simplegit.rb b/lib/simplegit.rb + index a0a60ae..47c6340 100644 + --- a/lib/simplegit.rb + +++ b/lib/simplegit.rb + @@ -18,8 +18,3 @@ class SimpleGit + end + + end + - + -if $0 == __FILE__ + - git = SimpleGit.new + - puts git.show + -end + \ No newline at end of file + +This option displays the same information but with a diff directly following each entry. This is very helpful for code review or to quickly browse what happened during a series of commits that a collaborator has added. + +Sometimes it's easier to review changes on the word level rather than on the line level. There is a `--word-diff` option available in Git, that you can append to the `git log -p` command to get word diff instead of normal line by line diff. Word diff format is quite useless when applied to source code, but it comes in handy when applied to large text files, like books or your dissertation. Here is an example: + + $ git log -U1 --word-diff + commit ca82a6dff817ec66f44342007202690a93763949 + Author: Scott Chacon + Date: Mon Mar 17 21:52:11 2008 -0700 + + changed the version number + + diff --git a/Rakefile b/Rakefile + index a874b73..8f94139 100644 + --- a/Rakefile + +++ b/Rakefile + @@ -7,3 +7,3 @@ spec = Gem::Specification.new do |s| + s.name = "simplegit" + s.version = [-"0.1.0"-]{+"0.1.1"+} + s.author = "Scott Chacon" + +As you can see, there is no added and removed lines in this output as in a normal diff. Changes are shown inline instead. You can see the added word enclosed in `{+ +}` and removed one enclosed in `[- -]`. You may also want to reduce the usual three lines context in diff output to only one line, as the context is now words, not lines. You can do this with `-U1` as we did in the example above. + +You can also use a series of summarizing options with `git log`. For example, if you want to see some abbreviated stats for each commit, you can use the `--stat` option: + + $ git log --stat + commit ca82a6dff817ec66f44342007202690a93763949 + Author: Scott Chacon + Date: Mon Mar 17 21:52:11 2008 -0700 + + changed the version number + + Rakefile | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + + commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 + Author: Scott Chacon + Date: Sat Mar 15 16:40:33 2008 -0700 + + removed unnecessary test code + + lib/simplegit.rb | 5 ----- + 1 files changed, 0 insertions(+), 5 deletions(-) + + commit a11bef06a3f659402fe7563abf99ad00de2209e6 + Author: Scott Chacon + Date: Sat Mar 15 10:31:28 2008 -0700 + + first commit + + README | 6 ++++++ + Rakefile | 23 +++++++++++++++++++++++ + lib/simplegit.rb | 25 +++++++++++++++++++++++++ + 3 files changed, 54 insertions(+), 0 deletions(-) + +As you can see, the `--stat` option prints below each commit entry a list of modified files, how many files were changed, and how many lines in those files were added and removed. It also puts a summary of the information at the end. +Another really useful option is `--pretty`. This option changes the log output to formats other than the default. A few prebuilt options are available for you to use. The `oneline` option prints each commit on a single line, which is useful if you’re looking at a lot of commits. In addition, the `short`, `full`, and `fuller` options show the output in roughly the same format but with less or more information, respectively: + + $ git log --pretty=oneline + ca82a6dff817ec66f44342007202690a93763949 changed the version number + 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code + a11bef06a3f659402fe7563abf99ad00de2209e6 first commit + +The most interesting option is `format`, which allows you to specify your own log output format. This is especially useful when you’re generating output for machine parsing — because you specify the format explicitly, you know it won’t change with updates to Git: + + $ git log --pretty=format:"%h - %an, %ar : %s" + ca82a6d - Scott Chacon, 11 months ago : changed the version number + 085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code + a11bef0 - Scott Chacon, 11 months ago : first commit + +Table 2-1 lists some of the more useful options that format takes. + + + + Option Description of Output + %H Commit hash + %h Abbreviated commit hash + %T Tree hash + %t Abbreviated tree hash + %P Parent hashes + %p Abbreviated parent hashes + %an Author name + %ae Author e-mail + %ad Author date (format respects the --date= option) + %ar Author date, relative + %cn Committer name + %ce Committer email + %cd Committer date + %cr Committer date, relative + %s Subject + +You may be wondering what the difference is between _author_ and _committer_. The _author_ is the person who originally wrote the patch, whereas the _committer_ is the person who last applied the patch. So, if you send in a patch to a project and one of the core members applies the patch, both of you get credit — you as the author and the core member as the committer. We’ll cover this distinction a bit more in *Chapter 5*. + +The `oneline` and `format` options are particularly useful with another `log` option called `--graph`. This option adds a nice little ASCII graph showing your branch and merge history, which we can see in our copy of the Grit project repository: + + $ git log --pretty=format:"%h %s" --graph + * 2d3acf9 ignore errors from SIGCHLD on trap + * 5e3ee11 Merge branch 'master' of git://github.com/dustin/grit + |\ + | * 420eac9 Added a method for getting the current branch. + * | 30e367c timeout code and tests + * | 5a09431 add timeout protection to grit + * | e1193f8 support for heads with slashes in them + |/ + * d6016bc require time for xmlschema + * 11d191e Merge branch 'defunkt' into local + +Those are only some simple output-formatting options to `git log` — there are many more. Table 2-2 lists the options we’ve covered so far and some other common formatting options that may be useful, along with how they change the output of the `log` command. + + + + Option Description + -p Show the patch introduced with each commit. + --word-diff Show the patch in a word diff format. + --stat Show statistics for files modified in each commit. + --shortstat Display only the changed/insertions/deletions line from the --stat command. + --name-only Show the list of files modified after the commit information. + --name-status Show the list of files affected with added/modified/deleted information as well. + --abbrev-commit Show only the first few characters of the SHA-1 checksum instead of all 40. + --relative-date Display the date in a relative format (for example, “2 weeks ago”) instead of using the full date format. + --graph Display an ASCII graph of the branch and merge history beside the log output. + --pretty Show commits in an alternate format. Options include oneline, short, full, fuller, and format (where you specify your own format). + --oneline A convenience option short for `--pretty=oneline --abbrev-commit`. + +### Limiting Log Output ### + +In addition to output-formatting options, `git log` takes a number of useful limiting options — that is, options that let you show only a subset of commits. You’ve seen one such option already — the `-2` option, which shows only the last two commits. In fact, you can do `-`, where `n` is any integer to show the last `n` commits. In reality, you’re unlikely to use that often, because Git by default pipes all output through a pager so you see only one page of log output at a time. + +However, the time-limiting options such as `--since` and `--until` are very useful. For example, this command gets the list of commits made in the last two weeks: + + $ git log --since=2.weeks + +This command works with lots of formats — you can specify a specific date (“2008-01-15”) or a relative date such as “2 years 1 day 3 minutes ago”. + +You can also filter the list to commits that match some search criteria. The `--author` option allows you to filter on a specific author, and the `--grep` option lets you search for keywords in the commit messages. (Note that if you want to specify both author and grep options, you have to add `--all-match` or the command will match commits with either.) + +The last really useful option to pass to `git log` as a filter is a path. If you specify a directory or file name, you can limit the log output to commits that introduced a change to those files. This is always the last option and is generally preceded by double dashes (`--`) to separate the paths from the options. + +In Table 2-3 we’ll list these and a few other common options for your reference. + + + + Option Description + -(n) Show only the last n commits + --since, --after Limit the commits to those made after the specified date. + --until, --before Limit the commits to those made before the specified date. + --author Only show commits in which the author entry matches the specified string. + --committer Only show commits in which the committer entry matches the specified string. + +For example, if you want to see which commits modifying test files in the Git source code history were committed by Junio Hamano in the month of October 2008 and were not merges, you can run something like this: + + $ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \ + --before="2008-11-01" --no-merges -- t/ + 5610e3b - Fix testcase failure when extended attribute + acd3b9e - Enhance hold_lock_file_for_{update,append}() + f563754 - demonstrate breakage of detached checkout wi + d1a43f2 - reset --hard/read-tree --reset -u: remove un + 51a94af - Fix "checkout --track -b newbranch" on detac + b0ad11e - pull: allow "git pull origin $something:$cur + +Of the nearly 20,000 commits in the Git source code history, this command shows the 6 that match those criteria. + +### Using a GUI to Visualize History ### + +If you like to use a more graphical tool to visualize your commit history, you may want to take a look at a Tcl/Tk program called `gitk` that is distributed with Git. Gitk is basically a visual `git log` tool, and it accepts nearly all the filtering options that `git log` does. If you type `gitk` on the command line in your project, you should see something like Figure 2-2. + +Insert 18333fig0202.png +Figure 2-2. The gitk history visualizer. + +You can see the commit history in the top half of the window along with a nice ancestry graph. The diff viewer in the bottom half of the window shows you the changes introduced at any commit you click. + +## Undoing Things ## + +At any stage, you may want to undo something. Here, we’ll review a few basic tools for undoing changes that you’ve made. Be careful, because you can’t always revert some of these undos. This is one of the few areas in Git where you may lose some work if you do it wrong. + +### Changing Your Last Commit ### + +One of the common undos takes place when you commit too early and possibly forget to add some files, or you mess up your commit message. If you want to try that commit again, you can run commit with the `--amend` option: + + $ git commit --amend + +This command takes your staging area and uses it for the commit. If you’ve made no changes since your last commit (for instance, you run this command immediately after your previous commit), then your snapshot will look exactly the same and all you’ll change is your commit message. + +The same commit-message editor fires up, but it already contains the message of your previous commit. You can edit the message the same as always, but it overwrites your previous commit. + +As an example, if you commit and then realize you forgot to stage the changes in a file you wanted to add to this commit, you can do something like this: + + $ git commit -m 'initial commit' + $ git add forgotten_file + $ git commit --amend + +After these three commands, you end up with a single commit — the second commit replaces the results of the first. + +### Unstaging a Staged File ### + +The next two sections demonstrate how to wrangle your staging area and working directory changes. The nice part is that the command you use to determine the state of those two areas also reminds you how to undo changes to them. For example, let’s say you’ve changed two files and want to commit them as two separate changes, but you accidentally type `git add *` and stage them both. How can you unstage one of the two? The `git status` command reminds you: + + $ git add . + $ git status + # On branch master + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # modified: README.txt + # modified: benchmarks.rb + # + +Right below the “Changes to be committed” text, it says "use `git reset HEAD ...` to unstage". So, let’s use that advice to unstage the `benchmarks.rb` file: + + $ git reset HEAD benchmarks.rb + benchmarks.rb: locally modified + $ git status + # On branch master + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # modified: README.txt + # + # Changes not staged for commit: + # (use "git add ..." to update what will be committed) + # (use "git checkout -- ..." to discard changes in working directory) + # + # modified: benchmarks.rb + # + +The command is a bit strange, but it works. The `benchmarks.rb` file is modified but once again unstaged. + +### Unmodifying a Modified File ### + +What if you realize that you don’t want to keep your changes to the `benchmarks.rb` file? How can you easily unmodify it — revert it back to what it looked like when you last committed (or initially cloned, or however you got it into your working directory)? Luckily, `git status` tells you how to do that, too. In the last example output, the unstaged area looks like this: + + # Changes not staged for commit: + # (use "git add ..." to update what will be committed) + # (use "git checkout -- ..." to discard changes in working directory) + # + # modified: benchmarks.rb + # + +It tells you pretty explicitly how to discard the changes you’ve made (at least, the newer versions of Git, 1.6.1 and later, do this — if you have an older version, we highly recommend upgrading it to get some of these nicer usability features). Let’s do what it says: + + $ git checkout -- benchmarks.rb + $ git status + # On branch master + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # modified: README.txt + # + +You can see that the changes have been reverted. You should also realize that this is a dangerous command: any changes you made to that file are gone — you just copied another file over it. Don’t ever use this command unless you absolutely know that you don’t want the file. If you just need to get it out of the way, we’ll go over stashing and branching in the next chapter; these are generally better ways to go. + +Remember, anything that is committed in Git can almost always be recovered. Even commits that were on branches that were deleted or commits that were overwritten with an `--amend` commit can be recovered (see *Chapter 9* for data recovery). However, anything you lose that was never committed is likely never to be seen again. + +## Working with Remotes ## + +To be able to collaborate on any Git project, you need to know how to manage your remote repositories. Remote repositories are versions of your project that are hosted on the Internet or network somewhere. You can have several of them, each of which generally is either read-only or read/write for you. Collaborating with others involves managing these remote repositories and pushing and pulling data to and from them when you need to share work. +Managing remote repositories includes knowing how to add remote repositories, remove remotes that are no longer valid, manage various remote branches and define them as being tracked or not, and more. In this section, we’ll cover these remote-management skills. + +### Showing Your Remotes ### + +To see which remote servers you have configured, you can run the `git remote` command. It lists the shortnames of each remote handle you’ve specified. If you’ve cloned your repository, you should at least see *origin* — that is the default name Git gives to the server you cloned from: + + $ git clone git://github.com/schacon/ticgit.git + Initialized empty Git repository in /private/tmp/ticgit/.git/ + remote: Counting objects: 595, done. + remote: Compressing objects: 100% (269/269), done. + remote: Total 595 (delta 255), reused 589 (delta 253) + Receiving objects: 100% (595/595), 73.31 KiB | 1 KiB/s, done. + Resolving deltas: 100% (255/255), done. + $ cd ticgit + $ git remote + origin + +You can also specify `-v`, which shows you the URL that Git has stored for the shortname to be expanded to: + + $ git remote -v + origin git://github.com/schacon/ticgit.git (fetch) + origin git://github.com/schacon/ticgit.git (push) + +If you have more than one remote, the command lists them all. For example, my Grit repository looks something like this. + + $ cd grit + $ git remote -v + bakkdoor git://github.com/bakkdoor/grit.git + cho45 git://github.com/cho45/grit.git + defunkt git://github.com/defunkt/grit.git + koke git://github.com/koke/grit.git + origin git@github.com:mojombo/grit.git + +This means we can pull contributions from any of these users pretty easily. But notice that only the origin remote is an SSH URL, so it’s the only one I can push to (we’ll cover why this is in *Chapter 4*). + +### Adding Remote Repositories ### + +I’ve mentioned and given some demonstrations of adding remote repositories in previous sections, but here is how to do it explicitly. To add a new remote Git repository as a shortname you can reference easily, run `git remote add [shortname] [url]`: + + $ git remote + origin + $ git remote add pb git://github.com/paulboone/ticgit.git + $ git remote -v + origin git://github.com/schacon/ticgit.git + pb git://github.com/paulboone/ticgit.git + +Now you can use the string `pb` on the command line in lieu of the whole URL. For example, if you want to fetch all the information that Paul has but that you don’t yet have in your repository, you can run `git fetch pb`: + + $ git fetch pb + remote: Counting objects: 58, done. + remote: Compressing objects: 100% (41/41), done. + remote: Total 44 (delta 24), reused 1 (delta 0) + Unpacking objects: 100% (44/44), done. + From git://github.com/paulboone/ticgit + * [new branch] master -> pb/master + * [new branch] ticgit -> pb/ticgit + +Paul’s master branch is accessible locally as `pb/master` — you can merge it into one of your branches, or you can check out a local branch at that point if you want to inspect it. + +### Fetching and Pulling from Your Remotes ### + +As you just saw, to get data from your remote projects, you can run: + + $ git fetch [remote-name] + +The command goes out to that remote project and pulls down all the data from that remote project that you don’t have yet. After you do this, you should have references to all the branches from that remote, which you can merge in or inspect at any time. (We’ll go over what branches are and how to use them in much more detail in *Chapter 3*.) + +If you clone a repository, the command automatically adds that remote repository under the name *origin*. So, `git fetch origin` fetches any new work that has been pushed to that server since you cloned (or last fetched from) it. It’s important to note that the `fetch` command pulls the data to your local repository — it doesn’t automatically merge it with any of your work or modify what you’re currently working on. You have to merge it manually into your work when you’re ready. + +If you have a branch set up to track a remote branch (see the next section and *Chapter 3* for more information), you can use the `git pull` command to automatically fetch and then merge a remote branch into your current branch. This may be an easier or more comfortable workflow for you; and by default, the `git clone` command automatically sets up your local master branch to track the remote master branch on the server you cloned from (assuming the remote has a master branch). Running `git pull` generally fetches data from the server you originally cloned from and automatically tries to merge it into the code you’re currently working on. + +### Pushing to Your Remotes ### + +When you have your project at a point that you want to share, you have to push it upstream. The command for this is simple: `git push [remote-name] [branch-name]`. If you want to push your master branch to your `origin` server (again, cloning generally sets up both of those names for you automatically), then you can run this to push your work back up to the server: + + $ git push origin master + +This command works only if you cloned from a server to which you have write access and if nobody has pushed in the meantime. If you and someone else clone at the same time and they push upstream and then you push upstream, your push will rightly be rejected. You’ll have to pull down their work first and incorporate it into yours before you’ll be allowed to push. See *Chapter 3* for more detailed information on how to push to remote servers. + +### Inspecting a Remote ### + +If you want to see more information about a particular remote, you can use the `git remote show [remote-name]` command. If you run this command with a particular shortname, such as `origin`, you get something like this: + + $ git remote show origin + * remote origin + URL: git://github.com/schacon/ticgit.git + Remote branch merged with 'git pull' while on branch master + master + Tracked remote branches + master + ticgit + +It lists the URL for the remote repository as well as the tracking branch information. The command helpfully tells you that if you’re on the master branch and you run `git pull`, it will automatically merge in the master branch on the remote after it fetches all the remote references. It also lists all the remote references it has pulled down. + +That is a simple example you’re likely to encounter. When you’re using Git more heavily, however, you may see much more information from `git remote show`: + + $ git remote show origin + * remote origin + URL: git@github.com:defunkt/github.git + Remote branch merged with 'git pull' while on branch issues + issues + Remote branch merged with 'git pull' while on branch master + master + New remote branches (next fetch will store in remotes/origin) + caching + Stale tracking branches (use 'git remote prune') + libwalker + walker2 + Tracked remote branches + acl + apiv2 + dashboard2 + issues + master + postgres + Local branch pushed with 'git push' + master:master + +This command shows which branch is automatically pushed when you run `git push` on certain branches. It also shows you which remote branches on the server you don’t yet have, which remote branches you have that have been removed from the server, and multiple branches that are automatically merged when you run `git pull`. + +### Removing and Renaming Remotes ### + +If you want to rename a reference, in newer versions of Git you can run `git remote rename` to change a remote’s shortname. For instance, if you want to rename `pb` to `paul`, you can do so with `git remote rename`: + + $ git remote rename pb paul + $ git remote + origin + paul + +It’s worth mentioning that this changes your remote branch names, too. What used to be referenced at `pb/master` is now at `paul/master`. + +If you want to remove a reference for some reason — you’ve moved the server or are no longer using a particular mirror, or perhaps a contributor isn’t contributing anymore — you can use `git remote rm`: + + $ git remote rm paul + $ git remote + origin + +## Tagging ## + +Like most VCSs, Git has the ability to tag specific points in history as being important. Generally, people use this functionality to mark release points (`v1.0`, and so on). In this section, you’ll learn how to list the available tags, how to create new tags, and what the different types of tags are. + +### Listing Your Tags ### + +Listing the available tags in Git is straightforward. Just type `git tag`: + + $ git tag + v0.1 + v1.3 + +This command lists the tags in alphabetical order; the order in which they appear has no real importance. + +You can also search for tags with a particular pattern. The Git source repo, for instance, contains more than 240 tags. If you’re only interested in looking at the 1.4.2 series, you can run this: + + $ git tag -l 'v1.4.2.*' + v1.4.2.1 + v1.4.2.2 + v1.4.2.3 + v1.4.2.4 + +### Creating Tags ### + +Git uses two main types of tags: lightweight and annotated. A lightweight tag is very much like a branch that doesn’t change — it’s just a pointer to a specific commit. Annotated tags, however, are stored as full objects in the Git database. They’re checksummed; contain the tagger name, e-mail, and date; have a tagging message; and can be signed and verified with GNU Privacy Guard (GPG). It’s generally recommended that you create annotated tags so you can have all this information; but if you want a temporary tag or for some reason don’t want to keep the other information, lightweight tags are available too. + +### Annotated Tags ### + +Creating an annotated tag in Git is simple. The easiest way is to specify `-a` when you run the `tag` command: + + $ git tag -a v1.4 -m 'my version 1.4' + $ git tag + v0.1 + v1.3 + v1.4 + +The `-m` specifies a tagging message, which is stored with the tag. If you don’t specify a message for an annotated tag, Git launches your editor so you can type it in. + +You can see the tag data along with the commit that was tagged by using the `git show` command: + + $ git show v1.4 + tag v1.4 + Tagger: Scott Chacon + Date: Mon Feb 9 14:45:11 2009 -0800 + + my version 1.4 + commit 15027957951b64cf874c3557a0f3547bd83b3ff6 + Merge: 4a447f7... a6b4c97... + Author: Scott Chacon + Date: Sun Feb 8 19:02:46 2009 -0800 + + Merge branch 'experiment' + +That shows the tagger information, the date the commit was tagged, and the annotation message before showing the commit information. + +### Signed Tags ### + +You can also sign your tags with GPG, assuming you have a private key. All you have to do is use `-s` instead of `-a`: + + $ git tag -s v1.5 -m 'my signed 1.5 tag' + You need a passphrase to unlock the secret key for + user: "Scott Chacon " + 1024-bit DSA key, ID F721C45A, created 2009-02-09 + +If you run `git show` on that tag, you can see your GPG signature attached to it: + + $ git show v1.5 + tag v1.5 + Tagger: Scott Chacon + Date: Mon Feb 9 15:22:20 2009 -0800 + + my signed 1.5 tag + -----BEGIN PGP SIGNATURE----- + Version: GnuPG v1.4.8 (Darwin) + + iEYEABECAAYFAkmQurIACgkQON3DxfchxFr5cACeIMN+ZxLKggJQf0QYiQBwgySN + Ki0An2JeAVUCAiJ7Ox6ZEtK+NvZAj82/ + =WryJ + -----END PGP SIGNATURE----- + commit 15027957951b64cf874c3557a0f3547bd83b3ff6 + Merge: 4a447f7... a6b4c97... + Author: Scott Chacon + Date: Sun Feb 8 19:02:46 2009 -0800 + + Merge branch 'experiment' + +A bit later, you’ll learn how to verify signed tags. + +### Lightweight Tags ### + +Another way to tag commits is with a lightweight tag. This is basically the commit checksum stored in a file — no other information is kept. To create a lightweight tag, don’t supply the `-a`, `-s`, or `-m` option: + + $ git tag v1.4-lw + $ git tag + v0.1 + v1.3 + v1.4 + v1.4-lw + v1.5 + +This time, if you run `git show` on the tag, you don’t see the extra tag information. The command just shows the commit: + + $ git show v1.4-lw + commit 15027957951b64cf874c3557a0f3547bd83b3ff6 + Merge: 4a447f7... a6b4c97... + Author: Scott Chacon + Date: Sun Feb 8 19:02:46 2009 -0800 + + Merge branch 'experiment' + +### Verifying Tags ### + +To verify a signed tag, you use `git tag -v [tag-name]`. This command uses GPG to verify the signature. You need the signer’s public key in your keyring for this to work properly: + + $ git tag -v v1.4.2.1 + object 883653babd8ee7ea23e6a5c392bb739348b1eb61 + type commit + tag v1.4.2.1 + tagger Junio C Hamano 1158138501 -0700 + + GIT 1.4.2.1 + + Minor fixes since 1.4.2, including git-mv and git-http with alternates. + gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A + gpg: Good signature from "Junio C Hamano " + gpg: aka "[jpeg image of size 1513]" + Primary key fingerprint: 3565 2A26 2040 E066 C9A7 4A7D C0C6 D9A4 F311 9B9A + +If you don’t have the signer’s public key, you get something like this instead: + + gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A + gpg: Can't check signature: public key not found + error: could not verify the tag 'v1.4.2.1' + +### Tagging Later ### + +You can also tag commits after you’ve moved past them. Suppose your commit history looks like this: + + $ git log --pretty=oneline + 15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment' + a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support + 0d52aaab4479697da7686c15f77a3d64d9165190 one more thing + 6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment' + 0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function + 4682c3261057305bdd616e23b64b0857d832627b added a todo file + 166ae0c4d3f420721acbb115cc33848dfcc2121a started write support + 9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile + 964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo + 8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme + +Now, suppose you forgot to tag the project at `v1.2`, which was at the "updated rakefile" commit. You can add it after the fact. To tag that commit, you specify the commit checksum (or part of it) at the end of the command: + + $ git tag -a v1.2 -m 'version 1.2' 9fceb02 + +You can see that you’ve tagged the commit: + + $ git tag + v0.1 + v1.2 + v1.3 + v1.4 + v1.4-lw + v1.5 + + $ git show v1.2 + tag v1.2 + Tagger: Scott Chacon + Date: Mon Feb 9 15:32:16 2009 -0800 + + version 1.2 + commit 9fceb02d0ae598e95dc970b74767f19372d61af8 + Author: Magnus Chacon + Date: Sun Apr 27 20:43:35 2008 -0700 + + updated rakefile + ... + +### Sharing Tags ### + +By default, the `git push` command doesn’t transfer tags to remote servers. You will have to explicitly push tags to a shared server after you have created them. This process is just like sharing remote branches — you can run `git push origin [tagname]`. + + $ git push origin v1.5 + Counting objects: 50, done. + Compressing objects: 100% (38/38), done. + Writing objects: 100% (44/44), 4.56 KiB, done. + Total 44 (delta 18), reused 8 (delta 1) + To git@github.com:schacon/simplegit.git + * [new tag] v1.5 -> v1.5 + +If you have a lot of tags that you want to push up at once, you can also use the `--tags` option to the `git push` command. This will transfer all of your tags to the remote server that are not already there. + + $ git push origin --tags + Counting objects: 50, done. + Compressing objects: 100% (38/38), done. + Writing objects: 100% (44/44), 4.56 KiB, done. + Total 44 (delta 18), reused 8 (delta 1) + To git@github.com:schacon/simplegit.git + * [new tag] v0.1 -> v0.1 + * [new tag] v1.2 -> v1.2 + * [new tag] v1.4 -> v1.4 + * [new tag] v1.4-lw -> v1.4-lw + * [new tag] v1.5 -> v1.5 + +Now, when someone else clones or pulls from your repository, they will get all your tags as well. + +## Tips and Tricks ## + +Before we finish this chapter on basic Git, a few little tips and tricks may make your Git experience a bit simpler, easier, or more familiar. Many people use Git without using any of these tips, and we won’t refer to them or assume you’ve used them later in the book; but you should probably know how to do them. + +### Auto-Completion ### + +If you use the Bash shell, Git comes with a nice auto-completion script you can enable. Download it directly from the Git source code at https://github.com/git/git/blob/master/contrib/completion/git-completion.bash . Copy this file to your home directory, and add this to your `.bashrc` file: + + source ~/git-completion.bash + +If you want to set up Git to automatically have Bash shell completion for all users, copy this script to the `/opt/local/etc/bash_completion.d` directory on Mac systems or to the `/etc/bash_completion.d/` directory on Linux systems. This is a directory of scripts that Bash will automatically load to provide shell completions. + +If you’re using Windows with Git Bash, which is the default when installing Git on Windows with msysGit, auto-completion should be preconfigured. + +Press the Tab key when you’re writing a Git command, and it should return a set of suggestions for you to pick from: + + $ git co + commit config + +In this case, typing `git co` and then pressing the Tab key twice suggests commit and config. Adding `m` completes `git commit` automatically. + +This also works with options, which is probably more useful. For instance, if you’re running a `git log` command and can’t remember one of the options, you can start typing it and press Tab to see what matches: + + $ git log --s + --shortstat --since= --src-prefix= --stat --summary + +That’s a pretty nice trick and may save you some time and documentation reading. + +### Git Aliases ### + +Git doesn’t infer your command if you type it in partially. If you don’t want to type the entire text of each of the Git commands, you can easily set up an alias for each command using `git config`. Here are a couple of examples you may want to set up: + + $ git config --global alias.co checkout + $ git config --global alias.br branch + $ git config --global alias.ci commit + $ git config --global alias.st status + +This means that, for example, instead of typing `git commit`, you just need to type `git ci`. As you go on using Git, you’ll probably use other commands frequently as well; in this case, don’t hesitate to create new aliases. + +This technique can also be very useful in creating commands that you think should exist. For example, to correct the usability problem you encountered with unstaging a file, you can add your own unstage alias to Git: + + $ git config --global alias.unstage 'reset HEAD --' + +This makes the following two commands equivalent: + + $ git unstage fileA + $ git reset HEAD fileA + +This seems a bit clearer. It’s also common to add a `last` command, like this: + + $ git config --global alias.last 'log -1 HEAD' + +This way, you can see the last commit easily: + + $ git last + commit 66938dae3329c7aebe598c2246a8e6af90d04646 + Author: Josh Goebel + Date: Tue Aug 26 19:48:51 2008 +0800 + + test for current head + + Signed-off-by: Scott Chacon + +As you can tell, Git simply replaces the new command with whatever you alias it to. However, maybe you want to run an external command, rather than a Git subcommand. In that case, you start the command with a `!` character. This is useful if you write your own tools that work with a Git repository. We can demonstrate by aliasing `git visual` to run `gitk`: + + $ git config --global alias.visual '!gitk' + +## Summary ## + +At this point, you can do all the basic local Git operations — creating or cloning a repository, making changes, staging and committing those changes, and viewing the history of all the changes the repository has been through. Next, we’ll cover Git’s killer feature: its branching model. diff --git a/vi/03-git-branching/01-chapter3.markdown b/vi/03-git-branching/01-chapter3.markdown new file mode 100644 index 000000000..8924dbe5e --- /dev/null +++ b/vi/03-git-branching/01-chapter3.markdown @@ -0,0 +1,598 @@ +# Git Branching # + +Nearly every VCS has some form of branching support. Branching means you diverge from the main line of development and continue to do work without messing with that main line. In many VCS tools, this is a somewhat expensive process, often requiring you to create a new copy of your source code directory, which can take a long time for large projects. + +Some people refer to the branching model in Git as its “killer feature” , and it certainly sets Git apart in the VCS community. Why is it so special? The way Git branches is incredibly lightweight, making branching operations nearly instantaneous and switching back and forth between branches generally just as fast. Unlike many other VCSs, Git encourages a workflow that branches and merges often, even multiple times in a day. Understanding and mastering this feature gives you a powerful and unique tool and can literally change the way that you develop. + +## What a Branch Is ## + +To really understand the way Git does branching, we need to take a step back and examine how Git stores its data. As you may remember from Chapter 1, Git doesn’t store data as a series of changesets or deltas, but instead as a series of snapshots. + +When you commit in Git, Git stores a commit object that contains a pointer to the snapshot of the content you staged, the author and message metadata, and zero or more pointers to the commit or commits that were the direct parents of this commit: zero parents for the first commit, one parent for a normal commit, and multiple parents for a commit that results from a merge of two or more branches. + +To visualize this, let’s assume that you have a directory containing three files, and you stage them all and commit. Staging the files checksums each one (the SHA-1 hash we mentioned in Chapter 1), stores that version of the file in the Git repository (Git refers to them as blobs), and adds that checksum to the staging area: + + $ git add README test.rb LICENSE + $ git commit -m 'initial commit of my project' + +Running `git commit` checksums all project directories and stores them as `tree` objects in the Git repository. Git then creates a `commit` object that has the metadata and a pointer to the root project `tree` object so it can re-create that snapshot when needed. + +Your Git repository now contains five objects: one blob for the contents of each of your three files, one tree that lists the contents of the directory and specifies which file names are stored as which blobs, and one commit with the pointer to that root tree and all the commit metadata. Conceptually, the data in your Git repository looks something like Figure 3-1. + +Insert 18333fig0301.png +Figure 3-1. Single commit repository data. + +If you make some changes and commit again, the next commit stores a pointer to the commit that came immediately before it. After two more commits, your history might look something like Figure 3-2. + +Insert 18333fig0302.png +Figure 3-2. Git object data for multiple commits. + +A branch in Git is simply a lightweight movable pointer to one of these commits. The default branch name in Git is master. As you initially make commits, you’re given a `master` branch that points to the last commit you made. Every time you commit, it moves forward automatically. + +Insert 18333fig0303.png +Figure 3-3. Branch pointing into the commit data’s history. + +What happens if you create a new branch? Well, doing so creates a new pointer for you to move around. Let’s say you create a new branch called testing. You do this with the `git branch` command: + + $ git branch testing + +This creates a new pointer at the same commit you’re currently on (see Figure 3-4). + +Insert 18333fig0304.png +Figure 3-4. Multiple branches pointing into the commit’s data history. + +How does Git know what branch you’re currently on? It keeps a special pointer called HEAD. Note that this is a lot different than the concept of HEAD in other VCSs you may be used to, such as Subversion or CVS. In Git, this is a pointer to the local branch you’re currently on. In this case, you’re still on master. The git branch command only created a new branch — it didn’t switch to that branch (see Figure 3-5). + +Insert 18333fig0305.png +Figure 3-5. HEAD file pointing to the branch you’re on. + +To switch to an existing branch, you run the `git checkout` command. Let’s switch to the new testing branch: + + $ git checkout testing + +This moves HEAD to point to the testing branch (see Figure 3-6). + +Insert 18333fig0306.png +Figure 3-6. HEAD points to another branch when you switch branches. + +What is the significance of that? Well, let’s do another commit: + + $ vim test.rb + $ git commit -a -m 'made a change' + +Figure 3-7 illustrates the result. + +Insert 18333fig0307.png +Figure 3-7. The branch that HEAD points to moves forward with each commit. + +This is interesting, because now your testing branch has moved forward, but your `master` branch still points to the commit you were on when you ran `git checkout` to switch branches. Let’s switch back to the `master` branch: + + $ git checkout master + +Figure 3-8 shows the result. + +Insert 18333fig0308.png +Figure 3-8. HEAD moves to another branch on a checkout. + +That command did two things. It moved the HEAD pointer back to point to the `master` branch, and it reverted the files in your working directory back to the snapshot that `master` points to. This also means the changes you make from this point forward will diverge from an older version of the project. It essentially rewinds the work you’ve done in your testing branch temporarily so you can go in a different direction. + +Let’s make a few changes and commit again: + + $ vim test.rb + $ git commit -a -m 'made other changes' + +Now your project history has diverged (see Figure 3-9). You created and switched to a branch, did some work on it, and then switched back to your main branch and did other work. Both of those changes are isolated in separate branches: you can switch back and forth between the branches and merge them together when you’re ready. And you did all that with simple `branch` and `checkout` commands. + +Insert 18333fig0309.png +Figure 3-9. The branch histories have diverged. + +Because a branch in Git is in actuality a simple file that contains the 40 character SHA-1 checksum of the commit it points to, branches are cheap to create and destroy. Creating a new branch is as quick and simple as writing 41 bytes to a file (40 characters and a newline). + +This is in sharp contrast to the way most VCS tools branch, which involves copying all of the project’s files into a second directory. This can take several seconds or even minutes, depending on the size of the project, whereas in Git the process is always instantaneous. Also, because we’re recording the parents when we commit, finding a proper merge base for merging is automatically done for us and is generally very easy to do. These features help encourage developers to create and use branches often. + +Let’s see why you should do so. + +## Basic Branching and Merging ## + +Let’s go through a simple example of branching and merging with a workflow that you might use in the real world. You’ll follow these steps: + +1. Do work on a web site. +2. Create a branch for a new story you’re working on. +3. Do some work in that branch. + +At this stage, you’ll receive a call that another issue is critical and you need a hotfix. You’ll do the following: + +1. Revert back to your production branch. +2. Create a branch to add the hotfix. +3. After it’s tested, merge the hotfix branch, and push to production. +4. Switch back to your original story and continue working. + +### Basic Branching ### + +First, let’s say you’re working on your project and have a couple of commits already (see Figure 3-10). + +Insert 18333fig0310.png +Figure 3-10. A short and simple commit history. + +You’ve decided that you’re going to work on issue #53 in whatever issue-tracking system your company uses. To be clear, Git isn’t tied into any particular issue-tracking system; but because issue #53 is a focused topic that you want to work on, you’ll create a new branch in which to work. To create a branch and switch to it at the same time, you can run the `git checkout` command with the `-b` switch: + + $ git checkout -b iss53 + Switched to a new branch "iss53" + +This is shorthand for: + + $ git branch iss53 + $ git checkout iss53 + +Figure 3-11 illustrates the result. + +Insert 18333fig0311.png +Figure 3-11. Creating a new branch pointer. + +You work on your web site and do some commits. Doing so moves the `iss53` branch forward, because you have it checked out (that is, your HEAD is pointing to it; see Figure 3-12): + + $ vim index.html + $ git commit -a -m 'added a new footer [issue 53]' + +Insert 18333fig0312.png +Figure 3-12. The iss53 branch has moved forward with your work. + +Now you get the call that there is an issue with the web site, and you need to fix it immediately. With Git, you don’t have to deploy your fix along with the `iss53` changes you’ve made, and you don’t have to put a lot of effort into reverting those changes before you can work on applying your fix to what is in production. All you have to do is switch back to your master branch. + +However, before you do that, note that if your working directory or staging area has uncommitted changes that conflict with the branch you’re checking out, Git won’t let you switch branches. It’s best to have a clean working state when you switch branches. There are ways to get around this (namely, stashing and commit amending) that we’ll cover later. For now, you’ve committed all your changes, so you can switch back to your master branch: + + $ git checkout master + Switched to branch "master" + +At this point, your project working directory is exactly the way it was before you started working on issue #53, and you can concentrate on your hotfix. This is an important point to remember: Git resets your working directory to look like the snapshot of the commit that the branch you check out points to. It adds, removes, and modifies files automatically to make sure your working copy is what the branch looked like on your last commit to it. + +Next, you have a hotfix to make. Let’s create a hotfix branch on which to work until it’s completed (see Figure 3-13): + + $ git checkout -b hotfix + Switched to a new branch "hotfix" + $ vim index.html + $ git commit -a -m 'fixed the broken email address' + [hotfix]: created 3a0874c: "fixed the broken email address" + 1 files changed, 0 insertions(+), 1 deletions(-) + +Insert 18333fig0313.png +Figure 3-13. hotfix branch based back at your master branch point. + +You can run your tests, make sure the hotfix is what you want, and merge it back into your master branch to deploy to production. You do this with the `git merge` command: + + $ git checkout master + $ git merge hotfix + Updating f42c576..3a0874c + Fast forward + README | 1 - + 1 files changed, 0 insertions(+), 1 deletions(-) + +You’ll notice the phrase "Fast forward" in that merge. Because the commit pointed to by the branch you merged in was directly upstream of the commit you’re on, Git moves the pointer forward. To phrase that another way, when you try to merge one commit with a commit that can be reached by following the first commit’s history, Git simplifies things by moving the pointer forward because there is no divergent work to merge together — this is called a "fast forward". + +Your change is now in the snapshot of the commit pointed to by the `master` branch, and you can deploy your change (see Figure 3-14). + +Insert 18333fig0314.png +Figure 3-14. Your master branch points to the same place as your hotfix branch after the merge. + +After your super-important fix is deployed, you’re ready to switch back to the work you were doing before you were interrupted. However, first you’ll delete the `hotfix` branch, because you no longer need it — the `master` branch points at the same place. You can delete it with the `-d` option to `git branch`: + + $ git branch -d hotfix + Deleted branch hotfix (3a0874c). + +Now you can switch back to your work-in-progress branch on issue #53 and continue working on it (see Figure 3-15): + + $ git checkout iss53 + Switched to branch "iss53" + $ vim index.html + $ git commit -a -m 'finished the new footer [issue 53]' + [iss53]: created ad82d7a: "finished the new footer [issue 53]" + 1 files changed, 1 insertions(+), 0 deletions(-) + +Insert 18333fig0315.png +Figure 3-15. Your iss53 branch can move forward independently. + +It’s worth noting here that the work you did in your `hotfix` branch is not contained in the files in your `iss53` branch. If you need to pull it in, you can merge your `master` branch into your `iss53` branch by running `git merge master`, or you can wait to integrate those changes until you decide to pull the `iss53` branch back into `master` later. + +### Basic Merging ### + +Suppose you’ve decided that your issue #53 work is complete and ready to be merged into your `master` branch. In order to do that, you’ll merge in your `iss53` branch, much like you merged in your `hotfix` branch earlier. All you have to do is check out the branch you wish to merge into and then run the `git merge` command: + + $ git checkout master + $ git merge iss53 + Merge made by recursive. + README | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +This looks a bit different than the `hotfix` merge you did earlier. In this case, your development history has diverged from some older point. Because the commit on the branch you’re on isn’t a direct ancestor of the branch you’re merging in, Git has to do some work. In this case, Git does a simple three-way merge, using the two snapshots pointed to by the branch tips and the common ancestor of the two. Figure 3-16 highlights the three snapshots that Git uses to do its merge in this case. + +Insert 18333fig0316.png +Figure 3-16. Git automatically identifies the best common-ancestor merge base for branch merging. + +Instead of just moving the branch pointer forward, Git creates a new snapshot that results from this three-way merge and automatically creates a new commit that points to it (see Figure 3-17). This is referred to as a merge commit and is special in that it has more than one parent. + +It’s worth pointing out that Git determines the best common ancestor to use for its merge base; this is different than CVS or Subversion (before version 1.5), where the developer doing the merge has to figure out the best merge base for themselves. This makes merging a heck of a lot easier in Git than in these other systems. + +Insert 18333fig0317.png +Figure 3-17. Git automatically creates a new commit object that contains the merged work. + +Now that your work is merged in, you have no further need for the `iss53` branch. You can delete it and then manually close the ticket in your ticket-tracking system: + + $ git branch -d iss53 + +### Basic Merge Conflicts ### + +Occasionally, this process doesn’t go smoothly. If you changed the same part of the same file differently in the two branches you’re merging together, Git won’t be able to merge them cleanly. If your fix for issue #53 modified the same part of a file as the `hotfix`, you’ll get a merge conflict that looks something like this: + + $ git merge iss53 + Auto-merging index.html + CONFLICT (content): Merge conflict in index.html + Automatic merge failed; fix conflicts and then commit the result. + +Git hasn’t automatically created a new merge commit. It has paused the process while you resolve the conflict. If you want to see which files are unmerged at any point after a merge conflict, you can run `git status`: + + [master*]$ git status + index.html: needs merge + # On branch master + # Changes not staged for commit: + # (use "git add ..." to update what will be committed) + # (use "git checkout -- ..." to discard changes in working directory) + # + # unmerged: index.html + # + +Anything that has merge conflicts and hasn’t been resolved is listed as unmerged. Git adds standard conflict-resolution markers to the files that have conflicts, so you can open them manually and resolve those conflicts. Your file contains a section that looks something like this: + + <<<<<<< HEAD:index.html + + ======= + + >>>>>>> iss53:index.html + +This means the version in HEAD (your master branch, because that was what you had checked out when you ran your merge command) is the top part of that block (everything above the `=======`), while the version in your `iss53` branch looks like everything in the bottom part. In order to resolve the conflict, you have to either choose one side or the other or merge the contents yourself. For instance, you might resolve this conflict by replacing the entire block with this: + + + +This resolution has a little of each section, and I’ve fully removed the `<<<<<<<`, `=======`, and `>>>>>>>` lines. After you’ve resolved each of these sections in each conflicted file, run `git add` on each file to mark it as resolved. Staging the file marks it as resolved in Git. +If you want to use a graphical tool to resolve these issues, you can run `git mergetool`, which fires up an appropriate visual merge tool and walks you through the conflicts: + + $ git mergetool + merge tool candidates: kdiff3 tkdiff xxdiff meld gvimdiff opendiff emerge vimdiff + Merging the files: index.html + + Normal merge conflict for 'index.html': + {local}: modified + {remote}: modified + Hit return to start merge resolution tool (opendiff): + +If you want to use a merge tool other than the default (Git chose `opendiff` for me in this case because I ran the command on a Mac), you can see all the supported tools listed at the top after “merge tool candidates”. Type the name of the tool you’d rather use. In Chapter 7, we’ll discuss how you can change this default value for your environment. + +After you exit the merge tool, Git asks you if the merge was successful. If you tell the script that it was, it stages the file to mark it as resolved for you. + +You can run `git status` again to verify that all conflicts have been resolved: + + $ git status + # On branch master + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # modified: index.html + # + +If you’re happy with that, and you verify that everything that had conflicts has been staged, you can type `git commit` to finalize the merge commit. The commit message by default looks something like this: + + Merge branch 'iss53' + + Conflicts: + index.html + # + # It looks like you may be committing a MERGE. + # If this is not correct, please remove the file + # .git/MERGE_HEAD + # and try again. + # + +You can modify that message with details about how you resolved the merge if you think it would be helpful to others looking at this merge in the future — why you did what you did, if it’s not obvious. + +## Branch Management ## + +Now that you’ve created, merged, and deleted some branches, let’s look at some branch-management tools that will come in handy when you begin using branches all the time. + +The `git branch` command does more than just create and delete branches. If you run it with no arguments, you get a simple listing of your current branches: + + $ git branch + iss53 + * master + testing + +Notice the `*` character that prefixes the `master` branch: it indicates the branch that you currently have checked out. This means that if you commit at this point, the `master` branch will be moved forward with your new work. To see the last commit on each branch, you can run `git branch -v`: + + $ git branch -v + iss53 93b412c fix javascript issue + * master 7a98805 Merge branch 'iss53' + testing 782fd34 add scott to the author list in the readmes + +Another useful option to figure out what state your branches are in is to filter this list to branches that you have or have not yet merged into the branch you’re currently on. There are useful `--merged` and `--no-merged` options available in Git for this purpose. To see which branches are already merged into the branch you’re on, you can run `git branch --merged`: + + $ git branch --merged + iss53 + * master + +Because you already merged in `iss53` earlier, you see it in your list. Branches on this list without the `*` in front of them are generally fine to delete with `git branch -d`; you’ve already incorporated their work into another branch, so you’re not going to lose anything. + +To see all the branches that contain work you haven’t yet merged in, you can run `git branch --no-merged`: + + $ git branch --no-merged + testing + +This shows your other branch. Because it contains work that isn’t merged in yet, trying to delete it with `git branch -d` will fail: + + $ git branch -d testing + error: The branch 'testing' is not an ancestor of your current HEAD. + If you are sure you want to delete it, run 'git branch -D testing'. + +If you really do want to delete the branch and lose that work, you can force it with `-D`, as the helpful message points out. + +## Branching Workflows ## + +Now that you have the basics of branching and merging down, what can or should you do with them? In this section, we’ll cover some common workflows that this lightweight branching makes possible, so you can decide if you would like to incorporate it into your own development cycle. + +### Long-Running Branches ### + +Because Git uses a simple three-way merge, merging from one branch into another multiple times over a long period is generally easy to do. This means you can have several branches that are always open and that you use for different stages of your development cycle; you can merge regularly from some of them into others. + +Many Git developers have a workflow that embraces this approach, such as having only code that is entirely stable in their `master` branch — possibly only code that has been or will be released. They have another parallel branch named develop or next that they work from or use to test stability — it isn’t necessarily always stable, but whenever it gets to a stable state, it can be merged into `master`. It’s used to pull in topic branches (short-lived branches, like your earlier `iss53` branch) when they’re ready, to make sure they pass all the tests and don’t introduce bugs. + +In reality, we’re talking about pointers moving up the line of commits you’re making. The stable branches are farther down the line in your commit history, and the bleeding-edge branches are farther up the history (see Figure 3-18). + +Insert 18333fig0318.png +Figure 3-18. More stable branches are generally farther down the commit history. + +It’s generally easier to think about them as work silos, where sets of commits graduate to a more stable silo when they’re fully tested (see Figure 3-19). + +Insert 18333fig0319.png +Figure 3-19. It may be helpful to think of your branches as silos. + +You can keep doing this for several levels of stability. Some larger projects also have a `proposed` or `pu` (proposed updates) branch that has integrated branches that may not be ready to go into the `next` or `master` branch. The idea is that your branches are at various levels of stability; when they reach a more stable level, they’re merged into the branch above them. +Again, having multiple long-running branches isn’t necessary, but it’s often helpful, especially when you’re dealing with very large or complex projects. + +### Topic Branches ### + +Topic branches, however, are useful in projects of any size. A topic branch is a short-lived branch that you create and use for a single particular feature or related work. This is something you’ve likely never done with a VCS before because it’s generally too expensive to create and merge branches. But in Git it’s common to create, work on, merge, and delete branches several times a day. + +You saw this in the last section with the `iss53` and `hotfix` branches you created. You did a few commits on them and deleted them directly after merging them into your main branch. This technique allows you to context-switch quickly and completely — because your work is separated into silos where all the changes in that branch have to do with that topic, it’s easier to see what has happened during code review and such. You can keep the changes there for minutes, days, or months, and merge them in when they’re ready, regardless of the order in which they were created or worked on. + +Consider an example of doing some work (on `master`), branching off for an issue (`iss91`), working on it for a bit, branching off the second branch to try another way of handling the same thing (`iss91v2`), going back to your master branch and working there for a while, and then branching off there to do some work that you’re not sure is a good idea (`dumbidea` branch). Your commit history will look something like Figure 3-20. + +Insert 18333fig0320.png +Figure 3-20. Your commit history with multiple topic branches. + +Now, let’s say you decide you like the second solution to your issue best (`iss91v2`); and you showed the `dumbidea` branch to your coworkers, and it turns out to be genius. You can throw away the original `iss91` branch (losing commits C5 and C6) and merge in the other two. Your history then looks like Figure 3-21. + +Insert 18333fig0321.png +Figure 3-21. Your history after merging in dumbidea and iss91v2. + +It’s important to remember when you’re doing all this that these branches are completely local. When you’re branching and merging, everything is being done only in your Git repository — no server communication is happening. + +## Remote Branches ## + +Remote branches are references to the state of branches on your remote repositories. They’re local branches that you can’t move; they’re moved automatically whenever you do any network communication. Remote branches act as bookmarks to remind you where the branches on your remote repositories were the last time you connected to them. + +They take the form `(remote)/(branch)`. For instance, if you wanted to see what the `master` branch on your `origin` remote looked like as of the last time you communicated with it, you would check the `origin/master` branch. If you were working on an issue with a partner and they pushed up an `iss53` branch, you might have your own local `iss53` branch; but the branch on the server would point to the commit at `origin/iss53`. + +This may be a bit confusing, so let’s look at an example. Let’s say you have a Git server on your network at `git.ourcompany.com`. If you clone from this, Git automatically names it `origin` for you, pulls down all its data, creates a pointer to where its `master` branch is, and names it `origin/master` locally; and you can’t move it. Git also gives you your own `master` branch starting at the same place as origin’s `master` branch, so you have something to work from (see Figure 3-22). + +Insert 18333fig0322.png +Figure 3-22. A Git clone gives you your own master branch and origin/master pointing to origin’s master branch. + +If you do some work on your local master branch, and, in the meantime, someone else pushes to `git.ourcompany.com` and updates its master branch, then your histories move forward differently. Also, as long as you stay out of contact with your origin server, your `origin/master` pointer doesn’t move (see Figure 3-23). + +Insert 18333fig0323.png +Figure 3-23. Working locally and having someone push to your remote server makes each history move forward differently. + +To synchronize your work, you run a `git fetch origin` command. This command looks up which server origin is (in this case, it’s `git.ourcompany.com`), fetches any data from it that you don’t yet have, and updates your local database, moving your `origin/master` pointer to its new, more up-to-date position (see Figure 3-24). + +Insert 18333fig0324.png +Figure 3-24. The git fetch command updates your remote references. + +To demonstrate having multiple remote servers and what remote branches for those remote projects look like, let’s assume you have another internal Git server that is used only for development by one of your sprint teams. This server is at `git.team1.ourcompany.com`. You can add it as a new remote reference to the project you’re currently working on by running the `git remote add` command as we covered in Chapter 2. Name this remote `teamone`, which will be your shortname for that whole URL (see Figure 3-25). + +Insert 18333fig0325.png +Figure 3-25. Adding another server as a remote. + +Now, you can run `git fetch teamone` to fetch everything the remote `teamone` server has that you don’t have yet. Because that server has a subset of the data your `origin` server has right now, Git fetches no data but sets a remote branch called `teamone/master` to point to the commit that `teamone` has as its `master` branch (see Figure 3-26). + +Insert 18333fig0326.png +Figure 3-26. You get a reference to teamone’s master branch position locally. + +### Pushing ### + +When you want to share a branch with the world, you need to push it up to a remote that you have write access to. Your local branches aren’t automatically synchronized to the remotes you write to — you have to explicitly push the branches you want to share. That way, you can use private branches for work you don’t want to share, and push up only the topic branches you want to collaborate on. + +If you have a branch named `serverfix` that you want to work on with others, you can push it up the same way you pushed your first branch. Run `git push (remote) (branch)`: + + $ git push origin serverfix + Counting objects: 20, done. + Compressing objects: 100% (14/14), done. + Writing objects: 100% (15/15), 1.74 KiB, done. + Total 15 (delta 5), reused 0 (delta 0) + To git@github.com:schacon/simplegit.git + * [new branch] serverfix -> serverfix + +This is a bit of a shortcut. Git automatically expands the `serverfix` branchname out to `refs/heads/serverfix:refs/heads/serverfix`, which means, “Take my serverfix local branch and push it to update the remote’s serverfix branch.” We’ll go over the `refs/heads/` part in detail in Chapter 9, but you can generally leave it off. You can also do `git push origin serverfix:serverfix`, which does the same thing — it says, “Take my serverfix and make it the remote’s serverfix.” You can use this format to push a local branch into a remote branch that is named differently. If you didn’t want it to be called `serverfix` on the remote, you could instead run `git push origin serverfix:awesomebranch` to push your local `serverfix` branch to the `awesomebranch` branch on the remote project. + +The next time one of your collaborators fetches from the server, they will get a reference to where the server’s version of `serverfix` is under the remote branch `origin/serverfix`: + + $ git fetch origin + remote: Counting objects: 20, done. + remote: Compressing objects: 100% (14/14), done. + remote: Total 15 (delta 5), reused 0 (delta 0) + Unpacking objects: 100% (15/15), done. + From git@github.com:schacon/simplegit + * [new branch] serverfix -> origin/serverfix + +It’s important to note that when you do a fetch that brings down new remote branches, you don’t automatically have local, editable copies of them. In other words, in this case, you don’t have a new `serverfix` branch — you only have an `origin/serverfix` pointer that you can’t modify. + +To merge this work into your current working branch, you can run `git merge origin/serverfix`. If you want your own `serverfix` branch that you can work on, you can base it off your remote branch: + + $ git checkout -b serverfix origin/serverfix + Branch serverfix set up to track remote branch refs/remotes/origin/serverfix. + Switched to a new branch "serverfix" + +This gives you a local branch that you can work on that starts where `origin/serverfix` is. + +### Tracking Branches ### + +Checking out a local branch from a remote branch automatically creates what is called a _tracking branch_. Tracking branches are local branches that have a direct relationship to a remote branch. If you’re on a tracking branch and type `git push`, Git automatically knows which server and branch to push to. Also, running `git pull` while on one of these branches fetches all the remote references and then automatically merges in the corresponding remote branch. + +When you clone a repository, it generally automatically creates a `master` branch that tracks `origin/master`. That’s why `git push` and `git pull` work out of the box with no other arguments. However, you can set up other tracking branches if you wish — ones that don’t track branches on `origin` and don’t track the `master` branch. The simple case is the example you just saw, running `git checkout -b [branch] [remotename]/[branch]`. If you have Git version 1.6.2 or later, you can also use the `--track` shorthand: + + $ git checkout --track origin/serverfix + Branch serverfix set up to track remote branch refs/remotes/origin/serverfix. + Switched to a new branch "serverfix" + +To set up a local branch with a different name than the remote branch, you can easily use the first version with a different local branch name: + + $ git checkout -b sf origin/serverfix + Branch sf set up to track remote branch refs/remotes/origin/serverfix. + Switched to a new branch "sf" + +Now, your local branch sf will automatically push to and pull from origin/serverfix. + +### Deleting Remote Branches ### + +Suppose you’re done with a remote branch — say, you and your collaborators are finished with a feature and have merged it into your remote’s `master` branch (or whatever branch your stable codeline is in). You can delete a remote branch using the rather obtuse syntax `git push [remotename] :[branch]`. If you want to delete your `serverfix` branch from the server, you run the following: + + $ git push origin :serverfix + To git@github.com:schacon/simplegit.git + - [deleted] serverfix + +Boom. No more branch on your server. You may want to dog-ear this page, because you’ll need that command, and you’ll likely forget the syntax. A way to remember this command is by recalling the `git push [remotename] [localbranch]:[remotebranch]` syntax that we went over a bit earlier. If you leave off the `[localbranch]` portion, then you’re basically saying, “Take nothing on my side and make it be `[remotebranch]`.” + +## Rebasing ## + +In Git, there are two main ways to integrate changes from one branch into another: the `merge` and the `rebase`. In this section you’ll learn what rebasing is, how to do it, why it’s a pretty amazing tool, and in what cases you won’t want to use it. + +### The Basic Rebase ### + +If you go back to an earlier example from the Merge section (see Figure 3-27), you can see that you diverged your work and made commits on two different branches. + +Insert 18333fig0327.png +Figure 3-27. Your initial diverged commit history. + +The easiest way to integrate the branches, as we’ve already covered, is the `merge` command. It performs a three-way merge between the two latest branch snapshots (C3 and C4) and the most recent common ancestor of the two (C2), creating a new snapshot (and commit), as shown in Figure 3-28. + +Insert 18333fig0328.png +Figure 3-28. Merging a branch to integrate the diverged work history. + +However, there is another way: you can take the patch of the change that was introduced in C3 and reapply it on top of C4. In Git, this is called _rebasing_. With the `rebase` command, you can take all the changes that were committed on one branch and replay them on another one. + +In this example, you’d run the following: + + $ git checkout experiment + $ git rebase master + First, rewinding head to replay your work on top of it... + Applying: added staged command + +It works by going to the common ancestor of the two branches (the one you’re on and the one you’re rebasing onto), getting the diff introduced by each commit of the branch you’re on, saving those diffs to temporary files, resetting the current branch to the same commit as the branch you are rebasing onto, and finally applying each change in turn. Figure 3-29 illustrates this process. + +Insert 18333fig0329.png +Figure 3-29. Rebasing the change introduced in C3 onto C4. + +At this point, you can go back to the master branch and do a fast-forward merge (see Figure 3-30). + +Insert 18333fig0330.png +Figure 3-30. Fast-forwarding the master branch. + +Now, the snapshot pointed to by C3' is exactly the same as the one that was pointed to by C5 in the merge example. There is no difference in the end product of the integration, but rebasing makes for a cleaner history. If you examine the log of a rebased branch, it looks like a linear history: it appears that all the work happened in series, even when it originally happened in parallel. + +Often, you’ll do this to make sure your commits apply cleanly on a remote branch — perhaps in a project to which you’re trying to contribute but that you don’t maintain. In this case, you’d do your work in a branch and then rebase your work onto `origin/master` when you were ready to submit your patches to the main project. That way, the maintainer doesn’t have to do any integration work — just a fast-forward or a clean apply. + +Note that the snapshot pointed to by the final commit you end up with, whether it’s the last of the rebased commits for a rebase or the final merge commit after a merge, is the same snapshot — it’s only the history that is different. Rebasing replays changes from one line of work onto another in the order they were introduced, whereas merging takes the endpoints and merges them together. + +### More Interesting Rebases ### + +You can also have your rebase replay on something other than the rebase branch. Take a history like Figure 3-31, for example. You branched a topic branch (`server`) to add some server-side functionality to your project, and made a commit. Then, you branched off that to make the client-side changes (`client`) and committed a few times. Finally, you went back to your server branch and did a few more commits. + +Insert 18333fig0331.png +Figure 3-31. A history with a topic branch off another topic branch. + +Suppose you decide that you want to merge your client-side changes into your mainline for a release, but you want to hold off on the server-side changes until it’s tested further. You can take the changes on client that aren’t on server (C8 and C9) and replay them on your master branch by using the `--onto` option of `git rebase`: + + $ git rebase --onto master server client + +This basically says, “Check out the client branch, figure out the patches from the common ancestor of the `client` and `server` branches, and then replay them onto `master`.” It’s a bit complex; but the result, shown in Figure 3-32, is pretty cool. + +Insert 18333fig0332.png +Figure 3-32. Rebasing a topic branch off another topic branch. + +Now you can fast-forward your master branch (see Figure 3-33): + + $ git checkout master + $ git merge client + +Insert 18333fig0333.png +Figure 3-33. Fast-forwarding your master branch to include the client branch changes. + +Let’s say you decide to pull in your server branch as well. You can rebase the server branch onto the master branch without having to check it out first by running `git rebase [basebranch] [topicbranch]` — which checks out the topic branch (in this case, `server`) for you and replays it onto the base branch (`master`): + + $ git rebase master server + +This replays your `server` work on top of your `master` work, as shown in Figure 3-34. + +Insert 18333fig0334.png +Figure 3-34. Rebasing your server branch on top of your master branch. + +Then, you can fast-forward the base branch (`master`): + + $ git checkout master + $ git merge server + +You can remove the `client` and `server` branches because all the work is integrated and you don’t need them anymore, leaving your history for this entire process looking like Figure 3-35: + + $ git branch -d client + $ git branch -d server + +Insert 18333fig0335.png +Figure 3-35. Final commit history. + +### The Perils of Rebasing ### + +Ahh, but the bliss of rebasing isn’t without its drawbacks, which can be summed up in a single line: + +**Do not rebase commits that you have pushed to a public repository.** + +If you follow that guideline, you’ll be fine. If you don’t, people will hate you, and you’ll be scorned by friends and family. + +When you rebase stuff, you’re abandoning existing commits and creating new ones that are similar but different. If you push commits somewhere and others pull them down and base work on them, and then you rewrite those commits with `git rebase` and push them up again, your collaborators will have to re-merge their work and things will get messy when you try to pull their work back into yours. + +Let’s look at an example of how rebasing work that you’ve made public can cause problems. Suppose you clone from a central server and then do some work off that. Your commit history looks like Figure 3-36. + +Insert 18333fig0336.png +Figure 3-36. Clone a repository, and base some work on it. + +Now, someone else does more work that includes a merge, and pushes that work to the central server. You fetch them and merge the new remote branch into your work, making your history look something like Figure 3-37. + +Insert 18333fig0337.png +Figure 3-37. Fetch more commits, and merge them into your work. + +Next, the person who pushed the merged work decides to go back and rebase their work instead; they do a `git push --force` to overwrite the history on the server. You then fetch from that server, bringing down the new commits. + +Insert 18333fig0338.png +Figure 3-38. Someone pushes rebased commits, abandoning commits you’ve based your work on. + +At this point, you have to merge this work in again, even though you’ve already done so. Rebasing changes the SHA-1 hashes of these commits so to Git they look like new commits, when in fact you already have the C4 work in your history (see Figure 3-39). + +Insert 18333fig0339.png +Figure 3-39. You merge in the same work again into a new merge commit. + +You have to merge that work in at some point so you can keep up with the other developer in the future. After you do that, your commit history will contain both the C4 and C4' commits, which have different SHA-1 hashes but introduce the same work and have the same commit message. If you run a `git log` when your history looks like this, you’ll see two commits that have the same author date and message, which will be confusing. Furthermore, if you push this history back up to the server, you’ll reintroduce all those rebased commits to the central server, which can further confuse people. + +If you treat rebasing as a way to clean up and work with commits before you push them, and if you only rebase commits that have never been available publicly, then you’ll be fine. If you rebase commits that have already been pushed publicly, and people may have based work on those commits, then you may be in for some frustrating trouble. + +## Summary ## + +We’ve covered basic branching and merging in Git. You should feel comfortable creating and switching to new branches, switching between branches and merging local branches together. You should also be able to share your branches by pushing them to a shared server, working with others on shared branches and rebasing your branches before they are shared. diff --git a/vi/04-git-server/01-chapter4.markdown b/vi/04-git-server/01-chapter4.markdown new file mode 100644 index 000000000..af7665115 --- /dev/null +++ b/vi/04-git-server/01-chapter4.markdown @@ -0,0 +1,859 @@ +# Git on the Server # + +At this point, you should be able to do most of the day-to-day tasks for which you’ll be using Git. However, in order to do any collaboration in Git, you’ll need to have a remote Git repository. Although you can technically push changes to and pull changes from individuals’ repositories, doing so is discouraged because you can fairly easily confuse what they’re working on if you’re not careful. Furthermore, you want your collaborators to be able to access the repository even if your computer is offline — having a more reliable common repository is often useful. Therefore, the preferred method for collaborating with someone is to set up an intermediate repository that you both have access to, and push to and pull from that. We’ll refer to this repository as a "Git server"; but you’ll notice that it generally takes a tiny amount of resources to host a Git repository, so you’ll rarely need to use an entire server for it. + +Running a Git server is simple. First, you choose which protocols you want your server to communicate with. The first section of this chapter will cover the available protocols and the pros and cons of each. The next sections will explain some typical setups using those protocols and how to get your server running with them. Last, we’ll go over a few hosted options, if you don’t mind hosting your code on someone else’s server and don’t want to go through the hassle of setting up and maintaining your own server. + +If you have no interest in running your own server, you can skip to the last section of the chapter to see some options for setting up a hosted account and then move on to the next chapter, where we discuss the various ins and outs of working in a distributed source control environment. + +A remote repository is generally a _bare repository_ — a Git repository that has no working directory. Because the repository is only used as a collaboration point, there is no reason to have a snapshot checked out on disk; it’s just the Git data. In the simplest terms, a bare repository is the contents of your project’s `.git` directory and nothing else. + +## The Protocols ## + +Git can use four major network protocols to transfer data: Local, Secure Shell (SSH), Git, and HTTP. Here we’ll discuss what they are and in what basic circumstances you would want (or not want) to use them. + +It’s important to note that with the exception of the HTTP protocols, all of these require Git to be installed and working on the server. + +### Local Protocol ### + +The most basic is the _Local protocol_, in which the remote repository is in another directory on disk. This is often used if everyone on your team has access to a shared filesystem such as an NFS mount, or in the less likely case that everyone logs in to the same computer. The latter wouldn’t be ideal, because all your code repository instances would reside on the same computer, making a catastrophic loss much more likely. + +If you have a shared mounted filesystem, then you can clone, push to, and pull from a local file-based repository. To clone a repository like this or to add one as a remote to an existing project, use the path to the repository as the URL. For example, to clone a local repository, you can run something like this: + + $ git clone /opt/git/project.git + +Or you can do this: + + $ git clone file:///opt/git/project.git + +Git operates slightly differently if you explicitly specify `file://` at the beginning of the URL. If you just specify the path, Git tries to use hardlinks or directly copy the files it needs. If you specify `file://`, Git fires up the processes that it normally uses to transfer data over a network which is generally a lot less efficient method of transferring the data. The main reason to specify the `file://` prefix is if you want a clean copy of the repository with extraneous references or objects left out — generally after an import from another version-control system or something similar (see Chapter 9 for maintenance tasks). We’ll use the normal path here because doing so is almost always faster. + +To add a local repository to an existing Git project, you can run something like this: + + $ git remote add local_proj /opt/git/project.git + +Then, you can push to and pull from that remote as though you were doing so over a network. + +#### The Pros #### + +The pros of file-based repositories are that they’re simple and they use existing file permissions and network access. If you already have a shared filesystem to which your whole team has access, setting up a repository is very easy. You stick the bare repository copy somewhere everyone has shared access to and set the read/write permissions as you would for any other shared directory. We’ll discuss how to export a bare repository copy for this purpose in the next section, “Getting Git on a Server.” + +This is also a nice option for quickly grabbing work from someone else’s working repository. If you and a co-worker are working on the same project and they want you to check something out, running a command like `git pull /home/john/project` is often easier than them pushing to a remote server and you pulling down. + +#### The Cons #### + +The cons of this method are that shared access is generally more difficult to set up and reach from multiple locations than basic network access. If you want to push from your laptop when you’re at home, you have to mount the remote disk, which can be difficult and slow compared to network-based access. + +It’s also important to mention that this isn’t necessarily the fastest option if you’re using a shared mount of some kind. A local repository is fast only if you have fast access to the data. A repository on NFS is often slower than the repository over SSH on the same server, allowing Git to run off local disks on each system. + +### The SSH Protocol ### + +Probably the most common transport protocol for Git is SSH. This is because SSH access to servers is already set up in most places — and if it isn’t, it’s easy to do. SSH is also the only network-based protocol that you can easily read from and write to. The other two network protocols (HTTP and Git) are generally read-only, so even if you have them available for the unwashed masses, you still need SSH for your own write commands. SSH is also an authenticated network protocol; and because it’s ubiquitous, it’s generally easy to set up and use. + +To clone a Git repository over SSH, you can specify ssh:// URL like this: + + $ git clone ssh://user@server/project.git + +Or you can use the shorter scp-like syntax for SSH protocol: + + $ git clone user@server:project.git + +You can also not specify a user, and Git assumes the user you’re currently logged in as. + +#### The Pros #### + +The pros of using SSH are many. First, you basically have to use it if you want authenticated write access to your repository over a network. Second, SSH is relatively easy to set up — SSH daemons are commonplace, many network admins have experience with them, and many OS distributions are set up with them or have tools to manage them. Next, access over SSH is secure — all data transfer is encrypted and authenticated. Last, like the Git and Local protocols, SSH is efficient, making the data as compact as possible before transferring it. + +#### The Cons #### + +The negative aspect of SSH is that you can’t serve anonymous access of your repository over it. People must have access to your machine over SSH to access it, even in a read-only capacity, which doesn’t make SSH access conducive to open source projects. If you’re using it only within your corporate network, SSH may be the only protocol you need to deal with. If you want to allow anonymous read-only access to your projects, you’ll have to set up SSH for you to push over but something else for others to pull over. + +### The Git Protocol ### + +Next is the Git protocol. This is a special daemon that comes packaged with Git; it listens on a dedicated port (9418) that provides a service similar to the SSH protocol, but with absolutely no authentication. In order for a repository to be served over the Git protocol, you must create the `git-export-daemon-ok` file — the daemon won’t serve a repository without that file in it — but other than that there is no security. Either the Git repository is available for everyone to clone or it isn’t. This means that there is generally no pushing over this protocol. You can enable push access; but given the lack of authentication, if you turn on push access, anyone on the internet who finds your project’s URL could push to your project. Suffice it to say that this is rare. + +#### The Pros #### + +The Git protocol is the fastest transfer protocol available. If you’re serving a lot of traffic for a public project or serving a very large project that doesn’t require user authentication for read access, it’s likely that you’ll want to set up a Git daemon to serve your project. It uses the same data-transfer mechanism as the SSH protocol but without the encryption and authentication overhead. + +#### The Cons #### + +The downside of the Git protocol is the lack of authentication. It’s generally undesirable for the Git protocol to be the only access to your project. Generally, you’ll pair it with SSH access for the few developers who have push (write) access and have everyone else use `git://` for read-only access. +It’s also probably the most difficult protocol to set up. It must run its own daemon, which is custom — we’ll look at setting one up in the “Gitosis” section of this chapter — it requires `xinetd` configuration or the like, which isn’t always a walk in the park. It also requires firewall access to port 9418, which isn’t a standard port that corporate firewalls always allow. Behind big corporate firewalls, this obscure port is commonly blocked. + +### The HTTP/S Protocol ### + +Last we have the HTTP protocol. The beauty of the HTTP or HTTPS protocol is the simplicity of setting it up. Basically, all you have to do is put the bare Git repository under your HTTP document root and set up a specific `post-update` hook, and you’re done (See Chapter 7 for details on Git hooks). At that point, anyone who can access the web server under which you put the repository can also clone your repository. To allow read access to your repository over HTTP, do something like this: + + $ cd /var/www/htdocs/ + $ git clone --bare /path/to/git_project gitproject.git + $ cd gitproject.git + $ mv hooks/post-update.sample hooks/post-update + $ chmod a+x hooks/post-update + +That’s all. The `post-update` hook that comes with Git by default runs the appropriate command (`git update-server-info`) to make HTTP fetching and cloning work properly. This command is run when you push to this repository over SSH; then, other people can clone via something like + + $ git clone http://example.com/gitproject.git + +In this particular case, we’re using the `/var/www/htdocs` path that is common for Apache setups, but you can use any static web server — just put the bare repository in its path. The Git data is served as basic static files (see Chapter 9 for details about exactly how it’s served). + +It’s possible to make Git push over HTTP as well, although that technique isn’t as widely used and requires you to set up complex WebDAV requirements. Because it’s rarely used, we won’t cover it in this book. If you’re interested in using the HTTP-push protocols, you can read about preparing a repository for this purpose at `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt`. One nice thing about making Git push over HTTP is that you can use any WebDAV server, without specific Git features; so, you can use this functionality if your web-hosting provider supports WebDAV for writing updates to your web site. + +#### The Pros #### + +The upside of using the HTTP protocol is that it’s easy to set up. Running the handful of required commands gives you a simple way to give the world read access to your Git repository. It takes only a few minutes to do. The HTTP protocol also isn’t very resource intensive on your server. Because it generally uses a static HTTP server to serve all the data, a normal Apache server can serve thousands of files per second on average — it’s difficult to overload even a small server. + +You can also serve your repositories read-only over HTTPS, which means you can encrypt the content transfer; or you can go so far as to make the clients use specific signed SSL certificates. Generally, if you’re going to these lengths, it’s easier to use SSH public keys; but it may be a better solution in your specific case to use signed SSL certificates or other HTTP-based authentication methods for read-only access over HTTPS. + +Another nice thing is that HTTP is such a commonly used protocol that corporate firewalls are often set up to allow traffic through this port. + +#### The Cons #### + +The downside of serving your repository over HTTP is that it’s relatively inefficient for the client. It generally takes a lot longer to clone or fetch from the repository, and you often have a lot more network overhead and transfer volume over HTTP than with any of the other network protocols. Because it’s not as intelligent about transferring only the data you need — there is no dynamic work on the part of the server in these transactions — the HTTP protocol is often referred to as a _dumb_ protocol. For more information about the differences in efficiency between the HTTP protocol and the other protocols, see Chapter 9. + +## Getting Git on a Server ## + +In order to initially set up any Git server, you have to export an existing repository into a new bare repository — a repository that doesn’t contain a working directory. This is generally straightforward to do. +In order to clone your repository to create a new bare repository, you run the clone command with the `--bare` option. By convention, bare repository directories end in `.git`, like so: + + $ git clone --bare my_project my_project.git + Initialized empty Git repository in /opt/projects/my_project.git/ + +The output for this command is a little confusing. Since `clone` is basically a `git init` then a `git fetch`, we see some output from the `git init` part, which creates an empty directory. The actual object transfer gives no output, but it does happen. You should now have a copy of the Git directory data in your `my_project.git` directory. + +This is roughly equivalent to something like + + $ cp -Rf my_project/.git my_project.git + +There are a couple of minor differences in the configuration file; but for your purpose, this is close to the same thing. It takes the Git repository by itself, without a working directory, and creates a directory specifically for it alone. + +### Putting the Bare Repository on a Server ### + +Now that you have a bare copy of your repository, all you need to do is put it on a server and set up your protocols. Let’s say you’ve set up a server called `git.example.com` that you have SSH access to, and you want to store all your Git repositories under the `/opt/git` directory. You can set up your new repository by copying your bare repository over: + + $ scp -r my_project.git user@git.example.com:/opt/git + +At this point, other users who have SSH access to the same server which has read-access to the `/opt/git` directory can clone your repository by running + + $ git clone user@git.example.com:/opt/git/my_project.git + +If a user SSHs into a server and has write access to the `/opt/git/my_project.git` directory, they will also automatically have push access. Git will automatically add group write permissions to a repository properly if you run the `git init` command with the `--shared` option. + + $ ssh user@git.example.com + $ cd /opt/git/my_project.git + $ git init --bare --shared + +You see how easy it is to take a Git repository, create a bare version, and place it on a server to which you and your collaborators have SSH access. Now you’re ready to collaborate on the same project. + +It’s important to note that this is literally all you need to do to run a useful Git server to which several people have access — just add SSH-able accounts on a server, and stick a bare repository somewhere that all those users have read and write access to. You’re ready to go — nothing else needed. + +In the next few sections, you’ll see how to expand to more sophisticated setups. This discussion will include not having to create user accounts for each user, adding public read access to repositories, setting up web UIs, using the Gitosis tool, and more. However, keep in mind that to collaborate with a couple of people on a private project, all you _need_ is an SSH server and a bare repository. + +### Small Setups ### + +If you’re a small outfit or are just trying out Git in your organization and have only a few developers, things can be simple for you. One of the most complicated aspects of setting up a Git server is user management. If you want some repositories to be read-only to certain users and read/write to others, access and permissions can be a bit difficult to arrange. + +#### SSH Access #### + +If you already have a server to which all your developers have SSH access, it’s generally easiest to set up your first repository there, because you have to do almost no work (as we covered in the last section). If you want more complex access control type permissions on your repositories, you can handle them with the normal filesystem permissions of the operating system your server runs. + +If you want to place your repositories on a server that doesn’t have accounts for everyone on your team whom you want to have write access, then you must set up SSH access for them. We assume that if you have a server with which to do this, you already have an SSH server installed, and that’s how you’re accessing the server. + +There are a few ways you can give access to everyone on your team. The first is to set up accounts for everybody, which is straightforward but can be cumbersome. You may not want to run `adduser` and set temporary passwords for every user. + +A second method is to create a single 'git' user on the machine, ask every user who is to have write access to send you an SSH public key, and add that key to the `~/.ssh/authorized_keys` file of your new 'git' user. At that point, everyone will be able to access that machine via the 'git' user. This doesn’t affect the commit data in any way — the SSH user you connect as doesn’t affect the commits you’ve recorded. + +Another way to do it is to have your SSH server authenticate from an LDAP server or some other centralized authentication source that you may already have set up. As long as each user can get shell access on the machine, any SSH authentication mechanism you can think of should work. + +## Generating Your SSH Public Key ## + +That being said, many Git servers authenticate using SSH public keys. In order to provide a public key, each user in your system must generate one if they don’t already have one. This process is similar across all operating systems. +First, you should check to make sure you don’t already have a key. By default, a user’s SSH keys are stored in that user’s `~/.ssh` directory. You can easily check to see if you have a key already by going to that directory and listing the contents: + + $ cd ~/.ssh + $ ls + authorized_keys2 id_dsa known_hosts + config id_dsa.pub + +You’re looking for a pair of files named something and something.pub, where the something is usually `id_dsa` or `id_rsa`. The `.pub` file is your public key, and the other file is your private key. If you don’t have these files (or you don’t even have a `.ssh` directory), you can create them by running a program called `ssh-keygen`, which is provided with the SSH package on Linux/Mac systems and comes with the MSysGit package on Windows: + + $ ssh-keygen + Generating public/private rsa key pair. + Enter file in which to save the key (/Users/schacon/.ssh/id_rsa): + Enter passphrase (empty for no passphrase): + Enter same passphrase again: + Your identification has been saved in /Users/schacon/.ssh/id_rsa. + Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub. + The key fingerprint is: + 43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local + +First it confirms where you want to save the key (`.ssh/id_rsa`), and then it asks twice for a passphrase, which you can leave empty if you don’t want to type a password when you use the key. + +Now, each user that does this has to send their public key to you or whoever is administrating the Git server (assuming you’re using an SSH server setup that requires public keys). All they have to do is copy the contents of the `.pub` file and e-mail it. The public keys look something like this: + + $ cat ~/.ssh/id_rsa.pub + ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU + GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3 + Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA + t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En + mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx + NrRFi9wrf+M7Q== schacon@agadorlaptop.local + +For a more in-depth tutorial on creating an SSH key on multiple operating systems, see the GitHub guide on SSH keys at `http://github.com/guides/providing-your-ssh-key`. + +## Setting Up the Server ## + +Let’s walk through setting up SSH access on the server side. In this example, you’ll use the `authorized_keys` method for authenticating your users. We also assume you’re running a standard Linux distribution like Ubuntu. First, you create a 'git' user and a `.ssh` directory for that user. + + $ sudo adduser git + $ su git + $ cd + $ mkdir .ssh + +Next, you need to add some developer SSH public keys to the `authorized_keys` file for that user. Let’s assume you’ve received a few keys by e-mail and saved them to temporary files. Again, the public keys look something like this: + + $ cat /tmp/id_rsa.john.pub + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4L + ojG6rs6hPB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4k + Yjh6541NYsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9Ez + Sdfd8AcCIicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myiv + O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq + dAv8JggJICUvax2T9va5 gsg-keypair + +You just append them to your `authorized_keys` file: + + $ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys + $ cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys + $ cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys + +Now, you can set up an empty repository for them by running `git init` with the `--bare` option, which initializes the repository without a working directory: + + $ cd /opt/git + $ mkdir project.git + $ cd project.git + $ git --bare init + +Then, John, Josie, or Jessica can push the first version of their project into that repository by adding it as a remote and pushing up a branch. Note that someone must shell onto the machine and create a bare repository every time you want to add a project. Let’s use `gitserver` as the hostname of the server on which you’ve set up your 'git' user and repository. If you’re running it internally, and you set up DNS for `gitserver` to point to that server, then you can use the commands pretty much as is: + + # on Johns computer + $ cd myproject + $ git init + $ git add . + $ git commit -m 'initial commit' + $ git remote add origin git@gitserver:/opt/git/project.git + $ git push origin master + +At this point, the others can clone it down and push changes back up just as easily: + + $ git clone git@gitserver:/opt/git/project.git + $ cd project + $ vim README + $ git commit -am 'fix for the README file' + $ git push origin master + +With this method, you can quickly get a read/write Git server up and running for a handful of developers. + +As an extra precaution, you can easily restrict the 'git' user to only doing Git activities with a limited shell tool called `git-shell` that comes with Git. If you set this as your 'git' user’s login shell, then the 'git' user can’t have normal shell access to your server. To use this, specify `git-shell` instead of bash or csh for your user’s login shell. To do so, you’ll likely have to edit your `/etc/passwd` file: + + $ sudo vim /etc/passwd + +At the bottom, you should find a line that looks something like this: + + git:x:1000:1000::/home/git:/bin/sh + +Change `/bin/sh` to `/usr/bin/git-shell` (or run `which git-shell` to see where it’s installed). The line should look something like this: + + git:x:1000:1000::/home/git:/usr/bin/git-shell + +Now, the 'git' user can only use the SSH connection to push and pull Git repositories and can’t shell onto the machine. If you try, you’ll see a login rejection like this: + + $ ssh git@gitserver + fatal: What do you think I am? A shell? + Connection to gitserver closed. + +## Public Access ## + +What if you want anonymous read access to your project? Perhaps instead of hosting an internal private project, you want to host an open source project. Or maybe you have a bunch of automated build servers or continuous integration servers that change a lot, and you don’t want to have to generate SSH keys all the time — you just want to add simple anonymous read access. + +Probably the simplest way for smaller setups is to run a static web server with its document root where your Git repositories are, and then enable that `post-update` hook we mentioned in the first section of this chapter. Let’s work from the previous example. Say you have your repositories in the `/opt/git` directory, and an Apache server is running on your machine. Again, you can use any web server for this; but as an example, we’ll demonstrate some basic Apache configurations that should give you an idea of what you might need. + +First you need to enable the hook: + + $ cd project.git + $ mv hooks/post-update.sample hooks/post-update + $ chmod a+x hooks/post-update + +What does this `post-update` hook do? It looks basically like this: + + $ cat .git/hooks/post-update + #!/bin/sh + exec git-update-server-info + +This means that when you push to the server via SSH, Git will run this command to update the files needed for HTTP fetching. + +Next, you need to add a VirtualHost entry to your Apache configuration with the document root as the root directory of your Git projects. Here, we’re assuming that you have wildcard DNS set up to send `*.gitserver` to whatever box you’re using to run all this: + + + ServerName git.gitserver + DocumentRoot /opt/git + + Order allow, deny + allow from all + + + +You’ll also need to set the Unix user group of the `/opt/git` directories to `www-data` so your web server can read-access the repositories, because the Apache instance running the CGI script will (by default) be running as that user: + + $ chgrp -R www-data /opt/git + +When you restart Apache, you should be able to clone your repositories under that directory by specifying the URL for your project: + + $ git clone http://git.gitserver/project.git + +This way, you can set up HTTP-based read access to any of your projects for a fair number of users in a few minutes. Another simple option for public unauthenticated access is to start a Git daemon, although that requires you to daemonize the process - we’ll cover this option in the next section, if you prefer that route. + +## GitWeb ## + +Now that you have basic read/write and read-only access to your project, you may want to set up a simple web-based visualizer. Git comes with a CGI script called GitWeb that is commonly used for this. You can see GitWeb in use at sites like `http://git.kernel.org` (see Figure 4-1). + +Insert 18333fig0401.png +Figure 4-1. The GitWeb web-based user interface. + +If you want to check out what GitWeb would look like for your project, Git comes with a command to fire up a temporary instance if you have a lightweight server on your system like `lighttpd` or `webrick`. On Linux machines, `lighttpd` is often installed, so you may be able to get it to run by typing `git instaweb` in your project directory. If you’re running a Mac, Leopard comes preinstalled with Ruby, so `webrick` may be your best bet. To start `instaweb` with a non-lighttpd handler, you can run it with the `--httpd` option. + + $ git instaweb --httpd=webrick + [2009-02-21 10:02:21] INFO WEBrick 1.3.1 + [2009-02-21 10:02:21] INFO ruby 1.8.6 (2008-03-03) [universal-darwin9.0] + +That starts up an HTTPD server on port 1234 and then automatically starts a web browser that opens on that page. It’s pretty easy on your part. When you’re done and want to shut down the server, you can run the same command with the `--stop` option: + + $ git instaweb --httpd=webrick --stop + +If you want to run the web interface on a server all the time for your team or for an open source project you’re hosting, you’ll need to set up the CGI script to be served by your normal web server. Some Linux distributions have a `gitweb` package that you may be able to install via `apt` or `yum`, so you may want to try that first. We’ll walk though installing GitWeb manually very quickly. First, you need to get the Git source code, which GitWeb comes with, and generate the custom CGI script: + + $ git clone git://git.kernel.org/pub/scm/git/git.git + $ cd git/ + $ make GITWEB_PROJECTROOT="/opt/git" \ + prefix=/usr gitweb + $ sudo cp -Rf gitweb /var/www/ + +Notice that you have to tell the command where to find your Git repositories with the `GITWEB_PROJECTROOT` variable. Now, you need to make Apache use CGI for that script, for which you can add a VirtualHost: + + + ServerName gitserver + DocumentRoot /var/www/gitweb + + Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch + AllowOverride All + order allow,deny + Allow from all + AddHandler cgi-script cgi + DirectoryIndex gitweb.cgi + + + +Again, GitWeb can be served with any CGI capable web server; if you prefer to use something else, it shouldn’t be difficult to set up. At this point, you should be able to visit `http://gitserver/` to view your repositories online, and you can use `http://git.gitserver` to clone and fetch your repositories over HTTP. + +## Gitosis ## + +Keeping all users’ public keys in the `authorized_keys` file for access works well only for a while. When you have hundreds of users, it’s much more of a pain to manage that process. You have to shell onto the server each time, and there is no access control — everyone in the file has read and write access to every project. + +At this point, you may want to turn to a widely used software project called Gitosis. Gitosis is basically a set of scripts that help you manage the `authorized_keys` file as well as implement some simple access controls. The really interesting part is that the UI for this tool for adding people and determining access isn’t a web interface but a special Git repository. You set up the information in that project; and when you push it, Gitosis reconfigures the server based on that, which is cool. + +Installing Gitosis isn’t the simplest task ever, but it’s not too difficult. It’s easiest to use a Linux server for it — these examples use a stock Ubuntu 8.10 server. + +Gitosis requires some Python tools, so first you have to install the Python setuptools package, which Ubuntu provides as python-setuptools: + + $ apt-get install python-setuptools + +Next, you clone and install Gitosis from the project’s main site: + + $ git clone git://eagain.net/gitosis.git + $ cd gitosis + $ sudo python setup.py install + +That installs a couple of executables that Gitosis will use. Next, Gitosis wants to put its repositories under `/home/git`, which is fine. But you have already set up your repositories in `/opt/git`, so instead of reconfiguring everything, you create a symlink: + + $ ln -s /opt/git /home/git/repositories + +Gitosis is going to manage your keys for you, so you need to remove the current file, re-add the keys later, and let Gitosis control the `authorized_keys` file automatically. For now, move the `authorized_keys` file out of the way: + + $ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak + +Next you need to turn your shell back on for the 'git' user, if you changed it to the `git-shell` command. People still won’t be able to log in, but Gitosis will control that for you. So, let’s change this line in your `/etc/passwd` file + + git:x:1000:1000::/home/git:/usr/bin/git-shell + +back to this: + + git:x:1000:1000::/home/git:/bin/sh + +Now it’s time to initialize Gitosis. You do this by running the `gitosis-init` command with your personal public key. If your public key isn’t on the server, you’ll have to copy it there: + + $ sudo -H -u git gitosis-init < /tmp/id_dsa.pub + Initialized empty Git repository in /opt/git/gitosis-admin.git/ + Reinitialized existing Git repository in /opt/git/gitosis-admin.git/ + +This lets the user with that key modify the main Git repository that controls the Gitosis setup. Next, you have to manually set the execute bit on the `post-update` script for your new control repository. + + $ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update + +You’re ready to roll. If you’re set up correctly, you can try to SSH into your server as the user for which you added the public key to initialize Gitosis. You should see something like this: + + $ ssh git@gitserver + PTY allocation request failed on channel 0 + fatal: unrecognized command 'gitosis-serve schacon@quaternion' + Connection to gitserver closed. + +That means Gitosis recognized you but shut you out because you’re not trying to do any Git commands. So, let’s do an actual Git command — you’ll clone the Gitosis control repository: + + # on your local computer + $ git clone git@gitserver:gitosis-admin.git + +Now you have a directory named `gitosis-admin`, which has two major parts: + + $ cd gitosis-admin + $ find . + ./gitosis.conf + ./keydir + ./keydir/scott.pub + +The `gitosis.conf` file is the control file you use to specify users, repositories, and permissions. The `keydir` directory is where you store the public keys of all the users who have any sort of access to your repositories — one file per user. The name of the file in `keydir` (in the previous example, `scott.pub`) will be different for you — Gitosis takes that name from the description at the end of the public key that was imported with the `gitosis-init` script. + +If you look at the `gitosis.conf` file, it should only specify information about the `gitosis-admin` project that you just cloned: + + $ cat gitosis.conf + [gitosis] + + [group gitosis-admin] + writable = gitosis-admin + members = scott + +It shows you that the 'scott' user — the user with whose public key you initialized Gitosis — is the only one who has access to the `gitosis-admin` project. + +Now, let’s add a new project for you. You’ll add a new section called `mobile` where you’ll list the developers on your mobile team and projects that those developers need access to. Because 'scott' is the only user in the system right now, you’ll add him as the only member, and you’ll create a new project called `iphone_project` to start on: + + [group mobile] + writable = iphone_project + members = scott + +Whenever you make changes to the `gitosis-admin` project, you have to commit the changes and push them back up to the server in order for them to take effect: + + $ git commit -am 'add iphone_project and mobile group' + [master]: created 8962da8: "changed name" + 1 files changed, 4 insertions(+), 0 deletions(-) + $ git push + Counting objects: 5, done. + Compressing objects: 100% (2/2), done. + Writing objects: 100% (3/3), 272 bytes, done. + Total 3 (delta 1), reused 0 (delta 0) + To git@gitserver:/opt/git/gitosis-admin.git + fb27aec..8962da8 master -> master + +You can make your first push to the new `iphone_project` project by adding your server as a remote to your local version of the project and pushing. You no longer have to manually create a bare repository for new projects on the server — Gitosis creates them automatically when it sees the first push: + + $ git remote add origin git@gitserver:iphone_project.git + $ git push origin master + Initialized empty Git repository in /opt/git/iphone_project.git/ + Counting objects: 3, done. + Writing objects: 100% (3/3), 230 bytes, done. + Total 3 (delta 0), reused 0 (delta 0) + To git@gitserver:iphone_project.git + * [new branch] master -> master + +Notice that you don’t need to specify the path (in fact, doing so won’t work), just a colon and then the name of the project — Gitosis finds it for you. + +You want to work on this project with your friends, so you’ll have to re-add their public keys. But instead of appending them manually to the `~/.ssh/authorized_keys` file on your server, you’ll add them, one key per file, into the `keydir` directory. How you name the keys determines how you refer to the users in the `gitosis.conf` file. Let’s re-add the public keys for John, Josie, and Jessica: + + $ cp /tmp/id_rsa.john.pub keydir/john.pub + $ cp /tmp/id_rsa.josie.pub keydir/josie.pub + $ cp /tmp/id_rsa.jessica.pub keydir/jessica.pub + +Now you can add them all to your 'mobile' team so they have read and write access to `iphone_project`: + + [group mobile] + writable = iphone_project + members = scott john josie jessica + +After you commit and push that change, all four users will be able to read from and write to that project. + +Gitosis has simple access controls as well. If you want John to have only read access to this project, you can do this instead: + + [group mobile] + writable = iphone_project + members = scott josie jessica + + [group mobile_ro] + readonly = iphone_project + members = john + +Now John can clone the project and get updates, but Gitosis won’t allow him to push back up to the project. You can create as many of these groups as you want, each containing different users and projects. You can also specify another group as one of the members (using `@` as prefix), to inherit all of its members automatically: + + [group mobile_committers] + members = scott josie jessica + + [group mobile] + writable = iphone_project + members = @mobile_committers + + [group mobile_2] + writable = another_iphone_project + members = @mobile_committers john + +If you have any issues, it may be useful to add `loglevel=DEBUG` under the `[gitosis]` section. If you’ve lost push access by pushing a messed-up configuration, you can manually fix the file on the server under `/home/git/.gitosis.conf` — the file from which Gitosis reads its info. A push to the project takes the `gitosis.conf` file you just pushed up and sticks it there. If you edit that file manually, it remains like that until the next successful push to the `gitosis-admin` project. + +## Gitolite ## + +This section serves as a quick introduction to Gitolite, and provides basic installation and setup instructions. It cannot, however, replace the enormous amount of [documentation][gltoc] that Gitolite comes with. There may also be occasional changes to this section itself, so you may also want to look at the latest version [here][gldpg]. + +[gldpg]: http://sitaramc.github.com/gitolite/progit.html +[gltoc]: http://sitaramc.github.com/gitolite/master-toc.html + +Gitolite is an authorization layer on top of Git, relying on `sshd` or `httpd` for authentication. (Recap: authentication is identifying who the user is, authorization is deciding if he is allowed to do what he is attempting to). + +Gitolite allows you to specify permissions not just by repository, but also by branch or tag names within each repository. That is, you can specify that certain people (or groups of people) can only push certain "refs" (branches or tags) but not others. + +### Installing ### + +Installing Gitolite is very easy, even if you don’t read the extensive documentation that comes with it. You need an account on a Unix server of some kind. You do not need root access, assuming Git, Perl, and an OpenSSH compatible SSH server are already installed. In the examples below, we will use the `git` account on a host called `gitserver`. + +Gitolite is somewhat unusual as far as "server" software goes — access is via SSH, and so every userid on the server is a potential "gitolite host". We will describe the simplest install method in this article; for the other methods please see the documentation. + +To begin, create a user called `git` on your server and login to this user. Copy your SSH public key (a file called `~/.ssh/id_rsa.pub` if you did a plain `ssh-keygen` with all the defaults) from your workstation, renaming it to `.pub` (we'll use `scott.pub` in our examples). Then run these commands: + + $ git clone git://github.com/sitaramc/gitolite + $ gitolite/install -ln + # assumes $HOME/bin exists and is in your $PATH + $ gitolite setup -pk $HOME/scott.pub + +That last command creates new Git repository called `gitolite-admin` on the server. + +Finally, back on your workstation, run `git clone git@gitserver:gitolite-admin`. And you’re done! Gitolite has now been installed on the server, and you now have a brand new repository called `gitolite-admin` in your workstation. You administer your Gitolite setup by making changes to this repository and pushing. + +### Customising the Install ### + +While the default, quick, install works for most people, there are some ways to customise the install if you need to. Some changes can be made simply by editing the rc file, but if that is not sufficient, there’s documentation on customising Gitolite. + +### Config File and Access Control Rules ### + +Once the install is done, you switch to the `gitolite-admin` clone you just made on your workstation, and poke around to see what you got: + + $ cd ~/gitolite-admin/ + $ ls + conf/ keydir/ + $ find conf keydir -type f + conf/gitolite.conf + keydir/scott.pub + $ cat conf/gitolite.conf + + repo gitolite-admin + RW+ = scott + + repo testing + RW+ = @all + +Notice that "scott" (the name of the pubkey in the `gitolite setup` command you used earlier) has read-write permissions on the `gitolite-admin` repository as well as a public key file of the same name. + +Adding users is easy. To add a user called "alice", obtain her public key, name it `alice.pub`, and put it in the `keydir` directory of the clone of the `gitolite-admin` repo you just made on your workstation. Add, commit, and push the change, and the user has been added. + +The config file syntax for Gitolite is well documented, so we’ll only mention some highlights here. + +You can group users or repos for convenience. The group names are just like macros; when defining them, it doesn’t even matter whether they are projects or users; that distinction is only made when you *use* the "macro". + + @oss_repos = linux perl rakudo git gitolite + @secret_repos = fenestra pear + + @admins = scott + @interns = ashok + @engineers = sitaram dilbert wally alice + @staff = @admins @engineers @interns + +You can control permissions at the "ref" level. In the following example, interns can only push the "int" branch. Engineers can push any branch whose name starts with "eng-", and tags that start with "rc" followed by a digit. And the admins can do anything (including rewind) to any ref. + + repo @oss_repos + RW int$ = @interns + RW eng- = @engineers + RW refs/tags/rc[0-9] = @engineers + RW+ = @admins + +The expression after the `RW` or `RW+` is a regular expression (regex) that the refname (ref) being pushed is matched against. So we call it a "refex"! Of course, a refex can be far more powerful than shown here, so don’t overdo it if you’re not comfortable with Perl regexes. + +Also, as you probably guessed, Gitolite prefixes `refs/heads/` as a syntactic convenience if the refex does not begin with `refs/`. + +An important feature of the config file’s syntax is that all the rules for a repository need not be in one place. You can keep all the common stuff together, like the rules for all `oss_repos` shown above, then add specific rules for specific cases later on, like so: + + repo gitolite + RW+ = sitaram + +That rule will just get added to the ruleset for the `gitolite` repository. + +At this point you might be wondering how the access control rules are actually applied, so let’s go over that briefly. + +There are two levels of access control in Gitolite. The first is at the repository level; if you have read (or write) access to *any* ref in the repository, then you have read (or write) access to the repository. This is the only access control that Gitosis had. + +The second level, applicable only to "write" access, is by branch or tag within a repository. The username, the access being attempted (`W` or `+`), and the refname being updated are known. The access rules are checked in order of appearance in the config file, looking for a match for this combination (but remember that the refname is regex-matched, not merely string-matched). If a match is found, the push succeeds. A fallthrough results in access being denied. + +### Advanced Access Control with "deny" rules ### + +So far, we’ve only seen permissions to be one of `R`, `RW`, or `RW+`. However, Gitolite allows another permission: `-`, standing for "deny". This gives you a lot more power, at the expense of some complexity, because now fallthrough is not the *only* way for access to be denied, so the *order of the rules now matters*! + +Let us say, in the situation above, we want engineers to be able to rewind any branch *except* master and integ. Here’s how to do that: + + RW master integ = @engineers + - master integ = @engineers + RW+ = @engineers + +Again, you simply follow the rules top down until you hit a match for your access mode, or a deny. Non-rewind push to master or integ is allowed by the first rule. A rewind push to those refs does not match the first rule, drops down to the second, and is therefore denied. Any push (rewind or non-rewind) to refs other than master or integ won’t match the first two rules anyway, and the third rule allows it. + +### Restricting pushes by files changed ### + +In addition to restricting what branches a user can push changes to, you can also restrict what files they are allowed to touch. For example, perhaps the Makefile (or some other program) is really not supposed to be changed by just anyone, because a lot of things depend on it or would break if the changes are not done *just right*. You can tell Gitolite: + + repo foo + RW = @junior_devs @senior_devs + + - VREF/NAME/Makefile = @junior_devs + +User who are migrating from the older Gitolite should note that there is a significant change in behaviour with regard to this feature; please see the migration guide for details. + +### Personal Branches ### + +Gitolite also has a feature called "personal branches" (or rather, "personal branch namespace") that can be very useful in a corporate environment. + +A lot of code exchange in the Git world happens by "please pull" requests. In a corporate environment, however, unauthenticated access is a no-no, and a developer workstation cannot do authentication, so you have to push to the central server and ask someone to pull from there. + +This would normally cause the same branch name clutter as in a centralised VCS, plus setting up permissions for this becomes a chore for the admin. + +Gitolite lets you define a "personal" or "scratch" namespace prefix for each developer (for example, `refs/personal//*`); please see the documentation for details. + +### "Wildcard" repositories ### + +Gitolite allows you to specify repositories with wildcards (actually Perl regexes), like, for example `assignments/s[0-9][0-9]/a[0-9][0-9]`, to pick a random example. It also allows you to assign a new permission mode (`C`) which enables users to create repositories based on such wild cards, automatically assigns ownership to the specific user who created it, allows him/her to hand out `R` and `RW` permissions to other users to collaborate, etc. Again, please see the documentation for details. + +### Other Features ### + +We’ll round off this discussion with a sampling of other features, all of which, and many more, are described in great detail in the documentation. + +**Logging**: Gitolite logs all successful accesses. If you were somewhat relaxed about giving people rewind permissions (`RW+`) and some kid blew away `master`, the log file is a life saver, in terms of easily and quickly finding the SHA that got hosed. + +**Access rights reporting**: Another convenient feature is what happens when you try and just ssh to the server. Gitolite shows you what repos you have access to, and what that access may be. Here’s an example: + + hello scott, this is git@git running gitolite3 v3.01-18-g9609868 on git 1.7.4.4 + + R anu-wsd + R entrans + R W git-notes + R W gitolite + R W gitolite-admin + R indic_web_input + R shreelipi_converter + +**Delegation**: For really large installations, you can delegate responsibility for groups of repositories to various people and have them manage those pieces independently. This reduces the load on the main admin, and makes him less of a bottleneck. + +**Mirroring**: Gitolite can help you maintain multiple mirrors, and switch between them easily if the primary server goes down. + +## Git Daemon ## + +For public, unauthenticated read access to your projects, you’ll want to move past the HTTP protocol and start using the Git protocol. The main reason is speed. The Git protocol is far more efficient and thus faster than the HTTP protocol, so using it will save your users time. + +Again, this is for unauthenticated read-only access. If you’re running this on a server outside your firewall, it should only be used for projects that are publicly visible to the world. If the server you’re running it on is inside your firewall, you might use it for projects that a large number of people or computers (continuous integration or build servers) have read-only access to, when you don’t want to have to add an SSH key for each. + +In any case, the Git protocol is relatively easy to set up. Basically, you need to run this command in a daemonized manner: + + git daemon --reuseaddr --base-path=/opt/git/ /opt/git/ + +`--reuseaddr` allows the server to restart without waiting for old connections to time out, the `--base-path` option allows people to clone projects without specifying the entire path, and the path at the end tells the Git daemon where to look for repositories to export. If you’re running a firewall, you’ll also need to punch a hole in it at port 9418 on the box you’re setting this up on. + +You can daemonize this process a number of ways, depending on the operating system you’re running. On an Ubuntu machine, you use an Upstart script. So, in the following file + + /etc/event.d/local-git-daemon + +you put this script: + + start on startup + stop on shutdown + exec /usr/bin/git daemon \ + --user=git --group=git \ + --reuseaddr \ + --base-path=/opt/git/ \ + /opt/git/ + respawn + +For security reasons, it is strongly encouraged to have this daemon run as a user with read-only permissions to the repositories — you can easily do this by creating a new user 'git-ro' and running the daemon as them. For the sake of simplicity we’ll simply run it as the same 'git' user that Gitosis is running as. + +When you restart your machine, your Git daemon will start automatically and respawn if it goes down. To get it running without having to reboot, you can run this: + + initctl start local-git-daemon + +On other systems, you may want to use `xinetd`, a script in your `sysvinit` system, or something else — as long as you get that command daemonized and watched somehow. + +Next, you have to tell your Gitosis server which repositories to allow unauthenticated Git server-based access to. If you add a section for each repository, you can specify the ones from which you want your Git daemon to allow reading. If you want to allow Git protocol access for the `iphone_project`, you add this to the end of the `gitosis.conf` file: + + [repo iphone_project] + daemon = yes + +When that is committed and pushed up, your running daemon should start serving requests for the project to anyone who has access to port 9418 on your server. + +If you decide not to use Gitosis, but you want to set up a Git daemon, you’ll have to run this on each project you want the Git daemon to serve: + + $ cd /path/to/project.git + $ touch git-daemon-export-ok + +The presence of that file tells Git that it’s OK to serve this project without authentication. + +Gitosis can also control which projects GitWeb shows. First, you need to add something like the following to the `/etc/gitweb.conf` file: + + $projects_list = "/home/git/gitosis/projects.list"; + $projectroot = "/home/git/repositories"; + $export_ok = "git-daemon-export-ok"; + @git_base_url_list = ('git://gitserver'); + +You can control which projects GitWeb lets users browse by adding or removing a `gitweb` setting in the Gitosis configuration file. For instance, if you want the `iphone_project` to show up on GitWeb, you make the `repo` setting look like this: + + [repo iphone_project] + daemon = yes + gitweb = yes + +Now, if you commit and push the project, GitWeb will automatically start showing the `iphone_project`. + +## Hosted Git ## + +If you don’t want to go through all of the work involved in setting up your own Git server, you have several options for hosting your Git projects on an external dedicated hosting site. Doing so offers a number of advantages: a hosting site is generally quick to set up and easy to start projects on, and no server maintenance or monitoring is involved. Even if you set up and run your own server internally, you may still want to use a public hosting site for your open source code — it’s generally easier for the open source community to find and help you with. + +These days, you have a huge number of hosting options to choose from, each with different advantages and disadvantages. To see an up-to-date list, check out the following page: + + https://git.wiki.kernel.org/index.php/GitHosting + +Because we can’t cover all of them, and because I happen to work at one of them, we’ll use this section to walk through setting up an account and creating a new project at GitHub. This will give you an idea of what is involved. + +GitHub is by far the largest open source Git hosting site and it’s also one of the very few that offers both public and private hosting options so you can keep your open source and private commercial code in the same place. In fact, we used GitHub to privately collaborate on this book. + +### GitHub ### + +GitHub is slightly different than most code-hosting sites in the way that it namespaces projects. Instead of being primarily based on the project, GitHub is user centric. That means when I host my `grit` project on GitHub, you won’t find it at `github.com/grit` but instead at `github.com/schacon/grit`. There is no canonical version of any project, which allows a project to move from one user to another seamlessly if the first author abandons the project. + +GitHub is also a commercial company that charges for accounts that maintain private repositories, but anyone can quickly get a free account to host as many open source projects as they want. We’ll quickly go over how that is done. + +### Setting Up a User Account ### + +The first thing you need to do is set up a free user account. If you visit the Pricing and Signup page at `http://github.com/plans` and click the "Sign Up" button on the Free account (see Figure 4-2), you’re taken to the signup page. + +Insert 18333fig0402.png +Figure 4-2. The GitHub plan page. + +Here you must choose a username that isn’t yet taken in the system and enter an e-mail address that will be associated with the account and a password (see Figure 4-3). + +Insert 18333fig0403.png +Figure 4-3. The GitHub user signup form. + +If you have it available, this is a good time to add your public SSH key as well. We covered how to generate a new key earlier, in the "Simple Setups" section. Take the contents of the public key of that pair, and paste it into the SSH Public Key text box. Clicking the "explain ssh keys" link takes you to detailed instructions on how to do so on all major operating systems. +Clicking the "I agree, sign me up" button takes you to your new user dashboard (see Figure 4-4). + +Insert 18333fig0404.png +Figure 4-4. The GitHub user dashboard. + +Next you can create a new repository. + +### Creating a New Repository ### + +Start by clicking the "create a new one" link next to Your Repositories on the user dashboard. You’re taken to the Create a New Repository form (see Figure 4-5). + +Insert 18333fig0405.png +Figure 4-5. Creating a new repository on GitHub. + +All you really have to do is provide a project name, but you can also add a description. When that is done, click the "Create Repository" button. Now you have a new repository on GitHub (see Figure 4-6). + +Insert 18333fig0406.png +Figure 4-6. GitHub project header information. + +Since you have no code there yet, GitHub will show you instructions for how create a brand-new project, push an existing Git project up, or import a project from a public Subversion repository (see Figure 4-7). + +Insert 18333fig0407.png +Figure 4-7. Instructions for a new repository. + +These instructions are similar to what we’ve already gone over. To initialize a project if it isn’t already a Git project, you use + + $ git init + $ git add . + $ git commit -m 'initial commit' + +When you have a Git repository locally, add GitHub as a remote and push up your master branch: + + $ git remote add origin git@github.com:testinguser/iphone_project.git + $ git push origin master + +Now your project is hosted on GitHub, and you can give the URL to anyone you want to share your project with. In this case, it’s `http://github.com/testinguser/iphone_project`. You can also see from the header on each of your project’s pages that you have two Git URLs (see Figure 4-8). + +Insert 18333fig0408.png +Figure 4-8. Project header with a public URL and a private URL. + +The Public Clone URL is a public, read-only Git URL over which anyone can clone the project. Feel free to give out that URL and post it on your web site or what have you. + +The Your Clone URL is a read/write SSH-based URL that you can read or write over only if you connect with the SSH private key associated with the public key you uploaded for your user. When other users visit this project page, they won’t see that URL—only the public one. + +### Importing from Subversion ### + +If you have an existing public Subversion project that you want to import into Git, GitHub can often do that for you. At the bottom of the instructions page is a link to a Subversion import. If you click it, you see a form with information about the import process and a text box where you can paste in the URL of your public Subversion project (see Figure 4-9). + +Insert 18333fig0409.png +Figure 4-9. Subversion importing interface. + +If your project is very large, nonstandard, or private, this process probably won’t work for you. In Chapter 7, you’ll learn how to do more complicated manual project imports. + +### Adding Collaborators ### + +Let’s add the rest of the team. If John, Josie, and Jessica all sign up for accounts on GitHub, and you want to give them push access to your repository, you can add them to your project as collaborators. Doing so will allow pushes from their public keys to work. + +Click the "edit" button in the project header or the Admin tab at the top of the project to reach the Admin page of your GitHub project (see Figure 4-10). + +Insert 18333fig0410.png +Figure 4-10. GitHub administration page. + +To give another user write access to your project, click the “Add another collaborator” link. A new text box appears, into which you can type a username. As you type, a helper pops up, showing you possible username matches. When you find the correct user, click the Add button to add that user as a collaborator on your project (see Figure 4-11). + +Insert 18333fig0411.png +Figure 4-11. Adding a collaborator to your project. + +When you’re finished adding collaborators, you should see a list of them in the Repository Collaborators box (see Figure 4-12). + +Insert 18333fig0412.png +Figure 4-12. A list of collaborators on your project. + +If you need to revoke access to individuals, you can click the "revoke" link, and their push access will be removed. For future projects, you can also copy collaborator groups by copying the permissions of an existing project. + +### Your Project ### + +After you push your project up or have it imported from Subversion, you have a main project page that looks something like Figure 4-13. + +Insert 18333fig0413.png +Figure 4-13. A GitHub main project page. + +When people visit your project, they see this page. It contains tabs to different aspects of your projects. The Commits tab shows a list of commits in reverse chronological order, similar to the output of the `git log` command. The Network tab shows all the people who have forked your project and contributed back. The Downloads tab allows you to upload project binaries and link to tarballs and zipped versions of any tagged points in your project. The Wiki tab provides a wiki where you can write documentation or other information about your project. The Graphs tab has some contribution visualizations and statistics about your project. The main Source tab that you land on shows your project’s main directory listing and automatically renders the README file below it if you have one. This tab also shows a box with the latest commit information. + +### Forking Projects ### + +If you want to contribute to an existing project to which you don’t have push access, GitHub encourages forking the project. When you land on a project page that looks interesting and you want to hack on it a bit, you can click the "fork" button in the project header to have GitHub copy that project to your user so you can push to it. + +This way, projects don’t have to worry about adding users as collaborators to give them push access. People can fork a project and push to it, and the main project maintainer can pull in those changes by adding them as remotes and merging in their work. + +To fork a project, visit the project page (in this case, mojombo/chronic) and click the "fork" button in the header (see Figure 4-14). + +Insert 18333fig0414.png +Figure 4-14. Get a writable copy of any repository by clicking the "fork" button. + +After a few seconds, you’re taken to your new project page, which indicates that this project is a fork of another one (see Figure 4-15). + +Insert 18333fig0415.png +Figure 4-15. Your fork of a project. + +### GitHub Summary ### + +That’s all we’ll cover about GitHub, but it’s important to note how quickly you can do all this. You can create an account, add a new project, and push to it in a matter of minutes. If your project is open source, you also get a huge community of developers who now have visibility into your project and may well fork it and help contribute to it. At the very least, this may be a way to get up and running with Git and try it out quickly. + +## Summary ## + +You have several options to get a remote Git repository up and running so that you can collaborate with others or share your work. + +Running your own server gives you a lot of control and allows you to run the server within your own firewall, but such a server generally requires a fair amount of your time to set up and maintain. If you place your data on a hosted server, it’s easy to set up and maintain; however, you have to be able to keep your code on someone else’s servers, and some organizations don’t allow that. + +It should be fairly straightforward to determine which solution or combination of solutions is appropriate for you and your organization. diff --git a/vi/05-distributed-git/01-chapter5.markdown b/vi/05-distributed-git/01-chapter5.markdown new file mode 100644 index 000000000..6bf3e1d49 --- /dev/null +++ b/vi/05-distributed-git/01-chapter5.markdown @@ -0,0 +1,897 @@ +# Distributed Git # + +Now that you have a remote Git repository set up as a point for all the developers to share their code, and you’re familiar with basic Git commands in a local workflow, you’ll look at how to utilize some of the distributed workflows that Git affords you. + +In this chapter, you’ll see how to work with Git in a distributed environment as a contributor and an integrator. That is, you’ll learn how to contribute code successfully to a project and make it as easy on you and the project maintainer as possible, and also how to maintain a project successfully with a number of developers contributing. + +## Distributed Workflows ## + +Unlike Centralized Version Control Systems (CVCSs), the distributed nature of Git allows you to be far more flexible in how developers collaborate on projects. In centralized systems, every developer is a node working more or less equally on a central hub. In Git, however, every developer is potentially both a node and a hub — that is, every developer can both contribute code to other repositories and maintain a public repository on which others can base their work and which they can contribute to. This opens a vast range of workflow possibilities for your project and/or your team, so I’ll cover a few common paradigms that take advantage of this flexibility. I’ll go over the strengths and possible weaknesses of each design; you can choose a single one to use, or you can mix and match features from each. + +### Centralized Workflow ### + +In centralized systems, there is generally a single collaboration model—the centralized workflow. One central hub, or repository, can accept code, and everyone synchronizes their work to it. A number of developers are nodes — consumers of that hub — and synchronize to that one place (see Figure 5-1). + +Insert 18333fig0501.png +Figure 5-1. Centralized workflow. + +This means that if two developers clone from the hub and both make changes, the first developer to push their changes back up can do so with no problems. The second developer must merge in the first one’s work before pushing changes up, so as not to overwrite the first developer’s changes. This concept is true in Git as it is in Subversion (or any CVCS), and this model works perfectly in Git. + +If you have a small team or are already comfortable with a centralized workflow in your company or team, you can easily continue using that workflow with Git. Simply set up a single repository, and give everyone on your team push access; Git won’t let users overwrite each other. If one developer clones, makes changes, and then tries to push their changes while another developer has pushed in the meantime, the server will reject that developer’s changes. They will be told that they’re trying to push non-fast-forward changes and that they won’t be able to do so until they fetch and merge. +This workflow is attractive to a lot of people because it’s a paradigm that many are familiar and comfortable with. + +### Integration-Manager Workflow ### + +Because Git allows you to have multiple remote repositories, it’s possible to have a workflow where each developer has write access to their own public repository and read access to everyone else’s. This scenario often includes a canonical repository that represents the "official" project. To contribute to that project, you create your own public clone of the project and push your changes to it. Then, you can send a request to the maintainer of the main project to pull in your changes. They can add your repository as a remote, test your changes locally, merge them into their branch, and push back to their repository. The process works as follow (see Figure 5-2): + +1. The project maintainer pushes to their public repository. +2. A contributor clones that repository and makes changes. +3. The contributor pushes to their own public copy. +4. The contributor sends the maintainer an e-mail asking them to pull changes. +5. The maintainer adds the contributor’s repo as a remote and merges locally. +6. The maintainer pushes merged changes to the main repository. + +Insert 18333fig0502.png +Figure 5-2. Integration-manager workflow. + +This is a very common workflow with sites like GitHub, where it’s easy to fork a project and push your changes into your fork for everyone to see. One of the main advantages of this approach is that you can continue to work, and the maintainer of the main repository can pull in your changes at any time. Contributors don’t have to wait for the project to incorporate their changes — each party can work at their own pace. + +### Dictator and Lieutenants Workflow ### + +This is a variant of a multiple-repository workflow. It’s generally used by huge projects with hundreds of collaborators; one famous example is the Linux kernel. Various integration managers are in charge of certain parts of the repository; they’re called lieutenants. All the lieutenants have one integration manager known as the benevolent dictator. The benevolent dictator’s repository serves as the reference repository from which all the collaborators need to pull. The process works like this (see Figure 5-3): + +1. Regular developers work on their topic branch and rebase their work on top of master. The master branch is that of the dictator. +2. Lieutenants merge the developers’ topic branches into their master branch. +3. The dictator merges the lieutenants’ master branches into the dictator’s master branch. +4. The dictator pushes their master to the reference repository so the other developers can rebase on it. + +Insert 18333fig0503.png +Figure 5-3. Benevolent dictator workflow. + +This kind of workflow isn’t common but can be useful in very big projects or in highly hierarchical environments, as it allows the project leader (the dictator) to delegate much of the work and collect large subsets of code at multiple points before integrating them. + +These are some commonly used workflows that are possible with a distributed system like Git, but you can see that many variations are possible to suit your particular real-world workflow. Now that you can (I hope) determine which workflow combination may work for you, I’ll cover some more specific examples of how to accomplish the main roles that make up the different flows. + +## Contributing to a Project ## + +You know what the different workflows are, and you should have a pretty good grasp of fundamental Git usage. In this section, you’ll learn about a few common patterns for contributing to a project. + +The main difficulty with describing this process is that there are a huge number of variations on how it’s done. Because Git is very flexible, people can and do work together many ways, and it’s problematic to describe how you should contribute to a project — every project is a bit different. Some of the variables involved are active contributor size, chosen workflow, your commit access, and possibly the external contribution method. + +The first variable is active contributor size. How many users are actively contributing code to this project, and how often? In many instances, you’ll have two or three developers with a few commits a day, or possibly less for somewhat dormant projects. For really large companies or projects, the number of developers could be in the thousands, with dozens or even hundreds of patches coming in each day. This is important because with more and more developers, you run into more issues with making sure your code applies cleanly or can be easily merged. Changes you submit may be rendered obsolete or severely broken by work that is merged in while you were working or while your changes were waiting to be approved or applied. How can you keep your code consistently up to date and your patches valid? + +The next variable is the workflow in use for the project. Is it centralized, with each developer having equal write access to the main codeline? Does the project have a maintainer or integration manager who checks all the patches? Are all the patches peer-reviewed and approved? Are you involved in that process? Is a lieutenant system in place, and do you have to submit your work to them first? + +The next issue is your commit access. The workflow required in order to contribute to a project is much different if you have write access to the project than if you don’t. If you don’t have write access, how does the project prefer to accept contributed work? Does it even have a policy? How much work are you contributing at a time? How often do you contribute? + +All these questions can affect how you contribute effectively to a project and what workflows are preferred or available to you. I’ll cover aspects of each of these in a series of use cases, moving from simple to more complex; you should be able to construct the specific workflows you need in practice from these examples. + +### Commit Guidelines ### + +Before you start looking at the specific use cases, here’s a quick note about commit messages. Having a good guideline for creating commits and sticking to it makes working with Git and collaborating with others a lot easier. The Git project provides a document that lays out a number of good tips for creating commits from which to submit patches — you can read it in the Git source code in the `Documentation/SubmittingPatches` file. + +First, you don’t want to submit any whitespace errors. Git provides an easy way to check for this — before you commit, run `git diff --check`, which identifies possible whitespace errors and lists them for you. Here is an example, where I’ve replaced a red terminal color with `X`s: + + $ git diff --check + lib/simplegit.rb:5: trailing whitespace. + + @git_dir = File.expand_path(git_dir)XX + lib/simplegit.rb:7: trailing whitespace. + + XXXXXXXXXXX + lib/simplegit.rb:26: trailing whitespace. + + def command(git_cmd)XXXX + +If you run that command before committing, you can tell if you’re about to commit whitespace issues that may annoy other developers. + +Next, try to make each commit a logically separate changeset. If you can, try to make your changes digestible — don’t code for a whole weekend on five different issues and then submit them all as one massive commit on Monday. Even if you don’t commit during the weekend, use the staging area on Monday to split your work into at least one commit per issue, with a useful message per commit. If some of the changes modify the same file, try to use `git add --patch` to partially stage files (covered in detail in Chapter 6). The project snapshot at the tip of the branch is identical whether you do one commit or five, as long as all the changes are added at some point, so try to make things easier on your fellow developers when they have to review your changes. This approach also makes it easier to pull out or revert one of the changesets if you need to later. Chapter 6 describes a number of useful Git tricks for rewriting history and interactively staging files — use these tools to help craft a clean and understandable history. + +The last thing to keep in mind is the commit message. Getting in the habit of creating quality commit messages makes using and collaborating with Git a lot easier. As a general rule, your messages should start with a single line that’s no more than about 50 characters and that describes the changeset concisely, followed by a blank line, followed by a more detailed explanation. The Git project requires that the more detailed explanation include your motivation for the change and contrast its implementation with previous behavior — this is a good guideline to follow. It’s also a good idea to use the imperative present tense in these messages. In other words, use commands. Instead of "I added tests for" or "Adding tests for," use "Add tests for." +Here is a template originally written by Tim Pope at tpope.net: + + Short (50 chars or less) summary of changes + + More detailed explanatory text, if necessary. Wrap it to about 72 + characters or so. In some contexts, the first line is treated as the + subject of an email and the rest of the text as the body. The blank + line separating the summary from the body is critical (unless you omit + the body entirely); tools like rebase can get confused if you run the + two together. + + Further paragraphs come after blank lines. + + - Bullet points are okay, too + + - Typically a hyphen or asterisk is used for the bullet, preceded by a + single space, with blank lines in between, but conventions vary here + +If all your commit messages look like this, things will be a lot easier for you and the developers you work with. The Git project has well-formatted commit messages — I encourage you to run `git log --no-merges` there to see what a nicely formatted project-commit history looks like. + +In the following examples, and throughout most of this book, for the sake of brevity I don’t format messages nicely like this; instead, I use the `-m` option to `git commit`. Do as I say, not as I do. + +### Private Small Team ### + +The simplest setup you’re likely to encounter is a private project with one or two other developers. By private, I mean closed source — not read-accessible to the outside world. You and the other developers all have push access to the repository. + +In this environment, you can follow a workflow similar to what you might do when using Subversion or another centralized system. You still get the advantages of things like offline committing and vastly simpler branching and merging, but the workflow can be very similar; the main difference is that merges happen client-side rather than on the server at commit time. +Let’s see what it might look like when two developers start to work together with a shared repository. The first developer, John, clones the repository, makes a change, and commits locally. (I’m replacing the protocol messages with `...` in these examples to shorten them somewhat.) + + # John's Machine + $ git clone john@githost:simplegit.git + Initialized empty Git repository in /home/john/simplegit/.git/ + ... + $ cd simplegit/ + $ vim lib/simplegit.rb + $ git commit -am 'removed invalid default value' + [master 738ee87] removed invalid default value + 1 files changed, 1 insertions(+), 1 deletions(-) + +The second developer, Jessica, does the same thing — clones the repository and commits a change: + + # Jessica's Machine + $ git clone jessica@githost:simplegit.git + Initialized empty Git repository in /home/jessica/simplegit/.git/ + ... + $ cd simplegit/ + $ vim TODO + $ git commit -am 'add reset task' + [master fbff5bc] add reset task + 1 files changed, 1 insertions(+), 0 deletions(-) + +Now, Jessica pushes her work up to the server: + + # Jessica's Machine + $ git push origin master + ... + To jessica@githost:simplegit.git + 1edee6b..fbff5bc master -> master + +John tries to push his change up, too: + + # John's Machine + $ git push origin master + To john@githost:simplegit.git + ! [rejected] master -> master (non-fast forward) + error: failed to push some refs to 'john@githost:simplegit.git' + +John isn’t allowed to push because Jessica has pushed in the meantime. This is especially important to understand if you’re used to Subversion, because you’ll notice that the two developers didn’t edit the same file. Although Subversion automatically does such a merge on the server if different files are edited, in Git you must merge the commits locally. John has to fetch Jessica’s changes and merge them in before he will be allowed to push: + + $ git fetch origin + ... + From john@githost:simplegit + + 049d078...fbff5bc master -> origin/master + +At this point, John’s local repository looks something like Figure 5-4. + +Insert 18333fig0504.png +Figure 5-4. John’s initial repository. + +John has a reference to the changes Jessica pushed up, but he has to merge them into his own work before he is allowed to push: + + $ git merge origin/master + Merge made by recursive. + TODO | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +The merge goes smoothly — John’s commit history now looks like Figure 5-5. + +Insert 18333fig0505.png +Figure 5-5. John’s repository after merging origin/master. + +Now, John can test his code to make sure it still works properly, and then he can push his new merged work up to the server: + + $ git push origin master + ... + To john@githost:simplegit.git + fbff5bc..72bbc59 master -> master + +Finally, John’s commit history looks like Figure 5-6. + +Insert 18333fig0506.png +Figure 5-6. John’s history after pushing to the origin server. + +In the meantime, Jessica has been working on a topic branch. She’s created a topic branch called `issue54` and done three commits on that branch. She hasn’t fetched John’s changes yet, so her commit history looks like Figure 5-7. + +Insert 18333fig0507.png +Figure 5-7. Jessica’s initial commit history. + +Jessica wants to sync up with John, so she fetches: + + # Jessica's Machine + $ git fetch origin + ... + From jessica@githost:simplegit + fbff5bc..72bbc59 master -> origin/master + +That pulls down the work John has pushed up in the meantime. Jessica’s history now looks like Figure 5-8. + +Insert 18333fig0508.png +Figure 5-8. Jessica’s history after fetching John’s changes. + +Jessica thinks her topic branch is ready, but she wants to know what she has to merge her work into so that she can push. She runs `git log` to find out: + + $ git log --no-merges origin/master ^issue54 + commit 738ee872852dfaa9d6634e0dea7a324040193016 + Author: John Smith + Date: Fri May 29 16:01:27 2009 -0700 + + removed invalid default value + +Now, Jessica can merge her topic work into her master branch, merge John’s work (`origin/master`) into her `master` branch, and then push back to the server again. First, she switches back to her master branch to integrate all this work: + + $ git checkout master + Switched to branch "master" + Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. + +She can merge either `origin/master` or `issue54` first — they’re both upstream, so the order doesn’t matter. The end snapshot should be identical no matter which order she chooses; only the history will be slightly different. She chooses to merge in `issue54` first: + + $ git merge issue54 + Updating fbff5bc..4af4298 + Fast forward + README | 1 + + lib/simplegit.rb | 6 +++++- + 2 files changed, 6 insertions(+), 1 deletions(-) + +No problems occur; as you can see, it was a simple fast-forward. Now Jessica merges in John’s work (`origin/master`): + + $ git merge origin/master + Auto-merging lib/simplegit.rb + Merge made by recursive. + lib/simplegit.rb | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Everything merges cleanly, and Jessica’s history looks like Figure 5-9. + +Insert 18333fig0509.png +Figure 5-9. Jessica’s history after merging John’s changes. + +Now `origin/master` is reachable from Jessica’s `master` branch, so she should be able to successfully push (assuming John hasn’t pushed again in the meantime): + + $ git push origin master + ... + To jessica@githost:simplegit.git + 72bbc59..8059c15 master -> master + +Each developer has committed a few times and merged each other’s work successfully; see Figure 5-10. + +Insert 18333fig0510.png +Figure 5-10. Jessica’s history after pushing all changes back to the server. + +That is one of the simplest workflows. You work for a while, generally in a topic branch, and merge into your master branch when it’s ready to be integrated. When you want to share that work, you merge it into your own master branch, then fetch and merge `origin/master` if it has changed, and finally push to the `master` branch on the server. The general sequence is something like that shown in Figure 5-11. + +Insert 18333fig0511.png +Figure 5-11. General sequence of events for a simple multiple-developer Git workflow. + +### Private Managed Team ### + +In this next scenario, you’ll look at contributor roles in a larger private group. You’ll learn how to work in an environment where small groups collaborate on features and then those team-based contributions are integrated by another party. + +Let’s say that John and Jessica are working together on one feature, while Jessica and Josie are working on a second. In this case, the company is using a type of integration-manager workflow where the work of the individual groups is integrated only by certain engineers, and the `master` branch of the main repo can be updated only by those engineers. In this scenario, all work is done in team-based branches and pulled together by the integrators later. + +Let’s follow Jessica’s workflow as she works on her two features, collaborating in parallel with two different developers in this environment. Assuming she already has her repository cloned, she decides to work on `featureA` first. She creates a new branch for the feature and does some work on it there: + + # Jessica's Machine + $ git checkout -b featureA + Switched to a new branch "featureA" + $ vim lib/simplegit.rb + $ git commit -am 'add limit to log function' + [featureA 3300904] add limit to log function + 1 files changed, 1 insertions(+), 1 deletions(-) + +At this point, she needs to share her work with John, so she pushes her `featureA` branch commits up to the server. Jessica doesn’t have push access to the `master` branch — only the integrators do — so she has to push to another branch in order to collaborate with John: + + $ git push origin featureA + ... + To jessica@githost:simplegit.git + * [new branch] featureA -> featureA + +Jessica e-mails John to tell him that she’s pushed some work into a branch named `featureA` and he can look at it now. While she waits for feedback from John, Jessica decides to start working on `featureB` with Josie. To begin, she starts a new feature branch, basing it off the server’s `master` branch: + + # Jessica's Machine + $ git fetch origin + $ git checkout -b featureB origin/master + Switched to a new branch "featureB" + +Now, Jessica makes a couple of commits on the `featureB` branch: + + $ vim lib/simplegit.rb + $ git commit -am 'made the ls-tree function recursive' + [featureB e5b0fdc] made the ls-tree function recursive + 1 files changed, 1 insertions(+), 1 deletions(-) + $ vim lib/simplegit.rb + $ git commit -am 'add ls-files' + [featureB 8512791] add ls-files + 1 files changed, 5 insertions(+), 0 deletions(-) + +Jessica’s repository looks like Figure 5-12. + +Insert 18333fig0512.png +Figure 5-12. Jessica’s initial commit history. + +She’s ready to push up her work, but gets an e-mail from Josie that a branch with some initial work on it was already pushed to the server as `featureBee`. Jessica first needs to merge those changes in with her own before she can push to the server. She can then fetch Josie’s changes down with `git fetch`: + + $ git fetch origin + ... + From jessica@githost:simplegit + * [new branch] featureBee -> origin/featureBee + +Jessica can now merge this into the work she did with `git merge`: + + $ git merge origin/featureBee + Auto-merging lib/simplegit.rb + Merge made by recursive. + lib/simplegit.rb | 4 ++++ + 1 files changed, 4 insertions(+), 0 deletions(-) + +There is a bit of a problem — she needs to push the merged work in her `featureB` branch to the `featureBee` branch on the server. She can do so by specifying the local branch followed by a colon (:) followed by the remote branch to the `git push` command: + + $ git push origin featureB:featureBee + ... + To jessica@githost:simplegit.git + fba9af8..cd685d1 featureB -> featureBee + +This is called a _refspec_. See Chapter 9 for a more detailed discussion of Git refspecs and different things you can do with them. + +Next, John e-mails Jessica to say he’s pushed some changes to the `featureA` branch and ask her to verify them. She runs a `git fetch` to pull down those changes: + + $ git fetch origin + ... + From jessica@githost:simplegit + 3300904..aad881d featureA -> origin/featureA + +Then, she can see what has been changed with `git log`: + + $ git log origin/featureA ^featureA + commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6 + Author: John Smith + Date: Fri May 29 19:57:33 2009 -0700 + + changed log output to 30 from 25 + +Finally, she merges John’s work into her own `featureA` branch: + + $ git checkout featureA + Switched to branch "featureA" + $ git merge origin/featureA + Updating 3300904..aad881d + Fast forward + lib/simplegit.rb | 10 +++++++++- + 1 files changed, 9 insertions(+), 1 deletions(-) + +Jessica wants to tweak something, so she commits again and then pushes this back up to the server: + + $ git commit -am 'small tweak' + [featureA 774b3ed] small tweak + 1 files changed, 1 insertions(+), 1 deletions(-) + $ git push origin featureA + ... + To jessica@githost:simplegit.git + 3300904..774b3ed featureA -> featureA + +Jessica’s commit history now looks something like Figure 5-13. + +Insert 18333fig0513.png +Figure 5-13. Jessica’s history after committing on a feature branch. + +Jessica, Josie, and John inform the integrators that the `featureA` and `featureBee` branches on the server are ready for integration into the mainline. After they integrate these branches into the mainline, a fetch will bring down the new merge commits, making the commit history look like Figure 5-14. + +Insert 18333fig0514.png +Figure 5-14. Jessica’s history after merging both her topic branches. + +Many groups switch to Git because of this ability to have multiple teams working in parallel, merging the different lines of work late in the process. The ability of smaller subgroups of a team to collaborate via remote branches without necessarily having to involve or impede the entire team is a huge benefit of Git. The sequence for the workflow you saw here is something like Figure 5-15. + +Insert 18333fig0515.png +Figure 5-15. Basic sequence of this managed-team workflow. + +### Public Small Project ### + +Contributing to public projects is a bit different. Because you don’t have the permissions to directly update branches on the project, you have to get the work to the maintainers some other way. This first example describes contributing via forking on Git hosts that support easy forking. The repo.or.cz and GitHub hosting sites both support this, and many project maintainers expect this style of contribution. The next section deals with projects that prefer to accept contributed patches via e-mail. + +First, you’ll probably want to clone the main repository, create a topic branch for the patch or patch series you’re planning to contribute, and do your work there. The sequence looks basically like this: + + $ git clone (url) + $ cd project + $ git checkout -b featureA + $ (work) + $ git commit + $ (work) + $ git commit + +You may want to use `rebase -i` to squash your work down to a single commit, or rearrange the work in the commits to make the patch easier for the maintainer to review — see Chapter 6 for more information about interactive rebasing. + +When your branch work is finished and you’re ready to contribute it back to the maintainers, go to the original project page and click the "Fork" button, creating your own writable fork of the project. You then need to add in this new repository URL as a second remote, in this case named `myfork`: + + $ git remote add myfork (url) + +You need to push your work up to it. It’s easiest to push the remote branch you’re working on up to your repository, rather than merging into your master branch and pushing that up. The reason is that if the work isn’t accepted or is cherry picked, you don’t have to rewind your master branch. If the maintainers merge, rebase, or cherry-pick your work, you’ll eventually get it back via pulling from their repository anyhow: + + $ git push myfork featureA + +When your work has been pushed up to your fork, you need to notify the maintainer. This is often called a pull request, and you can either generate it via the website — GitHub has a "pull request" button that automatically messages the maintainer — or run the `git request-pull` command and e-mail the output to the project maintainer manually. + +The `request-pull` command takes the base branch into which you want your topic branch pulled and the Git repository URL you want them to pull from, and outputs a summary of all the changes you’re asking to be pulled in. For instance, if Jessica wants to send John a pull request, and she’s done two commits on the topic branch she just pushed up, she can run this: + + $ git request-pull origin/master myfork + The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40: + John Smith (1): + added a new function + + are available in the git repository at: + + git://githost/simplegit.git featureA + + Jessica Smith (2): + add limit to log function + change log output to 30 from 25 + + lib/simplegit.rb | 10 +++++++++- + 1 files changed, 9 insertions(+), 1 deletions(-) + +The output can be sent to the maintainer—it tells them where the work was branched from, summarizes the commits, and tells where to pull this work from. + +On a project for which you’re not the maintainer, it’s generally easier to have a branch like `master` always track `origin/master` and to do your work in topic branches that you can easily discard if they’re rejected. Having work themes isolated into topic branches also makes it easier for you to rebase your work if the tip of the main repository has moved in the meantime and your commits no longer apply cleanly. For example, if you want to submit a second topic of work to the project, don’t continue working on the topic branch you just pushed up — start over from the main repository’s `master` branch: + + $ git checkout -b featureB origin/master + $ (work) + $ git commit + $ git push myfork featureB + $ (email maintainer) + $ git fetch origin + +Now, each of your topics is contained within a silo — similar to a patch queue — that you can rewrite, rebase, and modify without the topics interfering or interdepending on each other as in Figure 5-16. + +Insert 18333fig0516.png +Figure 5-16. Initial commit history with featureB work. + +Let’s say the project maintainer has pulled in a bunch of other patches and tried your first branch, but it no longer cleanly merges. In this case, you can try to rebase that branch on top of `origin/master`, resolve the conflicts for the maintainer, and then resubmit your changes: + + $ git checkout featureA + $ git rebase origin/master + $ git push -f myfork featureA + +This rewrites your history to now look like Figure 5-17. + +Insert 18333fig0517.png +Figure 5-17. Commit history after featureA work. + +Because you rebased the branch, you have to specify the `-f` to your push command in order to be able to replace the `featureA` branch on the server with a commit that isn’t a descendant of it. An alternative would be to push this new work to a different branch on the server (perhaps called `featureAv2`). + +Let’s look at one more possible scenario: the maintainer has looked at work in your second branch and likes the concept but would like you to change an implementation detail. You’ll also take this opportunity to move the work to be based off the project’s current `master` branch. You start a new branch based off the current `origin/master` branch, squash the `featureB` changes there, resolve any conflicts, make the implementation change, and then push that up as a new branch: + + $ git checkout -b featureBv2 origin/master + $ git merge --no-commit --squash featureB + $ (change implementation) + $ git commit + $ git push myfork featureBv2 + +The `--squash` option takes all the work on the merged branch and squashes it into one non-merge commit on top of the branch you’re on. The `--no-commit` option tells Git not to automatically record a commit. This allows you to introduce all the changes from another branch and then make more changes before recording the new commit. + +Now you can send the maintainer a message that you’ve made the requested changes and they can find those changes in your `featureBv2` branch (see Figure 5-18). + +Insert 18333fig0518.png +Figure 5-18. Commit history after featureBv2 work. + +### Public Large Project ### + +Many larger projects have established procedures for accepting patches — you’ll need to check the specific rules for each project, because they will differ. However, many larger public projects accept patches via a developer mailing list, so I’ll go over an example of that now. + +The workflow is similar to the previous use case — you create topic branches for each patch series you work on. The difference is how you submit them to the project. Instead of forking the project and pushing to your own writable version, you generate e-mail versions of each commit series and e-mail them to the developer mailing list: + + $ git checkout -b topicA + $ (work) + $ git commit + $ (work) + $ git commit + +Now you have two commits that you want to send to the mailing list. You use `git format-patch` to generate the mbox-formatted files that you can e-mail to the list — it turns each commit into an e-mail message with the first line of the commit message as the subject and the rest of the message plus the patch that the commit introduces as the body. The nice thing about this is that applying a patch from an e-mail generated with `format-patch` preserves all the commit information properly, as you’ll see more of in the next section when you apply these patches: + + $ git format-patch -M origin/master + 0001-add-limit-to-log-function.patch + 0002-changed-log-output-to-30-from-25.patch + +The `format-patch` command prints out the names of the patch files it creates. The `-M` switch tells Git to look for renames. The files end up looking like this: + + $ cat 0001-add-limit-to-log-function.patch + From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 + From: Jessica Smith + Date: Sun, 6 Apr 2008 10:17:23 -0700 + Subject: [PATCH 1/2] add limit to log function + + Limit log functionality to the first 20 + + --- + lib/simplegit.rb | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + + diff --git a/lib/simplegit.rb b/lib/simplegit.rb + index 76f47bc..f9815f1 100644 + --- a/lib/simplegit.rb + +++ b/lib/simplegit.rb + @@ -14,7 +14,7 @@ class SimpleGit + end + + def log(treeish = 'master') + - command("git log #{treeish}") + + command("git log -n 20 #{treeish}") + end + + def ls_tree(treeish = 'master') + -- + 1.6.2.rc1.20.g8c5b.dirty + +You can also edit these patch files to add more information for the e-mail list that you don’t want to show up in the commit message. If you add text between the `---` line and the beginning of the patch (the `lib/simplegit.rb` line), then developers can read it; but applying the patch excludes it. + +To e-mail this to a mailing list, you can either paste the file into your e-mail program or send it via a command-line program. Pasting the text often causes formatting issues, especially with "smarter" clients that don’t preserve newlines and other whitespace appropriately. Luckily, Git provides a tool to help you send properly formatted patches via IMAP, which may be easier for you. I’ll demonstrate how to send a patch via Gmail, which happens to be the e-mail agent I use; you can read detailed instructions for a number of mail programs at the end of the aforementioned `Documentation/SubmittingPatches` file in the Git source code. + +First, you need to set up the imap section in your `~/.gitconfig` file. You can set each value separately with a series of `git config` commands, or you can add them manually; but in the end, your config file should look something like this: + + [imap] + folder = "[Gmail]/Drafts" + host = imaps://imap.gmail.com + user = user@gmail.com + pass = p4ssw0rd + port = 993 + sslverify = false + +If your IMAP server doesn’t use SSL, the last two lines probably aren’t necessary, and the host value will be `imap://` instead of `imaps://`. +When that is set up, you can use `git send-email` to place the patch series in the Drafts folder of the specified IMAP server: + + $ git send-email *.patch + 0001-added-limit-to-log-function.patch + 0002-changed-log-output-to-30-from-25.patch + Who should the emails appear to be from? [Jessica Smith ] + Emails will be sent from: Jessica Smith + Who should the emails be sent to? jessica@example.com + Message-ID to be used as In-Reply-To for the first email? y + +Then, Git spits out a bunch of log information looking something like this for each patch you’re sending: + + (mbox) Adding cc: Jessica Smith from + \line 'From: Jessica Smith ' + OK. Log says: + Sendmail: /usr/sbin/sendmail -i jessica@example.com + From: Jessica Smith + To: jessica@example.com + Subject: [PATCH 1/2] added limit to log function + Date: Sat, 30 May 2009 13:29:15 -0700 + Message-Id: <1243715356-61726-1-git-send-email-jessica@example.com> + X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty + In-Reply-To: + References: + + Result: OK + +At this point, you should be able to go to your Drafts folder, change the To field to the mailing list you’re sending the patch to, possibly CC the maintainer or person responsible for that section, and send it off. + +### Summary ### + +This section has covered a number of common workflows for dealing with several very different types of Git projects you’re likely to encounter and introduced a couple of new tools to help you manage this process. Next, you’ll see how to work the other side of the coin: maintaining a Git project. You’ll learn how to be a benevolent dictator or integration manager. + +## Maintaining a Project ## + +In addition to knowing how to effectively contribute to a project, you’ll likely need to know how to maintain one. This can consist of accepting and applying patches generated via `format-patch` and e-mailed to you, or integrating changes in remote branches for repositories you’ve added as remotes to your project. Whether you maintain a canonical repository or want to help by verifying or approving patches, you need to know how to accept work in a way that is clearest for other contributors and sustainable by you over the long run. + +### Working in Topic Branches ### + +When you’re thinking of integrating new work, it’s generally a good idea to try it out in a topic branch — a temporary branch specifically made to try out that new work. This way, it’s easy to tweak a patch individually and leave it if it’s not working until you have time to come back to it. If you create a simple branch name based on the theme of the work you’re going to try, such as `ruby_client` or something similarly descriptive, you can easily remember it if you have to abandon it for a while and come back later. The maintainer of the Git project tends to namespace these branches as well — such as `sc/ruby_client`, where `sc` is short for the person who contributed the work. +As you’ll remember, you can create the branch based off your master branch like this: + + $ git branch sc/ruby_client master + +Or, if you want to also switch to it immediately, you can use the `checkout -b` command: + + $ git checkout -b sc/ruby_client master + +Now you’re ready to add your contributed work into this topic branch and determine if you want to merge it into your longer-term branches. + +### Applying Patches from E-mail ### + +If you receive a patch over e-mail that you need to integrate into your project, you need to apply the patch in your topic branch to evaluate it. There are two ways to apply an e-mailed patch: with `git apply` or with `git am`. + +#### Applying a Patch with apply #### + +If you received the patch from someone who generated it with the `git diff` or a Unix `diff` command, you can apply it with the `git apply` command. Assuming you saved the patch at `/tmp/patch-ruby-client.patch`, you can apply the patch like this: + + $ git apply /tmp/patch-ruby-client.patch + +This modifies the files in your working directory. It’s almost identical to running a `patch -p1` command to apply the patch, although it’s more paranoid and accepts fewer fuzzy matches than patch. It also handles file adds, deletes, and renames if they’re described in the `git diff` format, which `patch` won’t do. Finally, `git apply` is an "apply all or abort all" model where either everything is applied or nothing is, whereas `patch` can partially apply patchfiles, leaving your working directory in a weird state. `git apply` is overall much more paranoid than `patch`. It won’t create a commit for you — after running it, you must stage and commit the changes introduced manually. + +You can also use git apply to see if a patch applies cleanly before you try actually applying it — you can run `git apply --check` with the patch: + + $ git apply --check 0001-seeing-if-this-helps-the-gem.patch + error: patch failed: ticgit.gemspec:1 + error: ticgit.gemspec: patch does not apply + +If there is no output, then the patch should apply cleanly. This command also exits with a non-zero status if the check fails, so you can use it in scripts if you want. + +#### Applying a Patch with am #### + +If the contributor is a Git user and was good enough to use the `format-patch` command to generate their patch, then your job is easier because the patch contains author information and a commit message for you. If you can, encourage your contributors to use `format-patch` instead of `diff` to generate patches for you. You should only have to use `git apply` for legacy patches and things like that. + +To apply a patch generated by `format-patch`, you use `git am`. Technically, `git am` is built to read an mbox file, which is a simple, plain-text format for storing one or more e-mail messages in one text file. It looks something like this: + + From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 + From: Jessica Smith + Date: Sun, 6 Apr 2008 10:17:23 -0700 + Subject: [PATCH 1/2] add limit to log function + + Limit log functionality to the first 20 + +This is the beginning of the output of the format-patch command that you saw in the previous section. This is also a valid mbox e-mail format. If someone has e-mailed you the patch properly using git send-email, and you download that into an mbox format, then you can point git am to that mbox file, and it will start applying all the patches it sees. If you run a mail client that can save several e-mails out in mbox format, you can save entire patch series into a file and then use git am to apply them one at a time. + +However, if someone uploaded a patch file generated via `format-patch` to a ticketing system or something similar, you can save the file locally and then pass that file saved on your disk to `git am` to apply it: + + $ git am 0001-limit-log-function.patch + Applying: add limit to log function + +You can see that it applied cleanly and automatically created the new commit for you. The author information is taken from the e-mail’s `From` and `Date` headers, and the message of the commit is taken from the `Subject` and body (before the patch) of the e-mail. For example, if this patch was applied from the mbox example I just showed, the commit generated would look something like this: + + $ git log --pretty=fuller -1 + commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 + Author: Jessica Smith + AuthorDate: Sun Apr 6 10:17:23 2008 -0700 + Commit: Scott Chacon + CommitDate: Thu Apr 9 09:19:06 2009 -0700 + + add limit to log function + + Limit log functionality to the first 20 + +The `Commit` information indicates the person who applied the patch and the time it was applied. The `Author` information is the individual who originally created the patch and when it was originally created. + +But it’s possible that the patch won’t apply cleanly. Perhaps your main branch has diverged too far from the branch the patch was built from, or the patch depends on another patch you haven’t applied yet. In that case, the `git am` process will fail and ask you what you want to do: + + $ git am 0001-seeing-if-this-helps-the-gem.patch + Applying: seeing if this helps the gem + error: patch failed: ticgit.gemspec:1 + error: ticgit.gemspec: patch does not apply + Patch failed at 0001. + When you have resolved this problem run "git am --resolved". + If you would prefer to skip this patch, instead run "git am --skip". + To restore the original branch and stop patching run "git am --abort". + +This command puts conflict markers in any files it has issues with, much like a conflicted merge or rebase operation. You solve this issue much the same way — edit the file to resolve the conflict, stage the new file, and then run `git am --resolved` to continue to the next patch: + + $ (fix the file) + $ git add ticgit.gemspec + $ git am --resolved + Applying: seeing if this helps the gem + +If you want Git to try a bit more intelligently to resolve the conflict, you can pass a `-3` option to it, which makes Git attempt a three-way merge. This option isn’t on by default because it doesn’t work if the commit the patch says it was based on isn’t in your repository. If you do have that commit — if the patch was based on a public commit — then the `-3` option is generally much smarter about applying a conflicting patch: + + $ git am -3 0001-seeing-if-this-helps-the-gem.patch + Applying: seeing if this helps the gem + error: patch failed: ticgit.gemspec:1 + error: ticgit.gemspec: patch does not apply + Using index info to reconstruct a base tree... + Falling back to patching base and 3-way merge... + No changes -- Patch already applied. + +In this case, I was trying to apply a patch I had already applied. Without the `-3` option, it looks like a conflict. + +If you’re applying a number of patches from an mbox, you can also run the `am` command in interactive mode, which stops at each patch it finds and asks if you want to apply it: + + $ git am -3 -i mbox + Commit Body is: + -------------------------- + seeing if this helps the gem + -------------------------- + Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all + +This is nice if you have a number of patches saved, because you can view the patch first if you don’t remember what it is, or not apply the patch if you’ve already done so. + +When all the patches for your topic are applied and committed into your branch, you can choose whether and how to integrate them into a longer-running branch. + +### Checking Out Remote Branches ### + +If your contribution came from a Git user who set up their own repository, pushed a number of changes into it, and then sent you the URL to the repository and the name of the remote branch the changes are in, you can add them as a remote and do merges locally. + +For instance, if Jessica sends you an e-mail saying that she has a great new feature in the `ruby-client` branch of her repository, you can test it by adding the remote and checking out that branch locally: + + $ git remote add jessica git://github.com/jessica/myproject.git + $ git fetch jessica + $ git checkout -b rubyclient jessica/ruby-client + +If she e-mails you again later with another branch containing another great feature, you can fetch and check out because you already have the remote setup. + +This is most useful if you’re working with a person consistently. If someone only has a single patch to contribute once in a while, then accepting it over e-mail may be less time consuming than requiring everyone to run their own server and having to continually add and remove remotes to get a few patches. You’re also unlikely to want to have hundreds of remotes, each for someone who contributes only a patch or two. However, scripts and hosted services may make this easier — it depends largely on how you develop and how your contributors develop. + +The other advantage of this approach is that you get the history of the commits as well. Although you may have legitimate merge issues, you know where in your history their work is based; a proper three-way merge is the default rather than having to supply a `-3` and hope the patch was generated off a public commit to which you have access. + +If you aren’t working with a person consistently but still want to pull from them in this way, you can provide the URL of the remote repository to the `git pull` command. This does a one-time pull and doesn’t save the URL as a remote reference: + + $ git pull git://github.com/onetimeguy/project.git + From git://github.com/onetimeguy/project + * branch HEAD -> FETCH_HEAD + Merge made by recursive. + +### Determining What Is Introduced ### + +Now you have a topic branch that contains contributed work. At this point, you can determine what you’d like to do with it. This section revisits a couple of commands so you can see how you can use them to review exactly what you’ll be introducing if you merge this into your main branch. + +It’s often helpful to get a review of all the commits that are in this branch but that aren’t in your master branch. You can exclude commits in the master branch by adding the `--not` option before the branch name. For example, if your contributor sends you two patches and you create a branch called `contrib` and applied those patches there, you can run this: + + $ git log contrib --not master + commit 5b6235bd297351589efc4d73316f0a68d484f118 + Author: Scott Chacon + Date: Fri Oct 24 09:53:59 2008 -0700 + + seeing if this helps the gem + + commit 7482e0d16d04bea79d0dba8988cc78df655f16a0 + Author: Scott Chacon + Date: Mon Oct 22 19:38:36 2008 -0700 + + updated the gemspec to hopefully work better + +To see what changes each commit introduces, remember that you can pass the `-p` option to `git log` and it will append the diff introduced to each commit. + +To see a full diff of what would happen if you were to merge this topic branch with another branch, you may have to use a weird trick to get the correct results. You may think to run this: + + $ git diff master + +This command gives you a diff, but it may be misleading. If your `master` branch has moved forward since you created the topic branch from it, then you’ll get seemingly strange results. This happens because Git directly compares the snapshots of the last commit of the topic branch you’re on and the snapshot of the last commit on the `master` branch. For example, if you’ve added a line in a file on the `master` branch, a direct comparison of the snapshots will look like the topic branch is going to remove that line. + +If `master` is a direct ancestor of your topic branch, this isn’t a problem; but if the two histories have diverged, the diff will look like you’re adding all the new stuff in your topic branch and removing everything unique to the `master` branch. + +What you really want to see are the changes added to the topic branch — the work you’ll introduce if you merge this branch with master. You do that by having Git compare the last commit on your topic branch with the first common ancestor it has with the master branch. + +Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it: + + $ git merge-base contrib master + 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 + $ git diff 36c7db + +However, that isn’t convenient, so Git provides another shorthand for doing the same thing: the triple-dot syntax. In the context of the `diff` command, you can put three periods after another branch to do a `diff` between the last commit of the branch you’re on and its common ancestor with another branch: + + $ git diff master...contrib + +This command shows you only the work your current topic branch has introduced since its common ancestor with master. That is a very useful syntax to remember. + +### Integrating Contributed Work ### + +When all the work in your topic branch is ready to be integrated into a more mainline branch, the question is how to do it. Furthermore, what overall workflow do you want to use to maintain your project? You have a number of choices, so I’ll cover a few of them. + +#### Merging Workflows #### + +One simple workflow merges your work into your `master` branch. In this scenario, you have a `master` branch that contains basically stable code. When you have work in a topic branch that you’ve done or that someone has contributed and you’ve verified, you merge it into your master branch, delete the topic branch, and then continue the process. If we have a repository with work in two branches named `ruby_client` and `php_client` that looks like Figure 5-19 and merge `ruby_client` first and then `php_client` next, then your history will end up looking like Figure 5-20. + +Insert 18333fig0519.png +Figure 5-19. History with several topic branches. + +Insert 18333fig0520.png +Figure 5-20. After a topic branch merge. + +That is probably the simplest workflow, but it’s problematic if you’re dealing with larger repositories or projects. + +If you have more developers or a larger project, you’ll probably want to use at least a two-phase merge cycle. In this scenario, you have two long-running branches, `master` and `develop`, in which you determine that `master` is updated only when a very stable release is cut and all new code is integrated into the `develop` branch. You regularly push both of these branches to the public repository. Each time you have a new topic branch to merge in (Figure 5-21), you merge it into `develop` (Figure 5-22); then, when you tag a release, you fast-forward `master` to wherever the now-stable `develop` branch is (Figure 5-23). + +Insert 18333fig0521.png +Figure 5-21. Before a topic branch merge. + +Insert 18333fig0522.png +Figure 5-22. After a topic branch merge. + +Insert 18333fig0523.png +Figure 5-23. After a topic branch release. + +This way, when people clone your project’s repository, they can either check out master to build the latest stable version and keep up to date on that easily, or they can check out develop, which is the more cutting-edge stuff. +You can also continue this concept, having an integrate branch where all the work is merged together. Then, when the codebase on that branch is stable and passes tests, you merge it into a develop branch; and when that has proven itself stable for a while, you fast-forward your master branch. + +#### Large-Merging Workflows #### + +The Git project has four long-running branches: `master`, `next`, and `pu` (proposed updates) for new work, and `maint` for maintenance backports. When new work is introduced by contributors, it’s collected into topic branches in the maintainer’s repository in a manner similar to what I’ve described (see Figure 5-24). At this point, the topics are evaluated to determine whether they’re safe and ready for consumption or whether they need more work. If they’re safe, they’re merged into `next`, and that branch is pushed up so everyone can try the topics integrated together. + +Insert 18333fig0524.png +Figure 5-24. Managing a complex series of parallel contributed topic branches. + +If the topics still need work, they’re merged into `pu` instead. When it’s determined that they’re totally stable, the topics are re-merged into `master` and are then rebuilt from the topics that were in `next` but didn’t yet graduate to `master`. This means `master` almost always moves forward, `next` is rebased occasionally, and `pu` is rebased even more often (see Figure 5-25). + +Insert 18333fig0525.png +Figure 5-25. Merging contributed topic branches into long-term integration branches. + +When a topic branch has finally been merged into `master`, it’s removed from the repository. The Git project also has a `maint` branch that is forked off from the last release to provide backported patches in case a maintenance release is required. Thus, when you clone the Git repository, you have four branches that you can check out to evaluate the project in different stages of development, depending on how cutting edge you want to be or how you want to contribute; and the maintainer has a structured workflow to help them vet new contributions. + +#### Rebasing and Cherry Picking Workflows #### + +Other maintainers prefer to rebase or cherry-pick contributed work on top of their master branch, rather than merging it in, to keep a mostly linear history. When you have work in a topic branch and have determined that you want to integrate it, you move to that branch and run the rebase command to rebuild the changes on top of your current master (or `develop`, and so on) branch. If that works well, you can fast-forward your `master` branch, and you’ll end up with a linear project history. + +The other way to move introduced work from one branch to another is to cherry-pick it. A cherry-pick in Git is like a rebase for a single commit. It takes the patch that was introduced in a commit and tries to reapply it on the branch you’re currently on. This is useful if you have a number of commits on a topic branch and you want to integrate only one of them, or if you only have one commit on a topic branch and you’d prefer to cherry-pick it rather than run rebase. For example, suppose you have a project that looks like Figure 5-26. + +Insert 18333fig0526.png +Figure 5-26. Example history before a cherry pick. + +If you want to pull commit `e43a6` into your master branch, you can run + + $ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf + Finished one cherry-pick. + [master]: created a0a41a9: "More friendly message when locking the index fails." + 3 files changed, 17 insertions(+), 3 deletions(-) + +This pulls the same change introduced in `e43a6`, but you get a new commit SHA-1 value, because the date applied is different. Now your history looks like Figure 5-27. + +Insert 18333fig0527.png +Figure 5-27. History after cherry-picking a commit on a topic branch. + +Now you can remove your topic branch and drop the commits you didn’t want to pull in. + +### Tagging Your Releases ### + +When you’ve decided to cut a release, you’ll probably want to drop a tag so you can re-create that release at any point going forward. You can create a new tag as I discussed in Chapter 2. If you decide to sign the tag as the maintainer, the tagging may look something like this: + + $ git tag -s v1.5 -m 'my signed 1.5 tag' + You need a passphrase to unlock the secret key for + user: "Scott Chacon " + 1024-bit DSA key, ID F721C45A, created 2009-02-09 + +If you do sign your tags, you may have the problem of distributing the public PGP key used to sign your tags. The maintainer of the Git project has solved this issue by including their public key as a blob in the repository and then adding a tag that points directly to that content. To do this, you can figure out which key you want by running `gpg --list-keys`: + + $ gpg --list-keys + /Users/schacon/.gnupg/pubring.gpg + --------------------------------- + pub 1024D/F721C45A 2009-02-09 [expires: 2010-02-09] + uid Scott Chacon + sub 2048g/45D02282 2009-02-09 [expires: 2010-02-09] + +Then, you can directly import the key into the Git database by exporting it and piping that through `git hash-object`, which writes a new blob with those contents into Git and gives you back the SHA-1 of the blob: + + $ gpg -a --export F721C45A | git hash-object -w --stdin + 659ef797d181633c87ec71ac3f9ba29fe5775b92 + +Now that you have the contents of your key in Git, you can create a tag that points directly to it by specifying the new SHA-1 value that the `hash-object` command gave you: + + $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92 + +If you run `git push --tags`, the `maintainer-pgp-pub` tag will be shared with everyone. If anyone wants to verify a tag, they can directly import your PGP key by pulling the blob directly out of the database and importing it into GPG: + + $ git show maintainer-pgp-pub | gpg --import + +They can use that key to verify all your signed tags. Also, if you include instructions in the tag message, running `git show ` will let you give the end user more specific instructions about tag verification. + +### Generating a Build Number ### + +Because Git doesn’t have monotonically increasing numbers like 'v123' or the equivalent to go with each commit, if you want to have a human-readable name to go with a commit, you can run `git describe` on that commit. Git gives you the name of the nearest tag with the number of commits on top of that tag and a partial SHA-1 value of the commit you’re describing: + + $ git describe master + v1.6.2-rc1-20-g8c5b85c + +This way, you can export a snapshot or build and name it something understandable to people. In fact, if you build Git from source code cloned from the Git repository, `git --version` gives you something that looks like this. If you’re describing a commit that you have directly tagged, it gives you the tag name. + +The `git describe` command favors annotated tags (tags created with the `-a` or `-s` flag), so release tags should be created this way if you’re using `git describe`, to ensure the commit is named properly when described. You can also use this string as the target of a checkout or show command, although it relies on the abbreviated SHA-1 value at the end, so it may not be valid forever. For instance, the Linux kernel recently jumped from 8 to 10 characters to ensure SHA-1 object uniqueness, so older `git describe` output names were invalidated. + +### Preparing a Release ### + +Now you want to release a build. One of the things you’ll want to do is create an archive of the latest snapshot of your code for those poor souls who don’t use Git. The command to do this is `git archive`: + + $ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz + $ ls *.tar.gz + v1.6.2-rc1-20-g8c5b85c.tar.gz + +If someone opens that tarball, they get the latest snapshot of your project under a project directory. You can also create a zip archive in much the same way, but by passing the `--format=zip` option to `git archive`: + + $ git archive master --prefix='project/' --format=zip > `git describe master`.zip + +You now have a nice tarball and a zip archive of your project release that you can upload to your website or e-mail to people. + +### The Shortlog ### + +It’s time to e-mail your mailing list of people who want to know what’s happening in your project. A nice way of quickly getting a sort of changelog of what has been added to your project since your last release or e-mail is to use the `git shortlog` command. It summarizes all the commits in the range you give it; for example, the following gives you a summary of all the commits since your last release, if your last release was named v1.0.1: + + $ git shortlog --no-merges master --not v1.0.1 + Chris Wanstrath (8): + Add support for annotated tags to Grit::Tag + Add packed-refs annotated tag support. + Add Grit::Commit#to_patch + Update version and History.txt + Remove stray `puts` + Make ls_tree ignore nils + + Tom Preston-Werner (4): + fix dates in history + dynamic version method + Version bump to 1.0.2 + Regenerated gemspec for version 1.0.2 + +You get a clean summary of all the commits since v1.0.1, grouped by author, that you can e-mail to your list. + +## Summary ## + +You should feel fairly comfortable contributing to a project in Git as well as maintaining your own project or integrating other users’ contributions. Congratulations on being an effective Git developer! In the next chapter, you’ll learn more powerful tools and tips for dealing with complex situations, which will truly make you a Git master. diff --git a/vi/06-git-tools/01-chapter6.markdown b/vi/06-git-tools/01-chapter6.markdown new file mode 100644 index 000000000..3eef10757 --- /dev/null +++ b/vi/06-git-tools/01-chapter6.markdown @@ -0,0 +1,1126 @@ +# Git Tools # + +By now, you’ve learned most of the day-to-day commands and workflows that you need to manage or maintain a Git repository for your source code control. You’ve accomplished the basic tasks of tracking and committing files, and you’ve harnessed the power of the staging area and lightweight topic branching and merging. + +Now you’ll explore a number of very powerful things that Git can do that you may not necessarily use on a day-to-day basis but that you may need at some point. + +## Revision Selection ## + +Git allows you to specify specific commits or a range of commits in several ways. They aren’t necessarily obvious but are helpful to know. + +### Single Revisions ### + +You can obviously refer to a commit by the SHA-1 hash that it’s given, but there are more human-friendly ways to refer to commits as well. This section outlines the various ways you can refer to a single commit. + +### Short SHA ### + +Git is smart enough to figure out what commit you meant to type if you provide the first few characters, as long as your partial SHA-1 is at least four characters long and unambiguous — that is, only one object in the current repository begins with that partial SHA-1. + +For example, to see a specific commit, suppose you run a `git log` command and identify the commit where you added certain functionality: + + $ git log + commit 734713bc047d87bf7eac9674765ae793478c50d3 + Author: Scott Chacon + Date: Fri Jan 2 18:32:33 2009 -0800 + + fixed refs handling, added gc auto, updated tests + + commit d921970aadf03b3cf0e71becdaab3147ba71cdef + Merge: 1c002dd... 35cfb2b... + Author: Scott Chacon + Date: Thu Dec 11 15:08:43 2008 -0800 + + Merge commit 'phedders/rdocs' + + commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b + Author: Scott Chacon + Date: Thu Dec 11 14:58:32 2008 -0800 + + added some blame and merge stuff + +In this case, choose `1c002dd....` If you `git show` that commit, the following commands are equivalent (assuming the shorter versions are unambiguous): + + $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b + $ git show 1c002dd4b536e7479f + $ git show 1c002d + +Git can figure out a short, unique abbreviation for your SHA-1 values. If you pass `--abbrev-commit` to the `git log` command, the output will use shorter values but keep them unique; it defaults to using seven characters but makes them longer if necessary to keep the SHA-1 unambiguous: + + $ git log --abbrev-commit --pretty=oneline + ca82a6d changed the version number + 085bb3b removed unnecessary test code + a11bef0 first commit + +Generally, eight to ten characters are more than enough to be unique within a project. One of the largest Git projects, the Linux kernel, is beginning to need 12 characters out of the possible 40 to stay unique. + +### A SHORT NOTE ABOUT SHA-1 ### + +A lot of people become concerned at some point that they will, by random happenstance, have two objects in their repository that hash to the same SHA-1 value. What then? + +If you do happen to commit an object that hashes to the same SHA-1 value as a previous object in your repository, Git will see the previous object already in your Git database and assume it was already written. If you try to check out that object again at some point, you’ll always get the data of the first object. + +However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160 bits. The number of randomly hashed objects needed to ensure a 50% probability of a single collision is about 2^80 (the formula for determining collision probability is `p = (n(n-1)/2) * (1/2^160))`. 2^80 is 1.2 x 10^24 or 1 million billion billion. That’s 1,200 times the number of grains of sand on the earth. + +Here’s an example to give you an idea of what it would take to get a SHA-1 collision. If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (1 million Git objects) and pushing it into one enormous Git repository, it would take 5 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. A higher probability exists that every member of your programming team will be attacked and killed by wolves in unrelated incidents on the same night. + +### Branch References ### + +The most straightforward way to specify a commit requires that it have a branch reference pointed at it. Then, you can use a branch name in any Git command that expects a commit object or SHA-1 value. For instance, if you want to show the last commit object on a branch, the following commands are equivalent, assuming that the `topic1` branch points to `ca82a6d`: + + $ git show ca82a6dff817ec66f44342007202690a93763949 + $ git show topic1 + +If you want to see which specific SHA a branch points to, or if you want to see what any of these examples boils down to in terms of SHAs, you can use a Git plumbing tool called `rev-parse`. You can see Chapter 9 for more information about plumbing tools; basically, `rev-parse` exists for lower-level operations and isn’t designed to be used in day-to-day operations. However, it can be helpful sometimes when you need to see what’s really going on. Here you can run `rev-parse` on your branch. + + $ git rev-parse topic1 + ca82a6dff817ec66f44342007202690a93763949 + +### RefLog Shortnames ### + +One of the things Git does in the background while you’re working away is keep a reflog — a log of where your HEAD and branch references have been for the last few months. + +You can see your reflog by using `git reflog`: + + $ git reflog + 734713b... HEAD@{0}: commit: fixed refs handling, added gc auto, updated + d921970... HEAD@{1}: merge phedders/rdocs: Merge made by recursive. + 1c002dd... HEAD@{2}: commit: added some blame and merge stuff + 1c36188... HEAD@{3}: rebase -i (squash): updating HEAD + 95df984... HEAD@{4}: commit: # This is a combination of two commits. + 1c36188... HEAD@{5}: rebase -i (squash): updating HEAD + 7e05da5... HEAD@{6}: rebase -i (pick): updating HEAD + +Every time your branch tip is updated for any reason, Git stores that information for you in this temporary history. And you can specify older commits with this data, as well. If you want to see the fifth prior value of the HEAD of your repository, you can use the `@{n}` reference that you see in the reflog output: + + $ git show HEAD@{5} + +You can also use this syntax to see where a branch was some specific amount of time ago. For instance, to see where your `master` branch was yesterday, you can type + + $ git show master@{yesterday} + +That shows you where the branch tip was yesterday. This technique only works for data that’s still in your reflog, so you can’t use it to look for commits older than a few months. + +To see reflog information formatted like the `git log` output, you can run `git log -g`: + + $ git log -g master + commit 734713bc047d87bf7eac9674765ae793478c50d3 + Reflog: master@{0} (Scott Chacon ) + Reflog message: commit: fixed refs handling, added gc auto, updated + Author: Scott Chacon + Date: Fri Jan 2 18:32:33 2009 -0800 + + fixed refs handling, added gc auto, updated tests + + commit d921970aadf03b3cf0e71becdaab3147ba71cdef + Reflog: master@{1} (Scott Chacon ) + Reflog message: merge phedders/rdocs: Merge made by recursive. + Author: Scott Chacon + Date: Thu Dec 11 15:08:43 2008 -0800 + + Merge commit 'phedders/rdocs' + +It’s important to note that the reflog information is strictly local — it’s a log of what you’ve done in your repository. The references won’t be the same on someone else’s copy of the repository; and right after you initially clone a repository, you’ll have an empty reflog, as no activity has occurred yet in your repository. Running `git show HEAD@{2.months.ago}` will work only if you cloned the project at least two months ago — if you cloned it five minutes ago, you’ll get no results. + +### Ancestry References ### + +The other main way to specify a commit is via its ancestry. If you place a `^` at the end of a reference, Git resolves it to mean the parent of that commit. +Suppose you look at the history of your project: + + $ git log --pretty=format:'%h %s' --graph + * 734713b fixed refs handling, added gc auto, updated tests + * d921970 Merge commit 'phedders/rdocs' + |\ + | * 35cfb2b Some rdoc changes + * | 1c002dd added some blame and merge stuff + |/ + * 1c36188 ignore *.gem + * 9b29157 add open3_detach to gemspec file list + +Then, you can see the previous commit by specifying `HEAD^`, which means "the parent of HEAD": + + $ git show HEAD^ + commit d921970aadf03b3cf0e71becdaab3147ba71cdef + Merge: 1c002dd... 35cfb2b... + Author: Scott Chacon + Date: Thu Dec 11 15:08:43 2008 -0800 + + Merge commit 'phedders/rdocs' + +You can also specify a number after the `^` — for example, `d921970^2` means "the second parent of d921970." This syntax is only useful for merge commits, which have more than one parent. The first parent is the branch you were on when you merged, and the second is the commit on the branch that you merged in: + + $ git show d921970^ + commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b + Author: Scott Chacon + Date: Thu Dec 11 14:58:32 2008 -0800 + + added some blame and merge stuff + + $ git show d921970^2 + commit 35cfb2b795a55793d7cc56a6cc2060b4bb732548 + Author: Paul Hedderly + Date: Wed Dec 10 22:22:03 2008 +0000 + + Some rdoc changes + +The other main ancestry specification is the `~`. This also refers to the first parent, so `HEAD~` and `HEAD^` are equivalent. The difference becomes apparent when you specify a number. `HEAD~2` means "the first parent of the first parent," or "the grandparent" — it traverses the first parents the number of times you specify. For example, in the history listed earlier, `HEAD~3` would be + + $ git show HEAD~3 + commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d + Author: Tom Preston-Werner + Date: Fri Nov 7 13:47:59 2008 -0500 + + ignore *.gem + +This can also be written `HEAD^^^`, which again is the first parent of the first parent of the first parent: + + $ git show HEAD^^^ + commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d + Author: Tom Preston-Werner + Date: Fri Nov 7 13:47:59 2008 -0500 + + ignore *.gem + +You can also combine these syntaxes — you can get the second parent of the previous reference (assuming it was a merge commit) by using `HEAD~3^2`, and so on. + +### Commit Ranges ### + +Now that you can specify individual commits, let’s see how to specify ranges of commits. This is particularly useful for managing your branches — if you have a lot of branches, you can use range specifications to answer questions such as, "What work is on this branch that I haven’t yet merged into my main branch?" + +#### Double Dot #### + +The most common range specification is the double-dot syntax. This basically asks Git to resolve a range of commits that are reachable from one commit but aren’t reachable from another. For example, say you have a commit history that looks like Figure 6-1. + +Insert 18333fig0601.png +Figure 6-1. Example history for range selection. + +You want to see what is in your experiment branch that hasn’t yet been merged into your master branch. You can ask Git to show you a log of just those commits with `master..experiment` — that means "all commits reachable by experiment that aren’t reachable by master." For the sake of brevity and clarity in these examples, I’ll use the letters of the commit objects from the diagram in place of the actual log output in the order that they would display: + + $ git log master..experiment + D + C + +If, on the other hand, you want to see the opposite — all commits in `master` that aren’t in `experiment` — you can reverse the branch names. `experiment..master` shows you everything in `master` not reachable from `experiment`: + + $ git log experiment..master + F + E + +This is useful if you want to keep the `experiment` branch up to date and preview what you’re about to merge in. Another very frequent use of this syntax is to see what you’re about to push to a remote: + + $ git log origin/master..HEAD + +This command shows you any commits in your current branch that aren’t in the `master` branch on your `origin` remote. If you run a `git push` and your current branch is tracking `origin/master`, the commits listed by `git log origin/master..HEAD` are the commits that will be transferred to the server. +You can also leave off one side of the syntax to have Git assume HEAD. For example, you can get the same results as in the previous example by typing `git log origin/master..` — Git substitutes HEAD if one side is missing. + +#### Multiple Points #### + +The double-dot syntax is useful as a shorthand; but perhaps you want to specify more than two branches to indicate your revision, such as seeing what commits are in any of several branches that aren’t in the branch you’re currently on. Git allows you to do this by using either the `^` character or `--not` before any reference from which you don’t want to see reachable commits. Thus these three commands are equivalent: + + $ git log refA..refB + $ git log ^refA refB + $ git log refB --not refA + +This is nice because with this syntax you can specify more than two references in your query, which you cannot do with the double-dot syntax. For instance, if you want to see all commits that are reachable from `refA` or `refB` but not from `refC`, you can type one of these: + + $ git log refA refB ^refC + $ git log refA refB --not refC + +This makes for a very powerful revision query system that should help you figure out what is in your branches. + +#### Triple Dot #### + +The last major range-selection syntax is the triple-dot syntax, which specifies all the commits that are reachable by either of two references but not by both of them. Look back at the example commit history in Figure 6-1. +If you want to see what is in `master` or `experiment` but not any common references, you can run + + $ git log master...experiment + F + E + D + C + +Again, this gives you normal `log` output but shows you only the commit information for those four commits, appearing in the traditional commit date ordering. + +A common switch to use with the `log` command in this case is `--left-right`, which shows you which side of the range each commit is in. This helps make the data more useful: + + $ git log --left-right master...experiment + < F + < E + > D + > C + +With these tools, you can much more easily let Git know what commit or commits you want to inspect. + +## Interactive Staging ## + +Git comes with a couple of scripts that make some command-line tasks easier. Here, you’ll look at a few interactive commands that can help you easily craft your commits to include only certain combinations and parts of files. These tools are very helpful if you modify a bunch of files and then decide that you want those changes to be in several focused commits rather than one big messy commit. This way, you can make sure your commits are logically separate changesets and can be easily reviewed by the developers working with you. +If you run `git add` with the `-i` or `--interactive` option, Git goes into an interactive shell mode, displaying something like this: + + $ git add -i + staged unstaged path + 1: unchanged +0/-1 TODO + 2: unchanged +1/-1 index.html + 3: unchanged +5/-1 lib/simplegit.rb + + *** Commands *** + 1: status 2: update 3: revert 4: add untracked + 5: patch 6: diff 7: quit 8: help + What now> + +You can see that this command shows you a much different view of your staging area — basically the same information you get with `git status` but a bit more succinct and informative. It lists the changes you’ve staged on the left and unstaged changes on the right. + +After this comes a Commands section. Here you can do a number of things, including staging files, unstaging files, staging parts of files, adding untracked files, and seeing diffs of what has been staged. + +### Staging and Unstaging Files ### + +If you type `2` or `u` at the `What now>` prompt, the script prompts you for which files you want to stage: + + What now> 2 + staged unstaged path + 1: unchanged +0/-1 TODO + 2: unchanged +1/-1 index.html + 3: unchanged +5/-1 lib/simplegit.rb + Update>> + +To stage the TODO and index.html files, you can type the numbers: + + Update>> 1,2 + staged unstaged path + * 1: unchanged +0/-1 TODO + * 2: unchanged +1/-1 index.html + 3: unchanged +5/-1 lib/simplegit.rb + Update>> + +The `*` next to each file means the file is selected to be staged. If you press Enter after typing nothing at the `Update>>` prompt, Git takes anything selected and stages it for you: + + Update>> + updated 2 paths + + *** Commands *** + 1: status 2: update 3: revert 4: add untracked + 5: patch 6: diff 7: quit 8: help + What now> 1 + staged unstaged path + 1: +0/-1 nothing TODO + 2: +1/-1 nothing index.html + 3: unchanged +5/-1 lib/simplegit.rb + +Now you can see that the TODO and index.html files are staged and the simplegit.rb file is still unstaged. If you want to unstage the TODO file at this point, you use the `3` or `r` (for revert) option: + + *** Commands *** + 1: status 2: update 3: revert 4: add untracked + 5: patch 6: diff 7: quit 8: help + What now> 3 + staged unstaged path + 1: +0/-1 nothing TODO + 2: +1/-1 nothing index.html + 3: unchanged +5/-1 lib/simplegit.rb + Revert>> 1 + staged unstaged path + * 1: +0/-1 nothing TODO + 2: +1/-1 nothing index.html + 3: unchanged +5/-1 lib/simplegit.rb + Revert>> [enter] + reverted one path + +Looking at your Git status again, you can see that you’ve unstaged the TODO file: + + *** Commands *** + 1: status 2: update 3: revert 4: add untracked + 5: patch 6: diff 7: quit 8: help + What now> 1 + staged unstaged path + 1: unchanged +0/-1 TODO + 2: +1/-1 nothing index.html + 3: unchanged +5/-1 lib/simplegit.rb + +To see the diff of what you’ve staged, you can use the `6` or `d` (for diff) command. It shows you a list of your staged files, and you can select the ones for which you would like to see the staged diff. This is much like specifying `git diff --cached` on the command line: + + *** Commands *** + 1: status 2: update 3: revert 4: add untracked + 5: patch 6: diff 7: quit 8: help + What now> 6 + staged unstaged path + 1: +1/-1 nothing index.html + Review diff>> 1 + diff --git a/index.html b/index.html + index 4d07108..4335f49 100644 + --- a/index.html + +++ b/index.html + @@ -16,7 +16,7 @@ Date Finder + +

...

+ + - + + + +