From dd6488cbb96a276303e47e7c515c988b0f3b1859 Mon Sep 17 00:00:00 2001 From: Jean-Noel Avila Date: Fri, 30 Aug 2013 23:07:34 +0200 Subject: [PATCH 001/690] 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 e36c02acad6d7fd7ab356f90842ad17ac1c3d9e8 Mon Sep 17 00:00:00 2001 From: Jean-Noel Avila Date: Sun, 27 Oct 2013 11:50:11 +0100 Subject: [PATCH 002/690] 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 003/690] 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 bdef6f762f3cc3652c142cc64aa2342f9e0da9da Mon Sep 17 00:00:00 2001 From: Daniel Rosen Date: Mon, 16 Dec 2013 00:35:12 -0500 Subject: [PATCH 004/690] 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 1ca5ef1602de99198882a0153b8c3f399317e76f Mon Sep 17 00:00:00 2001 From: Daniel Rosen Date: Mon, 16 Dec 2013 13:53:24 -0500 Subject: [PATCH 005/690] 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 2a0a8371ed727a2f536fa3a51d14201de97540ca Mon Sep 17 00:00:00 2001 From: Chris Down Date: Fri, 3 Jan 2014 16:34:54 +0800 Subject: [PATCH 006/690] Note that, when locally copying, the hardlinked files are the objects Previously it was possible to infer from this sentence that the actual work tree was hard linked, but it is the Git objects that are hard linked. This makes the passage much less ambiguous. --- en/04-git-server/01-chapter4.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/04-git-server/01-chapter4.markdown b/en/04-git-server/01-chapter4.markdown index af7665115..ec3f415a4 100644 --- a/en/04-git-server/01-chapter4.markdown +++ b/en/04-git-server/01-chapter4.markdown @@ -26,7 +26,7 @@ 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. +Git operates slightly differently if you explicitly specify `file://` at the beginning of the URL. If you just specify the path, and the source and the destination are on the same filesystem, Git tries to hardlink the objects it needs. If they are not on the same filesystem, it will copy the objects it needs using the system's standard copying functionality. 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: From 83a4198d37f28a782d0e1306b73fcca391ea3589 Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Thu, 2 Jan 2014 19:28:05 +0100 Subject: [PATCH 007/690] [de] First translation of chapter 6.6 (submodules) --- de/06-git-tools/01-chapter6.markdown | 70 ++++++++++++++++++++++++++++ de/README.md | 4 +- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index 3f1726928..f928356ac 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -1104,14 +1104,23 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Oft möchte man während der Arbeit an einem Projekt ein weiteres Projekt darin einbinden und verwenden. Das kann zum Beispiel eine Bibliothek von einer anderen Firma oder vielleicht auch eine selbstentwickelte Bibliothek sein. In einem solchen Szenario tritt dann meistens folgendes Problem auf: Die zwei Projekte sollen unabhängig voneinander entwickelt werden können, aber trotzdem soll es möglich sein, das eine Projekt im anderen zu verwenden. + +Dazu ein Beispiel. Nehmen wir an, Du entwickelt gerade eine Webseite, die unter anderem einen Atom-Feed zur Verfügung stellen soll. Anstatt den notwendigen Code zur Auslieferung des Atom-Feeds selber zu schreiben, entscheidest Du Dich für eine geeignete Bibliothek. Dann wirst Du wahrscheinlich den Code in Dein Projekt inkludieren müssen, zum Beispiel durch eine CPAN Installation oder Ruby gem oder durch Kopieren des Quellcodes in das Arbeitsverzeichnis Deines Projekts. Das Problem beim Einbinden einer Bibliothek ist, dass es schwierig ist, diese an die eigene Bedürfnisse anzupassen. Noch schwieriger gestaltet sich dann die Veröffentlichung des Projekts, da man sicherstellen muss, dass jeder der die Software verwendet, auf die Bibliothek zugreifen kann. Wenn man die Bibliothek im eigenen Projekt projektspezifisch anpasst, hat man meist ein Problem, wenn man eine neue Version der Bibliothek einspielen will. + +Git löst dieses Problem mit Hilfe von Submodulen. Mit Hilfe von Submodulen kann man innerhalb eines Git Repositorys ein weiteres Git Repository in einem Unterverzeichnis verwalten. Daraus entsteht der Vorteil, dass man ein anderes Repository in das eigene Projekt klonen kann und die Commits der jeweiligen Projekte trennen kann. + +### Die ersten Schritte mit Submodulen ### +Nehmen wir einmal an, dass Du die Rack Bibliothek (eine Ruby Gateway Schnittstelle für Webserver) zu Deinem Projekt hinzufügen willst. Dabei möchtest Du Deine eigenen Änderungen an dieser Bibliothek nachverfolgen, aber auch weiterhin Änderungen von den Rack Bibliothek-Entwicklern verwalten und zusammenmergen. Das erste was Du dazu tun musst, ist das Repository der Rack Bibliothek in ein Unterverzeichnis Deines Projekts zu klonen. Diesen Vorgang kannst Du mit Hilfe des Befehls `git submodule add` ausführen: + $ git submodule add git://github.com/chneukirchen/rack.git rack Initialized empty Git repository in /opt/subtest/rack/.git/ remote: Counting objects: 3181, done. @@ -1122,6 +1131,8 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Innerhalb Deines Projekts befindet sich nun im Unterverzeichnis `rack` das komplette Rack-Projekt. Man kann jetzt in diesem Verzeichnis Änderungen vornehmen und ein eigenes Remote Repository mit Schreibrechten, zu welchem man pushen kann, hinzufügen. Ebenso ist es möglich, Änderungen von den Rack Entwicklern in sein Repository zu laden und diese mit den eigenen Ergebnissen zu mergen. Im Prinzip kann man innerhalb eines Submoduls die gleichen Vorgänge, wie in einem normalen Repository ausführen. Vorher müssen wir aber noch ein paar weitere Dinge zu Submodulen besprechen. Wenn Du gleich nach dem Hinzufügen des Submoduls, den Befehl `git status` ausführst, wirst Du gleich zwei Dinge bemerken: + $ git status # On branch master # Changes to be committed: @@ -1133,6 +1144,8 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Als erstes wird Dir die neue Datei `.gitmodules` auffallen. Das ist eine Konfigurationsdatei, welche die Zuordnung der URL des geklonten Projekts und dem lokalen Unterverzeichnis, in welches das Projekt geklont wurde, festlegt: + $ cat .gitmodules [submodule "rack"] path = rack @@ -1140,8 +1153,12 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Wenn Du mehrere Submodule in einem Projekt verwaltest, werden auch mehrere Einträge in dieser Datei auftauchen. Dabei ist es wichtig zu wissen, dass diese Datei zusammen mit all den anderen Dateien aus Deinem Projekt, ebenso in die Versionskontrolle aufgenommen wird, ähnlich wie die Datei `.gitignore`. Die Datei wird so wie der Rest Deines Projekts gepusht und gepullt. Dadurch wissen andere Personen, die Dein Projekt klonen, von welchem Ort sie die Submodule erhalten können. + +Die zweite Auffälligkeit bei der Ausgabe von `git status` ist der Eintrag rack. Wenn Du auf diesen Eintrag ein `git diff` durchführst, erhält man in etwa die folgende, interessante Ausgabe: + $ git diff --cached rack diff --git a/rack b/rack new file mode 160000 @@ -1153,10 +1170,16 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Obwohl `rack` ein Unterverzeichnis in Deinem Arbeitsverzeichnis ist, erkennt Git dieses Verzeichnis als Submodul und verfolgt die Änderungen innerhalb dieses Verzeichnis nicht, wenn Git nicht innerhalb dieses Verzeichnis aufgerufen wird. Stattdessen erfässt Git welcher Commit in diesem Repository ausgecheckt ist. Wenn Du also Änderungen in diesem Unterverzeichnis durchführst und eincheckst, kann das Superprojekt erkennen, dass sich der aktuelle HEAD von diesem Projekt geändert hat. Das Superprojekt kann sich jetzt diesen Commit merken. Auf diese Art und Weise ist es möglich den kompletten Zustand des Projekts mit allen Projekten, die als Submodul hinzugefügt wurden, zu reproduzieren. In der Git Terminologie wird das Projekt, welches eines oder mehrere Submodule enthält, als Superprojekt bezeichnet. + +Dabei muss man sich folgender Eigenschaft bewusst sein: Git verwaltet den exakten Commit, der gerade ausgecheckt ist und nicht etwa den Branch oder eine andere Referenz. Git kann also zum Beispiel nicht speichern, dass der aktuelle Stand im Branch `master` enthalten ist. + +Wenn Du Dein Projekt das erste mal eincheckst, erhälst Du in etwa folgende Ausgabe: + $ git commit -m 'first commit with submodule rack' [master 0550271] first commit with submodule rack 2 files changed, 4 insertions(+), 0 deletions(-) @@ -1165,8 +1188,12 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Der Mode 160000, der für den rack Eintrag gilt, ist ein spezieller Mode in Git. Er bedeutet in etwa, dass man einen Commit als Verzeichnis-Eintrag in Git verwaltet und damit nicht wie normalerweise ein Verzeichnis oder eine Datei. + +Das Verzeichnis `rack` kann man wie ein separates Projekt behandeln und verwenden. Und von Zeit zur Zeit aktualisiert man auch das Superprojekt und speichert damit die letzte Commit Id des Unterprojekts. Jedes Git Kommando arbeitet unabhängig in einem der beiden Unterverzeichnisse: + $ git log -1 commit 0550271328a0038865aad6331e620cd7238601bb Author: Scott Chacon @@ -1182,9 +1209,12 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem Document version change +### Klonen eines Projekts mit den dazugehörigen Submodulen ### +Als nächstes klonen wir ein Projekt, welches ein Submodul verwendet. Wenn man ein solches Projekt klont, werden die entsprechenden Verzeichnisse, welche ein Submodul enthalten, erstellt. Allerdings enthalten diese Verzeichnisse noch keinen Inhalt: + $ git clone git://github.com/schacon/myproject.git Initialized empty Git repository in /opt/myproject/.git/ remote: Counting objects: 6, done. @@ -1201,6 +1231,8 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Das Verzeichnis `rack` wurde zwar erzeugt, aber es ist leer. Deshalb musst Du zwei Dinge ausführen: `git submodule init`, damit wird die Datei für die lokale Konfiguration initiailisiert. Und `git submodule update`, welches die gesamten Daten des Projekts von der im `.gitmodules` angegebenen Quelle holt und den entsprechenden Commit, welcher im Superprojekt hinterlegt ist, auscheckt: + $ git submodule init Submodule 'rack' (git://github.com/chneukirchen/rack.git) registered for path 'rack' $ git submodule update @@ -1214,6 +1246,8 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Nach Ausführung der beiden Befehle befindet sich das Verzeichnis `rack` in genau dem gleichen Zustand, wie wir es ursprünglich eingecheckt haben. Wenn ein anderer Entwickler Änderungen am Rack Code durchführt, diese eincheckt und Du diese dann pullst und mergst, erhält man einen etwas seltsamen Zustand: + $ git merge origin/master Updating 0550271..85a3eee Fast forward @@ -1230,6 +1264,8 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Der Merge, der gerade durchgeführt worden ist, ist eigentlich nur eine Aktualisierung des Zeigers auf einen neuen Commit des Submoduls. Der eigentliche Inhalt des Submodul-Verzeichnis wurde allerdings nicht aktualisiert. Das sieht dann so aus, als gäbe es noch nicht eingecheckte Dateien innerhalb Deines Arbeitsverzeichnis: + $ git diff diff --git a/rack b/rack index 6c5e70b..08d709f 160000 @@ -1241,6 +1277,8 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Dieser Zustand tritt auf, weil der Zeiger auf den Commit im Submodul derzeit nicht der Commit ist, welcher im Submodul ausgecheckt ist. Um dies zu beheben, muss man den Befehl `git submodule update` erneut ausführen: + $ git submodule update remote: Counting objects: 5, done. remote: Compressing objects: 100% (3/3), done. @@ -1252,14 +1290,20 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Dieser Update muss jedes mal ausgeführt werden, wenn man das Superprojekt pullt und dort ein Änderung in einem Submodul enthalten ist. Es ist vielleicht ein wenig merkwürdig, aber es funktioniert. + +Häufig tritt beim Arbeiten mit Submodulen ein Problem bei folgendem Szenario auf: Ein Entwickler führt Änderungen in einem Submodul durch, checkt diese ein, vergisst aber diese Änderungen zum zentralen Server zu pushen. Wenn dann im Superprojekt die Änderung des Submoduls ebenso eingecheckt wird und dieses dann gepusht wird, tritt ein Problem auf. Wenn jetzt andere Entwickler den neuen Stand des Superprojekts holen und den Befehl `git submodule update` ausführen, erhalten sie eine Fehlermeldung, dass der entsprechend referenzierte Commit von dem Submodul nicht gefunden werden konnte. Das passiert weil dieser Commit bei dem zweiten Entwickler noch gar nicht existiert. Wenn ein solcher Fall auftritt, erhält man in etwa folgende Fehlermeldung: + $ git submodule update fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 Unable to checkout '6c5e70b984a60b3cecd395edd5ba7575bf58e0' in submodule path 'rack' +Dann kann man allerdings herausfinden, wer zum letzten mal eine Änderung eingecheckt hat: + $ git log -1 rack commit 85a3eee996800fcfa91e2119372dd4172bf76678 Author: Scott Chacon @@ -1269,20 +1313,34 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Dann kannst Du diesem Entwickler eine E-Mail schreiben und ihn auf seinen Fehler aufmerksam machen. + +### Superprojekte ### +In manchen großen Projekten möchten die Entwickler die Arbeit in verschiedenen Verzeichnissen aufteilen, sodass das jeweilige Team in diesen Verzeichnissen arbeiten kann. Man trifft diese Vorgehensweise häufig an, wenn ein Team gerade von CVS oder Subversion nach Git gewechselt hat, im alten System ein Modul oder eine Sammlung von solchen Unterverzeichnissen gebildet hat und diesen Arbeitsablauf weiterhin verwenden möchte. + +In Git kann man diese Vorgehensweise gut abbilden, indem man für jedes Unterverzeichnis ein neues Git Repository erzeugt. Zusätzlich kann man dann ein Superprojekt erzeugen und die ganzen Git Repositorys als Submodul hinzufügen. Ein Vorteil dabei ist, dass man mit Hilfe von Tags und Branches im Superprojekt das Verhältnis der einzelnen Submodule zueinander festhalten kann. + +### Häufige Probleme mit Submodulen ### +Die Arbeit mit Submodulen verläuft jedoch nicht immer reibungslos. Man muss verhältnismäßig gut aufpassen, wenn man in einem Submodul-Verzeichnis arbeitet. Wenn man nämlich den Befehl `git submodule update` ausführt, checkt Git den entsprechenden Zustand des Commits aus, aber checkt dabei keinen Branch aus. Diesen Zustand nennt man auch `detached HEAD`. Das bedeutet das die Datei HEAD direkt auf einen Commit zeigt und nicht wie sonst üblich auf eine symbolische Referenz, also zum Beispiel auf einen Branch. Das Problem dabei ist, dass man normalerweise in einem solchen Zustand nicht weiterarbeiten möchte, weil es sehr leicht vorkommen kann, dass Änderungen verloren gehen. Wenn man also den Befehl `git submodule update` aufruft, dann einen Commit in dem entsprechenden Submodul-Verzeichnis ausführt, ohne davor einen Branch auszuchecken, und dann noch einmal `git submodule update` im Superprojekt aufruft, ohne dass man die Änderungen im Submodul im Superprojekt eingecheckt hat, verliert man die ganzen Änderungen, ohne das Git einen darauf vorher hinweist. Tatsächlich ist es so, dass die Änderungen nicht verloren gehen, aber es gibt keinen Branch der auf die entsprechenden Commits hinzeigt und damit kann es schwierig werden die entsprechenden Commits wiederherzustellen beziehungsweise sichtbar zu machen. + +Um dieses Problem zu vermeiden, sollte man also immer in dem Submodul-Verzeichnis einen neuen Branch mit `git checkout -b work` oder auf eine andere Art und Weise erzeugen. Wenn man dann wieder das Aktualisieren des Submoduls ausführt, wird Git wieder den ursprünglichen Commit auschecken, allerdings hat man jetzt mit dem Branch einen Zeiger auf die neuen Commits und man kann sie leicht wieder auschecken. + +Wenn ein Projekt ein Submodul enthält und man im Superprojekt zwischen einzelnen Branches hin und her wechseln möchte, kann sich das manchmal auch schwierig gestalten. Wenn man zum Beispiel einen neuen Branch erzeugt, in diesem dann ein Submodul hinzufügt und dann wieder in den ursprünglichen Branch, welcher das Submodul noch nicht enthält, zurückwechselt, hat man im Arbeitsverzeichnis immer noch das Submodul-Verzeichnis, welches auch so dargestellt wird, als ob es von Git noch nicht verfolgt wird: + $ git checkout -b rack Switched to a new branch "rack" $ git submodule add git@github.com:schacon/rack.git rack @@ -1306,14 +1364,20 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +In diesem Fall muss man das Verzeichnis entweder an einen anderen Ort verschieben oder löschen. Im letzteren Fall muss man aber wieder das Submodul komplett klonen, wenn man in den anderen Zweig zurückwechselt. Außerdem kann man dabei lokale Änderungen zu nichte machen oder Zweige, welche man noch nicht gepusht hat, verlieren. + +Die letzte Falle in die viele Leute tappen, tritt auf, wenn man bereits vorhandene Verzeichnisse in Submodule umwandeln will. Wenn man also Dateien, die bereits von Git verwaltet werden, entfernen und in ein entsprechendes Submodul verschieben möchte, muss man vorsichtig sein. Ansonsten können schwer zu behebende Probleme mit Git auftreten. Nehmen wir zum Beispiel an, dass Du die Dateien vom Rack Projekt in ein Unterverzeichnis Deines Projekts abgelegt hast und diese jetzt aber in ein Submodul verschieben möchtest. Wenn Du das Unterverzeichnis einfach löschst und dann den Befehl `submodule add` ausführst, zeigt dir Git folgende Fehlermeldung an: + $ rm -Rf rack/ $ git submodule add git@github.com:schacon/rack.git rack 'rack' already exists in the index +Man muss dann das Verzeichnis `rack` erst aus der Staging Area entfernen. Danach kann man dann das Submodul erzeugen: + $ git rm -r rack $ git submodule add git@github.com:schacon/rack.git rack Initialized empty Git repository in /opt/testsub/rack/.git/ @@ -1325,11 +1389,15 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Wenn wir jetzt annehmen, dass Du diesen Vorgang innerhalb eines Zweigs durchgeführt hast und jetzt auf einen anderen Zweig, in dem das Submodul noch nicht existiert hat und damit die Dateien noch ganz normal im Repository enthalten waren, wechselst, erhält Du folgenden Fehler: + $ git checkout master error: Untracked working tree file 'rack/AUTHORS' would be overwritten by merge. +Dann musst Du das Submodul-Verzeichnis `rack` an einen anderen Ort verschieben, bevor Du diesen Branch auschecken kannst: + $ mv rack /tmp/ $ git checkout master Switched to branch "master" @@ -1338,6 +1406,8 @@ Wenn Du die untere, genannte Zeile ausführst, führt Git automatisch nach jedem +Wenn man dann wieder in den Zweig mit dem Submodul zurückwechseln will, erhält man ein leeres Verzeichnis `rack`. Um dieses zu befüllen, kannst du entweder `git submodule update` ausführen oder Du kannst Deine Kopie von `/tmp/rack` wieder an den ursprünglichen Ort wiederherstellen. + ## Subtree Merging ## diff --git a/de/README.md b/de/README.md index e5774f6d9..d9e8abcad 100644 --- a/de/README.md +++ b/de/README.md @@ -418,10 +418,10 @@ Bitte den Status nicht aktualisieren. Dies übernimmt ein Maintainer. 6.6 -Nein +Ja Nein Ja -Übersetzung fehlt +Review notwendig 6.7 From 81d9ebed352637ff3390f11034cb5119014916e4 Mon Sep 17 00:00:00 2001 From: Jean-Noel Avila Date: Fri, 3 Jan 2014 13:16:29 +0100 Subject: [PATCH 008/690] [fr] update README to bypass progit-fr Now the french translation's fixup don't need a specific repo. Just use the main repo for forking and submitting. --- fr/README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/fr/README.md b/fr/README.md index 75cf1f4f3..4e8bfe586 100644 --- a/fr/README.md +++ b/fr/README.md @@ -2,10 +2,8 @@ ## Dépôt de référence ## -Le dépot de référence de la traduction française est situé ici : -https://github.com/progit-fr/progit - -C'est le dépôt de fusion des travaux sur la branche fr, avant de lancer les requêtes de tirage sur le dépôt principal Progit. +Comme le mainteneur des traductions du livre est français, le dépot de référence de la traduction française est situé ici. +https://github.com/progit/progit ## Liste de diffusion ## @@ -15,7 +13,7 @@ Si vous travaillez ou souhaitez travailler sur la traduction française de Progi ## Workflow ## -Pour simplifier la gestion et utiliser pleinement les capacités de Git et Github, la manière la plus directe de collaborer consiste à faire un fork sur Github du dépôt progit-fr/progit sur votre propre compte pour y générer vos modifications, si possible sur une branche thématique. +Pour simplifier la gestion et utiliser pleinement les capacités de Git et Github, la manière la plus directe de collaborer consiste à faire un fork sur Github du dépôt progit/progit sur votre propre compte pour y générer vos modifications, si possible sur une branche thématique. Ensuite, il suffit de lancer une requête de tirage pour nous avertir que les modifications peuvent être revues et intégrées. From fab4c1ed65d96f848cd3298738944d364960e3b9 Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Fri, 3 Jan 2014 17:42:11 +0100 Subject: [PATCH 009/690] [de] First translation of chapter 6.7 (subtree-merge) --- de/06-git-tools/01-chapter6.markdown | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index f928356ac..e266f393e 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -1413,12 +1413,20 @@ Wenn man dann wieder in den Zweig mit dem Submodul zurückwechseln will, erhält +Nachdem wir neben den Vor- und Nachteilen beim Arbeiten mit Submodulen kennengelernt haben, möchte ich jetzt noch eine alternative Lösung zeigen, wie man ähnliche Probleme lösen kann. Wenn Git etwas zusammenführt, also mergt, analysiert es die Teile, die es mergen muss. Auf Basis dieser Analyse entscheidet Git sich für eine geeignete Merging-Methode. Wenn man zwei Branches mergt, dann verwendet Git automatisch, die sogenannte Recursive-Strategie. Wenn man mehr als zwei Branches mergt, verwendet Git die sogenannte Octopus Strategie. Diese Strategien werden automatisch für Dich gewählt, weil die Recursive-Strategie normalerweise sehr gut geeignet ist, um einen Drei-Wege-Merge (engl. three-way merge) durchzuführen — zum Beispiel, wenn es mehr als einen gemeinsamen Vorgänger-Commit gibt — aber der Drei-Wege-Merge ist nur für das Mergen von zwei Branches geeignet. Die Octopus-Merge-Strategie kann mehrere Branches zusammenführen, aber es wird dabei vorsichtiger vorgegangen um schwierig aufzulösende Konflikte zu vermeiden. Aus diesem Grund wird diese Strategie standardmäßig verwendet, wenn man mehr als zwei Branches zusammenführen möchte. + +Es gibt jedoch noch weitere Strategien die man verwenden kann. Einer dieser Strategien ist der sogenannte Subtree-Merge. Dies kann verwendet werden um unser Problem mit Unterprojekten zu lösen. Ich möchte Dir im folgenden aufzeigen, wie man das Rack-Projekt aus dem letzten Kapitel einbindet und dabei den Subree-Merge anstatt den Submodulen verwendet. + +Das Prinzip, das hinter einem Subtree-Merge steckt, ist, dass man zwei Projekte hat und eines der Projekte wird in ein Unterverzeichnis des anderen Projekts abgebildet. Wenn man ein Subtree-Merge ausführt, ist Git schlau genug um zu erkennen, dass ein Projekt ein Abbild von einem anderen Projekt ist und es kann den Merge in geeigneter Weise durchführen — das ist wirklich sehr erstaunlich. + +Als erstes musst Du dazu die Rack Applikation zu Deinem Projekt hinzufügen. Dazu fügst Du das Rack Projekt als neues Remote Repository in Deinem Projekt hinzu und checkst dieses in einem separaten Branch aus: + $ git remote add rack_remote git@github.com:schacon/rack.git $ git fetch rack_remote warning: no common commits @@ -1438,6 +1446,8 @@ Wenn man dann wieder in den Zweig mit dem Submodul zurückwechseln will, erhält +Nach der Ausführung der drei Befehle befindet sich das Rack Projekt in Deinem Branch `rack_branch` und Dein eigenes Projekt liegt weiterhin im Branch `master`. Wenn man jetzt den jeweiligen Zweig auscheckt, sieht man die unterschiedlichen Inhalte im Wurzelverzeichnis: + $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib COPYING README bin example test @@ -1448,15 +1458,21 @@ Wenn man dann wieder in den Zweig mit dem Submodul zurückwechseln will, erhält +Jetzt möchten wir das Rack Projekt in Deinen Branch `master` als Unterverzeichnis hinzufügen. Dies kann man in Git mit dem Befehl `git read-tree` durchführen. In Kapitel 9 werde ich den Befehl `read-tree` und dessen verwandten Befehle näher erläutern. Hier möchte ich nur erklären, dass der Befehl das Wurzelverzeichnis eines Branches in die aktuelle Staging Area und in das Arbeitsverzeichnis packt. Damit hast Du jetzt zu Deinem Branch `master` zurückgewechselt, den Inhalt des Branches `rack` in das Unterverzeichnis `rack` im Branch `master` Deines Projekts hinterlegt: + $ git read-tree --prefix=rack/ -u rack_branch +Wenn Du jetzt einen Commit ausführst, erscheint es einem so, als ob die ganzen Dateien aus dem Rack Projekt in diesem Unterverzeichnis liegen — als ob man das Projekt aus einem Tarball-Container hineinkopiert hätte. Das Besondere ist jetzt aber, dass man Änderungen zwischen den verschiedenen Branches jetzt einfach zusammenführen kann. Das beduetet, wenn das Rack Projekt aktualisiert wird, kann man sich diese Änderungen einfach holen indem man in diese Branch wechselt und dort einen Pull durchführt: + $ git checkout rack_branch $ git pull +Danach kann man diese Änderungen wieder in den master Branch mergen. Wenn man den Befehl `git merge -s subtree` verwendet, sollte dies einwandfrei funktionieren. Allerdings wird Git bei Ausführen dieses Befehl auch die jeweilige Historie mergen, was Du wahrscheinlich nicht haben möchtest. Um nun die Änderungen zu holen und eine entsprechende Commit Nachricht vorzubereiten, hängt man einfach `--squash`, `--no-commit` und natürlich `-s subtree` als Option an: + $ git checkout master $ git merge --squash -s subtree --no-commit rack_branch Squash commit -- not updating HEAD @@ -1464,12 +1480,18 @@ Wenn man dann wieder in den Zweig mit dem Submodul zurückwechseln will, erhält +Die ganzen Änderungen des Rack Projekts wurden nun zusammengeführt, Du musst jetzt nur noch einen entsprechenden Commit durchführen. Man kann aber auch genau das Gegenteil machen: Man führt Änderungen im Unterverzeichnis `rack` des master Branch aus und mergt diese dann später in den Zweig `rack_branch`. Diesen kann man dann den Entwicklern des Rack Projekts zur Verfügung stellen. + +Um die Unterschiede zwischen dem Inhalt in Deinem Verzeichnis `rack` und dem Code im Zweig `rack_branch` anzuzeigen, kann man keinen normalen Vergleich mit `diff` durchführen. Man muss stattdessen den Befehl `git diff-tree` verwenden und als Argument den zu vergleichenden Branch angeben: + $ git diff-tree -p rack_branch +Um Dein Verzeichnis `rack` mit dem letzten Stand des Branches `master` auf dem Server zu vergleichen, kannst Du folgenden Befehl verwenden: + $ git diff-tree -p rack_remote/master From abbe03223bf378246608c95f4316fb84b6a9509c Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Fri, 3 Jan 2014 17:50:49 +0100 Subject: [PATCH 010/690] [de] First translation of chapter 6.8 (summary) --- de/06-git-tools/01-chapter6.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index e266f393e..f83fc9c52 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -1498,3 +1498,5 @@ Um Dein Verzeichnis `rack` mit dem letzten Stand des Branches `master` auf dem S ## Zusammenfassung ## + +In diesem Kapitel hast Du viele ausgeklügelte Werzeuge kennengelernt, die es Dir ermöglichen Commits und die Staging Area nach Deinen Vorstellungen zu beeinflussen. Wenn ein Problem in Deinem Projekt auftaucht, solltest Du jetzt leicht bestimmen können, welcher Commit den Fehler verursacht hat, genauso die Information wann und von wem der Fehler begangen wurde. Wenn Du andere Projekte in Deinem Projekt verwendet möchtest, hast Du jetzt mehrere Möglichkeiten kennengelernt, wie Du dies handhaben kannst. An dieser Stelle solltest Du jetzt in der Lage sein die meisten Dinge, die Du bei der täglichen Arbeit benötigst, in der Kommandozeile durchzuführen, ohne das Dir dabei Schweißperlen auf der Stirn stehen. From 13b7ee3e6bec9b4314313a3c828989bf3b9e62b1 Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Fri, 3 Jan 2014 17:54:27 +0100 Subject: [PATCH 011/690] [de] Use Dir instead of dir and Du instead of Du --- de/06-git-tools/01-chapter6.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index f83fc9c52..032a2ef52 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -14,7 +14,7 @@ Als nächstes werden wir einige sehr mächtige Werkzeuge besprechen, die Dir Git -Git erlaubt dir, Commits auf verschiedenste Art und Weise auszuwählen. Diese sind nicht immer offensichtlich, aber es ist hilfreich diese zu kennen. +Git erlaubt Dir, Commits auf verschiedenste Art und Weise auszuwählen. Diese sind nicht immer offensichtlich, aber es ist hilfreich diese zu kennen. ### Einzelne Revisionen ### @@ -145,7 +145,7 @@ Außerdem kannst Du dieselbe Syntax verwenden, um eine Zeitspanne anzugeben. Um -Das zeigt dir, wo der `master` Branch gestern war. Diese Technik funktioniert nur mit Daten, die noch im Reflog sind, d.h. man kann sie nicht für Commits verwenden, die ein älter sind als ein paar Monate. +Das zeigt Dir, wo der `master` Branch gestern war. Diese Technik funktioniert nur mit Daten, die noch im Reflog sind, d.h. man kann sie nicht für Commits verwenden, die ein älter sind als ein paar Monate. @@ -527,7 +527,7 @@ Im Allgemeinen, wirst Du `y` oder `n` nutzen wenn Du jeden Hunk stagen willst, a -Der Status der simplegit.rb ist interessant. Er zeigt dir, dass ein paar Zeilen gestagd und ein paar ungestaged sind. Du hast diese Datei teilweise gestaged. An dieser Stelle kannst Du das interaktive add Skript verlassen und `git commit` ausführen, um die teilweise gestageden Dateien zu commiten. +Der Status der simplegit.rb ist interessant. Er zeigt Dir, dass ein paar Zeilen gestagd und ein paar ungestaged sind. Du hast diese Datei teilweise gestaged. An dieser Stelle kannst Du das interaktive add Skript verlassen und `git commit` ausführen, um die teilweise gestageden Dateien zu commiten. @@ -1368,7 +1368,7 @@ In diesem Fall muss man das Verzeichnis entweder an einen anderen Ort verschiebe -Die letzte Falle in die viele Leute tappen, tritt auf, wenn man bereits vorhandene Verzeichnisse in Submodule umwandeln will. Wenn man also Dateien, die bereits von Git verwaltet werden, entfernen und in ein entsprechendes Submodul verschieben möchte, muss man vorsichtig sein. Ansonsten können schwer zu behebende Probleme mit Git auftreten. Nehmen wir zum Beispiel an, dass Du die Dateien vom Rack Projekt in ein Unterverzeichnis Deines Projekts abgelegt hast und diese jetzt aber in ein Submodul verschieben möchtest. Wenn Du das Unterverzeichnis einfach löschst und dann den Befehl `submodule add` ausführst, zeigt dir Git folgende Fehlermeldung an: +Die letzte Falle in die viele Leute tappen, tritt auf, wenn man bereits vorhandene Verzeichnisse in Submodule umwandeln will. Wenn man also Dateien, die bereits von Git verwaltet werden, entfernen und in ein entsprechendes Submodul verschieben möchte, muss man vorsichtig sein. Ansonsten können schwer zu behebende Probleme mit Git auftreten. Nehmen wir zum Beispiel an, dass Du die Dateien vom Rack Projekt in ein Unterverzeichnis Deines Projekts abgelegt hast und diese jetzt aber in ein Submodul verschieben möchtest. Wenn Du das Unterverzeichnis einfach löschst und dann den Befehl `submodule add` ausführst, zeigt Dir Git folgende Fehlermeldung an: $ rm -Rf rack/ $ git submodule add git@github.com:schacon/rack.git rack @@ -1406,7 +1406,7 @@ Dann musst Du das Submodul-Verzeichnis `rack` an einen anderen Ort verschieben, -Wenn man dann wieder in den Zweig mit dem Submodul zurückwechseln will, erhält man ein leeres Verzeichnis `rack`. Um dieses zu befüllen, kannst du entweder `git submodule update` ausführen oder Du kannst Deine Kopie von `/tmp/rack` wieder an den ursprünglichen Ort wiederherstellen. +Wenn man dann wieder in den Zweig mit dem Submodul zurückwechseln will, erhält man ein leeres Verzeichnis `rack`. Um dieses zu befüllen, kannst Du entweder `git submodule update` ausführen oder Du kannst Deine Kopie von `/tmp/rack` wieder an den ursprünglichen Ort wiederherstellen. ## Subtree Merging ## From ac5ab1130658d2425fc6a57d7e4c37e803d87ac4 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 18:06:45 +0100 Subject: [PATCH 012/690] Reviewing translation to ensure compliance within the chapter, before proceeding translation --- it/06-git-tools/01-chapter6.markdown | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index d22624086..e06ba3e1f 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -1,28 +1,16 @@ # Git Tools # -Fin'ora sono stati imparati la maggior parte dei comandi giornalieri a i -workflow che potrebbero essere necessari a gestire e mantenere un repository Git -per il controllo del codice sorgente. -Sono state compiute le attività di base per il tracciamento e il commit dei -file, ed è stato sfruttato il potere della *staging area* e argomenti leggeri il -*branching* (ramificazione) e il *merge*. +Finora hai imparato la la maggior parte dei comandi d’uso quotidiani e i workflow che potrebbero essere necessari a gestire e mantenere un repository per il controllo del codice sorgente con Git. Hai eseguito le attività di base per il tracciamento e la commit dei file, e hai sfruttato il potere della *staging area* e il *branch* (la ramificazione) e il *merge* di argomenti dall’impatto leggero. -Ora verrà esplorato un numero di cose veramente potenti che Git può fare che non -vengono necessariamente usate di base quotidianamente ma che potrebbero servire -ad un certo punto. +Vedremo ora una serie di potenzialità di Git che potresti non usare quotidianamente, ma di cui potresti averne bisogno a un certo punto. ## Selezione della revisione ## -Git permette di specificare determinati *commit* o una serie di *commit* in -diversi modi. -Non sono necessariamente evidenti ma può essere d'aiuto conoscerli. +Git ti permette di specificare una o più *commit* in diversi modi. Non sono sempre ovvi, ma è utile conoscerli. -### Singola revisione ### +### Singole versioni ### -E' possibile ovviamente riferirsi a un *commit* tramite l'hash SHA-1 che viene -dato, ma ci sono modi più alla portata degli umani per riferirsi ai *commit*. -Questa sezione delinea i diversi modi con cui ci si può riferire ad un singolo -commit. +Puoi fare riferimento a una singola commit usando l’hash SHA-1 attribuito, ma ci sono altri metodi più amichevoli per fare riferimento a una *commit*. Questa sezione delinea i modi con cui ci si può riferire a una singolo commit. ### SHA breve ### From 4277884d857c18b7f5b4f7135f4ab75e20f70416 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 18:51:20 +0100 Subject: [PATCH 013/690] Reviewing translation --- it/06-git-tools/01-chapter6.markdown | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index e06ba3e1f..602aec655 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -14,14 +14,9 @@ Puoi fare riferimento a una singola commit usando l’hash SHA-1 attribuito, ma ### SHA breve ### -Git è abbastanza intelligente da capire a quale *commit* ci si riferisce se si -fornisce i primi caratteri, purché il codice SHA-1 sia di almeno quattro -caratteri e univoco - solo un oggetto nel *repository* corrente inizia con quel -SHA-1 parziale. +Git è abbastanza intelligente da capire a quale *commit* ti riferisci scrivi i primi caratteri purché il codice SHA-1 sia di almeno quattro caratteri e sia univoco, ovvero che un solo oggetti nel *repository* attuale inizi con quel SHA-1. -Per esempio, per vedere uno specifico *commit*, supponiamo che venga eseguito un -comando 'git log' e venga identificato un *commit* dove sono state aggiunte -certe funzionalità: +Per vedere per esempio una *commit* specifica, immaginiamo di eseguire 'git log' e venga identificata una *commit* dove sono state aggiunte determinate funzionalità: $ git log commit 734713bc047d87bf7eac9674765ae793478c50d3 @@ -43,18 +38,13 @@ certe funzionalità: added some blame and merge stuff -In questo caso, scegliamo '1c002dd....' Se viene eseguito 'git show' su quel -*commit*, i seguenti comandi sono equivalenti (assumendo che le versioni più -corte siano univoche): +In questo caso scegliamo '1c002dd....'. Se vuoi eseguire 'git show' su quella *commit*, i seguenti comandi sono equivalenti (assumendo che le versioni più brevi siano univoche): $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b $ git show 1c002dd4b536e7479f $ git show 1c002d -Git riesce a capire una corta, univoca abbreviazione del valore SHA-1. Se viene -passato '--abbrev-commit' al comando 'git-log', l'*output* userà valori più -corti ma li manterrà unici; in maniera predefinita utilizza sette caratteri ma -se necessario ne userà di più per mantenere il codice SHA-1 univoco: +Git riesce a capire un valore SHA-1 intero da uno corto, abbreviato. Se usi l’opzione '--abbrev-commit' col comando 'git-log', l'*output* userà valori più corti ma garantirà che siano unici: di default usa sette caratteri ma ne userà di più se sarà necessario per mantenere l’univocità del valore SHA-1: $ git log --abbrev-commit --pretty=oneline ca82a6d changed the version number From ced105a89e1b4acc9bb04993aff79bf40e08e73a Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 18:58:45 +0100 Subject: [PATCH 014/690] Reviewing translation --- it/06-git-tools/01-chapter6.markdown | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 602aec655..c6b8026ab 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -51,10 +51,8 @@ Git riesce a capire un valore SHA-1 intero da uno corto, abbreviato. Se usi l’ 085bb3b removed unnecessary test code a11bef0 first commit -Generalmente, da otto a dieci caratteri sono più che sufficienti per essere -univoci all'interno di un progetto. -Uno dei progetti Git più grandi, il kernel Linux, inizia a necessitare 12 -caratteri, dei 40 possibili, per rimanere univoco. +Da otto a dieci caratteri sono, generalmente, più che sufficienti per essere +univoci all'interno di un progetto. Uno dei progetti Git più grandi, il kernel di Linux, inizia a necessitare 12 caratteri, dei 40 possibili, per essere univoco. ### Una breve nota su SHA-1 ### From ec260b072d9ec0c5b9e9be980c14c6eab1951f45 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 19:02:48 +0100 Subject: [PATCH 015/690] Reviewing translation --- it/06-git-tools/01-chapter6.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index c6b8026ab..0c75784aa 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -56,6 +56,7 @@ univoci all'interno di un progetto. Uno dei progetti Git più grandi, il kernel ### Una breve nota su SHA-1 ### +Arriva un momento in cui molte persone si preoccupano che Un sacco di gente si preoccupa ad un certo punto che, per una qualche casualità, potrebbe avere due oggetti nel proprio *repository* che abbiano lo stesso hash SHA-1. Cosa accadrebbe a quel punto? From e18f755aea8fae6313f9990c088629773c94e98a Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 19:15:00 +0100 Subject: [PATCH 016/690] Reviewed "Una breve nota su SHA-1" --- it/06-git-tools/01-chapter6.markdown | 34 +++++++--------------------- 1 file changed, 8 insertions(+), 26 deletions(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 0c75784aa..c44e8b2dd 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -56,34 +56,16 @@ univoci all'interno di un progetto. Uno dei progetti Git più grandi, il kernel ### Una breve nota su SHA-1 ### -Arriva un momento in cui molte persone si preoccupano che -Un sacco di gente si preoccupa ad un certo punto che, per una qualche casualità, -potrebbe avere due oggetti nel proprio *repository* che abbiano lo stesso hash -SHA-1. Cosa accadrebbe a quel punto? - -Se capita di fare il *commit* di un oggetto che ha lo stesso SHA-1 di un oggetto -precedente nel proprio *repository*, Git noterà il precedente oggetto già -presente nel database Git e lo riterrà già scritto. -Provando ad ottenere informazioni su quell'oggetto nuovamente ad un certo punto, -verranno sempre restituiti i dati del primo oggetto. - -Ad ogni modo, è necessario essere consapevoli di quanto ridicolmente improbabile -sia questo scenario. Il codice SHA-1 riassunto è di 20 bytes o 160 bits. Il -numero casuale di oggetti necessari per assicurare un 50% di una singola -collisione è di circa 2^80 (la formula per determinare la probabilità di -collisione è `p = (n(n-1)/2) * (1/2^160))`. 2^80 è 1.2 x 10^24 o un milione di -miliardi di miliardi. E' 1,200 volte il numero di granelli di sabbia sulla -terra. +Arriva un momento in cui molte persone si preoccupano che possano avere, per puro caso, due oggetti nel proprio *repository* che abbiano lo stesso hash SHA-1. E allora? + +Se capita di fare la *commit* di un oggetto a che abbia lo stesso SHA-1 di un oggetto +già presente nel tuo *repository*, Git vedrà l’oggetto precedente già nel database di Git e lo riterrà già scritto. Se successivamente proverai a fare il checkout di quest’ultimo oggetto, otterrai sempre i dati del primo oggetto. + +Ad ogni modo, è necessario essere consapevoli di quanto sia ridicolmente improbabile +questo scenario. Il codice SHA-1 è di 20 bytes o 160 bits. Il numero di oggetti casuali necessari perché ci sia la probabilità del 50% di una singola collisione è di circa 2^80 (la formula per determinare la probabilità di collisione è `p = (n(n-1)/2) * (1/2^160))`. 2^80 è 1.2 x 10^24 ovvero un milione di miliardi di miliardi. È 1.200 volte il numero di granelli di sabbia sulla terra. Ecco un esempio per dare un'idea di cosa ci vorrebbe per ottenere una collisione -SHA-1. Se tutti i 6.5 miliardi di esseri umani sulla Terra stessero -programmando, e ogni secondo, ognuno stesse producendo codice che fosse -equivalente all'intera storia del kernel Linux (1 milione di oggetti Git) e se -lo stesse caricando su un enorme *repository* Git, ci vorrebbero 5 anni per -contenere abbastanza oggetti in quel *repository* da avere il 50% di possibilità -di una singola collisione di oggetti SHA-1. Esiste una probabilità più alta che -ogni membro del team venga attaccato e ucciso dai lupi in situazioni -indipendenti durante la stessa notte. +SHA-1. Se tutti i 6.5 miliardi di esseri umani sulla Terra programmassero e, ogni secondo, ognuno scrivesse codice che fosse equivalente all'intera cronologia del kernel Linux (1 milione di oggetti Git) e ne facesse la push su un enorme *repository* Git, ci vorrebbero 5 anni per contenere abbastanza oggetti in quel *repository* per avere il 50% di possibilità di una singola collisione di oggetti SHA-1. Esiste una probabilità più alta che ogni membro del tuo gruppo di sviluppo, per pura coincidenza, venga attaccato e ucciso da dei lupi nella stessa notte. ### Riferimenti al *branch* ### From 551e61c66e505541ae0dbe5a93f94c2d258142cc Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 19:24:16 +0100 Subject: [PATCH 017/690] Reviewing translation --- it/06-git-tools/01-chapter6.markdown | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index c44e8b2dd..f0fead5e5 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -67,25 +67,14 @@ questo scenario. Il codice SHA-1 è di 20 bytes o 160 bits. Il numero di oggetti Ecco un esempio per dare un'idea di cosa ci vorrebbe per ottenere una collisione SHA-1. Se tutti i 6.5 miliardi di esseri umani sulla Terra programmassero e, ogni secondo, ognuno scrivesse codice che fosse equivalente all'intera cronologia del kernel Linux (1 milione di oggetti Git) e ne facesse la push su un enorme *repository* Git, ci vorrebbero 5 anni per contenere abbastanza oggetti in quel *repository* per avere il 50% di possibilità di una singola collisione di oggetti SHA-1. Esiste una probabilità più alta che ogni membro del tuo gruppo di sviluppo, per pura coincidenza, venga attaccato e ucciso da dei lupi nella stessa notte. -### Riferimenti al *branch* ### +### Riferimenti ai *branch* ### -La strada più diretta per specificare un *commit* richiede che punti ad un -riferimento di un *branch*. A quel punto potrebbe essere usato il nome del -*branch* in qualsiasi comando Git che richiede un oggetto *commit* o un valore -SHA-1. Per esempio, se si vuole mostrare l'ultimo oggetto *commit* di un -*branch*, i seguenti comandi sono equivalenti, ammesso che il *branch* 'topic1' -punti a 'ca82a6d': +Il modo più diretto per specificare una *commit* è avere un *branch* che vi faccia riferimento, che ti permetterebbe di usare il nome del *branch* in qualsiasi comando Git che richieda un oggetto *commit* o un valore SHA-1. Se vuoi, per esempio, mostrare l'ultima *commit* di un *branch*, i seguenti comandi sono equivalenti, supponendo che il *branch* 'topic1' punti a 'ca82a6d': $ git show ca82a6dff817ec66f44342007202690a93763949 $ git show topic1 -Se si vuole vedere a quale specifico SHA un *branch* punta, o se si vuole vedere -a cosa si riduce ognuno di questi esempi in termini di SHA, si può usare un -*plumbing tool* di Git chiamato 'rev-parse'. Nel Capitolo 9 ci sono più informazioni -sui *plumbing tool*; sostanzialmente, 'rev-parse' esiste per operazioni di basso -livello e non è concepito per essere usato in operazioni quotidiane. Comunque, -può essere d'aiuto a volte quanto c'è bisogno di vedere cosa succede realmente. -A quel punto si può lanciare 'rev-parse' sul proprio *branch*. +Se vuoi vedere a quale SHA specifico punti un *branch*, o se vuoi vedere a quale SHA puntino questi esempi, puoi usare il comando 'rev-parse' di Git, che fa parte dei comandi *plumbing* . Nel Capitolo 9 trovi maggiori informazioni sui comandi *plumbing*: brevemente, 'rev-parse' esiste per operazioni di basso livello e non è concepito per essere usato nelle operazioni quotidiane. Può Comunque essere d'aiuto quando hai bisogno di vedere cosa sta succedendo. Puoi quindi eseguire 'rev-parse' su tuo *branch*. $ git rev-parse topic1 ca82a6dff817ec66f44342007202690a93763949 From 9a8c4a124b79338bd6597a590e65ec7a432c5359 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 19:30:56 +0100 Subject: [PATCH 018/690] Fixed typo --- it/09-git-internals/01-chapter9.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/09-git-internals/01-chapter9.markdown b/it/09-git-internals/01-chapter9.markdown index 2bcf1ca5e..820f5b305 100644 --- a/it/09-git-internals/01-chapter9.markdown +++ b/it/09-git-internals/01-chapter9.markdown @@ -837,7 +837,7 @@ Muovi ora il branch `master` a una commit centrale: Così facendo hai perso le due commit più recenti: questa commit non sono più raggiungibili in nessun modo. Devi scoprire l’hash SHA dell’ultima commit e aggiungere quindi un branch che vi punti. Il trucco è trovare l’hash SHA dell’ultima commit: non è come lo ricordavi, vero? -Spesso il modo più veloce è usare `git reflog`. Mentre lavori Git memorizza silenziosamente lo stato del tuo HEAD ogni volta che lo cambi. IL reflag viene aggiornato ogni volta che fai una commit o cambi un branch. Il reflog viene aggiornato anche dal comando `git update-ref`, che è un’altra buona ragione per usarlo, invece di scrivere direttamente il valore dell’SHA nei tuoi file ref, come abbiamo visto nella sezione “I Riferimenti di Git" in questo stesso capitolo. Eseguendo `git reflog` puoi vedere dov’eri in qualsiasi dato momento: +Spesso il modo più veloce è usare `git reflog`. Mentre lavori Git memorizza silenziosamente lo stato del tuo HEAD ogni volta che lo cambi. IL reflog viene aggiornato ogni volta che fai una commit o cambi un branch. Il reflog viene aggiornato anche dal comando `git update-ref`, che è un’altra buona ragione per usarlo, invece di scrivere direttamente il valore dell’SHA nei tuoi file ref, come abbiamo visto nella sezione “I Riferimenti di Git" in questo stesso capitolo. Eseguendo `git reflog` puoi vedere dov’eri in qualsiasi dato momento: $ git reflog 1a410ef HEAD@{0}: 1a410efbd13591db07496601ebc7a059dd55cfe9: updating HEAD From aeb37a2bf6705ea30a40be1f3199a750a24b309a Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 19:31:15 +0100 Subject: [PATCH 019/690] Fixed typo --- it/09-git-internals/01-chapter9.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/09-git-internals/01-chapter9.markdown b/it/09-git-internals/01-chapter9.markdown index 820f5b305..b39dc0830 100644 --- a/it/09-git-internals/01-chapter9.markdown +++ b/it/09-git-internals/01-chapter9.markdown @@ -837,7 +837,7 @@ Muovi ora il branch `master` a una commit centrale: Così facendo hai perso le due commit più recenti: questa commit non sono più raggiungibili in nessun modo. Devi scoprire l’hash SHA dell’ultima commit e aggiungere quindi un branch che vi punti. Il trucco è trovare l’hash SHA dell’ultima commit: non è come lo ricordavi, vero? -Spesso il modo più veloce è usare `git reflog`. Mentre lavori Git memorizza silenziosamente lo stato del tuo HEAD ogni volta che lo cambi. IL reflog viene aggiornato ogni volta che fai una commit o cambi un branch. Il reflog viene aggiornato anche dal comando `git update-ref`, che è un’altra buona ragione per usarlo, invece di scrivere direttamente il valore dell’SHA nei tuoi file ref, come abbiamo visto nella sezione “I Riferimenti di Git" in questo stesso capitolo. Eseguendo `git reflog` puoi vedere dov’eri in qualsiasi dato momento: +Spesso il modo più veloce è usare `git reflog`. Mentre lavori Git memorizza silenziosamente lo stato del tuo HEAD ogni volta che lo cambi. Il reflog viene aggiornato ogni volta che fai una commit o cambi un branch. Il reflog viene aggiornato anche dal comando `git update-ref`, che è un’altra buona ragione per usarlo, invece di scrivere direttamente il valore dell’SHA nei tuoi file ref, come abbiamo visto nella sezione “I Riferimenti di Git" in questo stesso capitolo. Eseguendo `git reflog` puoi vedere dov’eri in qualsiasi dato momento: $ git reflog 1a410ef HEAD@{0}: 1a410efbd13591db07496601ebc7a059dd55cfe9: updating HEAD From 84305e50526f18673c9d5f35a27a0918484f75c3 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 19:35:15 +0100 Subject: [PATCH 020/690] Reviewing translation --- it/06-git-tools/01-chapter6.markdown | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index f0fead5e5..9efcffa29 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -79,12 +79,11 @@ Se vuoi vedere a quale SHA specifico punti un *branch*, o se vuoi vedere a quale $ git rev-parse topic1 ca82a6dff817ec66f44342007202690a93763949 -### RefLog ### +### Nomi brevi di RefLog ### -Una delle cose che Git fa mentre si lavora è tenere un reflog - un log sui -riferimenti di *HEAD* e *branch* degli ultimi mesi. +Una delle cose che Git fa dietro le quinte è aggiornare il file reflog, che memorizza silenziosamente la posizione negli ultimi mesi del tuo HEAD e dei riferimenti ai tuoi branch , ogni volta che li cambi. -E' possibile vedere il reflog usando il comando 'git reflog': +Puoi consultare il reflog con il comando 'git reflog': $ git reflog 734713b... HEAD@{0}: commit: fixed refs handling, added gc auto, updated From 80adfd77d793668ed07c8c17f473629408406b0a Mon Sep 17 00:00:00 2001 From: Tuan Vu Date: Fri, 3 Jan 2014 18:44:48 +0000 Subject: [PATCH 021/690] =?UTF-8?q?using=20't=C3=ADch=20h=E1=BB=A3p'=20ins?= =?UTF-8?q?tead=20of=20'g=E1=BB=99p'=20as=20translation=20for=20merge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vi/02-git-basics/01-chapter2.markdown | 22 +-- vi/03-git-branching/01-chapter3.markdown | 211 ++++++++++++----------- 2 files changed, 117 insertions(+), 116 deletions(-) diff --git a/vi/02-git-basics/01-chapter2.markdown b/vi/02-git-basics/01-chapter2.markdown index 73ef3e6a7..5904099a7 100644 --- a/vi/02-git-basics/01-chapter2.markdown +++ b/vi/02-git-basics/01-chapter2.markdown @@ -107,7 +107,7 @@ Hãy sửa một tập tin đang được theo dõi. Nếu bạn sửa một t # modified: benchmarks.rb # -Tập tin `benchmarks.rb` nằm trong danh sách "Các thay đổi chưa được tổ chức/đánh dấu để commit" - có nghĩa là một tập tin đang được theo dõi đã bị thay đổi trong thư mục làm việc nhưng chưa được "staged". Để làm việc này, bạn chạy lệnh `git add` (đó là một câu lệnh đa chức năng - bạn có thể dùng nó để bắt đầu theo dõi tập tin, tổ chức tập tin, hoặc các việc khác như đánh dấu đã giải quyết xong các tập tin có nội dung mâu thuẫn nhau khi gộp). Chạy `git add` để "stage" tập tin `benchmarks.rb` và sau đó chạy lại lệnh `git status`: +Tập tin `benchmarks.rb` nằm trong danh sách "Các thay đổi chưa được tổ chức/đánh dấu để commit" - có nghĩa là một tập tin đang được theo dõi đã bị thay đổi trong thư mục làm việc nhưng chưa được "staged". Để làm việc này, bạn chạy lệnh `git add` (đó là một câu lệnh đa chức năng - bạn có thể dùng nó để bắt đầu theo dõi tập tin, tổ chức tập tin, hoặc các việc khác như đánh dấu đã giải quyết xong các tập tin có nội dung mâu thuẫn nhau khi tích hợp). Chạy `git add` để "stage" tập tin `benchmarks.rb` và sau đó chạy lại lệnh `git status`: $ git add benchmarks.rb $ git status @@ -589,7 +589,7 @@ The lines must be formatted as follows Có thể bạn băn khoăn về sự khác nhau giữa _tác giả_ (author) và _người commit_ (committer). _Tác giả_ là người đầu tiên viết bản vá (patch), trong khi đó _người commit_ là người cuối cùng áp dụng miếng vá đó. Như vậy, nếu bạn gửi một bản vá cho một dự án và một trong các thành viên chính của dự án "áp dụng" (chấp nhận) bản vá đó, cả hai sẽ cùng được ghi nhận công trạng (credit) - bạn với vai trò là tác giả và thành viên của dự án trong vai trò người commit. Chúng ta sẽ bàn kỹ hơn một chút về sự khác nhau này trong *Chương 5*. -Lựa chọn `oneline` và `formar` đặc biệt hữu ích khi sử dụng với một tham số khác của `log` là `--graph`. Khi sử dụng, tham số này sẽ thêm một biểu đồ sử dụng dựa trên các ký tự ASCII hiển thị nhánh và lịch sử gộp các tập tin của bạn, chúng ta có thể thấy trong dự án Grit như sau: +Lựa chọn `oneline` và `formar` đặc biệt hữu ích khi sử dụng với một tham số khác của `log` là `--graph`. Khi sử dụng, tham số này sẽ thêm một biểu đồ sử dụng dựa trên các ký tự ASCII hiển thị nhánh và lịch sử tích hợp các tập tin của bạn, chúng ta có thể thấy trong dự án Grit như sau: $ git log --pretty=format:"%h %s" --graph * 2d3acf9 ignore errors from SIGCHLD on trap @@ -619,7 +619,7 @@ The lines must be formatted as follows --name-status Hiển thị các tập tin bị ảnh hưởng với các thông tin như thêm mới/sửa/xoá. --abbrev-commit Chỉ hiện thị một số ký tự đầu của mã băm SHA-1 thay vì tất cả 40. --relative-date Hiển thị ngày ở định dạng tương đối (ví dụ, "2 weeks ago") thay vì định dạng đầy đủ. - --graph Hiển thị biểu đồ ASCII của nhánh và lịch sử gộp cùng với thông tin đầu ra khác. + --graph Hiển thị biểu đồ ASCII của nhánh và lịch sử tích hợp cùng với thông tin đầu ra khác. --pretty Hiện thị các commit sử dụng một định dạng khác. Các lựa chọn bao gồm oneline, short, full, fuller và format (cho phép bạn sử dụng định dạng riêng). --oneline Một lựa chọn ngắn, thuận tiện cho `--pretty=oneline --abbrev-commit`. @@ -651,7 +651,7 @@ The lines must be formatted as follows --author Chỉ hiện thị các commit mà tên tác giả thoả mãn điều kiện nhất định. --committer Chỉ hiện thị các commit mà tên người commit thoả mãn điều kiện nhất định. -Ví dụ, bạn muốn xem các commit đã thay đổi các tập tin thử nghiệm trong lịch sử mã nguồn của Git, được commit bởi Junio Hâmno trng tháng 10 năm 2008 mà chưa được gộp/trộn, bạn có thể chạy lệnh sau: +Ví dụ, bạn muốn xem các commit đã thay đổi các tập tin thử nghiệm trong lịch sử mã nguồn của Git, được commit bởi Junio Hâmno trng tháng 10 năm 2008 mà chưa được tích hợp/gộp, bạn có thể chạy lệnh sau: $ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \ --before="2008-11-01" --no-merges -- t/ @@ -815,7 +815,7 @@ Bây giờ bạn có thể sử dụng `pb` trong các câu lệnh, nó có tác * [new branch] master -> pb/master * [new branch] ticgit -> pb/ticgit -Nhánh chính của Paul có thể truy cập cục bộ như là `pb/master` - bạn có thể gộp nó vào các nhánh của bạn, hoặc sử dụng nó như là một nhánh cục bộ ở thời điểm đó nếu như bạn muốn kiểm tra nó. +Nhánh chính của Paul có thể truy cập cục bộ như là `pb/master` - bạn có thể tích hợp nó vào các nhánh của bạn, hoặc sử dụng nó như là một nhánh cục bộ ở thời điểm đó nếu như bạn muốn kiểm tra nó. ### Truy Cập Và Kéo Về Từ Máy Chủ Trung Tâm ### @@ -823,11 +823,11 @@ Như bạn vừa thấy, để lấy dữ liệu của các dự án từ xa v $ git fetch [remote-name] -Lệnh này sẽ truy cập vào dự án từ xa đó và kéo xuống toàn bộ dữ liệu mà bạn chưa có trong đó cho bạn. Sau khi thực hiện xong bước này, bạn đã có các tham chiếu đến toàn bộ các nhánh của dự án từ xa đó, nơi mà bạn có thể gộp hoặc kiểm tra bất kỳ thời điểm nào. (Chúng ta sẽ đề cập chi tiết hơn về nhánh là gì và sử dụng chúng như thế nào ở *Chương 3*.) +Lệnh này sẽ truy cập vào dự án từ xa đó và kéo xuống toàn bộ dữ liệu mà bạn chưa có trong đó cho bạn. Sau khi thực hiện xong bước này, bạn đã có các tham chiếu đến toàn bộ các nhánh của dự án từ xa đó, nơi mà bạn có thể tích hợp hoặc kiểm tra bất kỳ thời điểm nào. (Chúng ta sẽ đề cập chi tiết hơn về nhánh là gì và sử dụng chúng như thế nào ở *Chương 3*.) -Nếu bạn tạo bản sao từ một kho chứa nào đó khác, lệnh này sẽ tự động kho chứa từ xa đó vào dưới tên *origin*. Vì thế, `git fetch origin` sẽ truy xuất (fetch) bất kỳ thay đổi mới nào được đẩy lên trên máy chủ từ sau khi bạn sao chép (hoặc lần truy xuất cuối cùng). Hãy ghi nhớ một điều quan trọng là lệnh `fetch` kéo tất cả dữ liệu về kho chứa trên máy của bạn - nó không tự động gộp với bất kỳ thay đổi nào mà bạn đang thực hiện. Bạn phải gộp nó một cách thủ không vào kho chứa nội bộ khi đã sẵn sàng. +Nếu bạn tạo bản sao từ một kho chứa nào đó khác, lệnh này sẽ tự động kho chứa từ xa đó vào dưới tên *origin*. Vì thế, `git fetch origin` sẽ truy xuất (fetch) bất kỳ thay đổi mới nào được đẩy lên trên máy chủ từ sau khi bạn sao chép (hoặc lần truy xuất cuối cùng). Hãy ghi nhớ một điều quan trọng là lệnh `fetch` kéo tất cả dữ liệu về kho chứa trên máy của bạn - nó không tự động tích hợp với bất kỳ thay đổi nào mà bạn đang thực hiện. Bạn phải tích hợp nó một cách thủ không vào kho chứa nội bộ khi đã sẵn sàng. -Nếu bạn có một nhánh được cài đặt để theo dõi một nhánh từ xa khác (xem phần tiếp theo và *Chương 3* để biết thêm chi tiết), bạn có thể sử dụng lệnh `git pull` để tự động truy xuất và sau đó gộp nhánh từ xa vào nhánh nội bộ. Đây có thể là cách dễ dàng và thoải mái hơn cho bạn; và mặc định thì, lệnh `git clone` tự động cài đặt nhánh chính nội bộ (local master branch) để theo dõi nhanh chính trên máy chủ từ xa (remote master branch) - nơi mà bạn sao chép về, (giả sử máy chủ từ xa có một nhánh chính). Thường thì khi chạy lệnh `git pull` nó sẽ truy xuất dữ liệu từ máy chủ trung tâm nơi lần đầu bạn sao chép và cố gắng tự động gộp chúng vào kho chứa hiện thời nơi bạn đang làm việc. +Nếu bạn có một nhánh được cài đặt để theo dõi một nhánh từ xa khác (xem phần tiếp theo và *Chương 3* để biết thêm chi tiết), bạn có thể sử dụng lệnh `git pull` để tự động truy xuất và sau đó tích hợp nhánh từ xa vào nhánh nội bộ. Đây có thể là cách dễ dàng và thoải mái hơn cho bạn; và mặc định thì, lệnh `git clone` tự động cài đặt nhánh chính nội bộ (local master branch) để theo dõi nhanh chính trên máy chủ từ xa (remote master branch) - nơi mà bạn sao chép về, (giả sử máy chủ từ xa có một nhánh chính). Thường thì khi chạy lệnh `git pull` nó sẽ truy xuất dữ liệu từ máy chủ trung tâm nơi lần đầu bạn sao chép và cố gắng tự động tích hợp chúng vào kho chứa hiện thời nơi bạn đang làm việc. ### Đẩy Lên Máy Chủ Trung Tâm ### @@ -835,7 +835,7 @@ Nếu bạn có một nhánh được cài đặt để theo dõi một nhánh t $ git push origin master -Lệnh này chỉ hoạt động nếu bạn sao chép từ một máy chủ mà trên đó bạn được cấp phép quyền ghi và chưa có ai khác đẩy dữ liệu lên tại thời điểm đó. Nếu bạn và ai khác cùng sao chép tại cùng một thời điểm; người kia đẩy ngược lên, sau đó bạn cũng muốn đẩy lên, thì hành động của bạn sẽ bị từ chối ngay tức khắc. Trước hết bạn phải thực hiện kéo các thay đổi mà người đó đã thực hiện và sát nhập/gộp nó vào của bạn, sau đó bạn mới được phép đẩy lên. Xem *Chương 3* để hiểu chi tiết hơn về làm thế nào để đẩy lên máy chủ trung tâm. +Lệnh này chỉ hoạt động nếu bạn sao chép từ một máy chủ mà trên đó bạn được cấp phép quyền ghi và chưa có ai khác đẩy dữ liệu lên tại thời điểm đó. Nếu bạn và ai khác cùng sao chép tại cùng một thời điểm; người kia đẩy ngược lên, sau đó bạn cũng muốn đẩy lên, thì hành động của bạn sẽ bị từ chối ngay tức khắc. Trước hết bạn phải thực hiện kéo các thay đổi mà người đó đã thực hiện và tích hợp/gộp nó vào của bạn, sau đó bạn mới được phép đẩy lên. Xem *Chương 3* để hiểu chi tiết hơn về làm thế nào để đẩy lên máy chủ trung tâm. ### Kiểm Tra Một Máy Chủ Trung Tâm ### @@ -850,7 +850,7 @@ Nếu bạn muốn xem chi tiết hơn các thông tin về một kho chứa tru master ticgit -Lệnh này liệt kê địa chỉ của kho chứa trung tâm cũng như thông tin các nhánh đang theo dõi. Nó cho bạn biết rằng nếu như bạn đang ở nhánh master và chạy lệnh git pull, nó sẽ tự động gộp nhánh này với nhánh trung tâm sau khi truy xuất toàn bộ các tham chiếu từ xa. Nó cũng liệt kê tất cả các tham chiếu từ xa mà nó đã kéo xuống đó. +Lệnh này liệt kê địa chỉ của kho chứa trung tâm cũng như thông tin các nhánh đang theo dõi. Nó cho bạn biết rằng nếu như bạn đang ở nhánh master và chạy lệnh git pull, nó sẽ tự động tích hợp nhánh này với nhánh trung tâm sau khi truy xuất toàn bộ các tham chiếu từ xa. Nó cũng liệt kê tất cả các tham chiếu từ xa mà nó đã kéo xuống đó. Đây là một ví dụ đơn giản mà bạn thường xuyên gặp phải. Khi bạn sử dụng Git thường xuyên hơn, bạn sẽ thường thấy nhiều thông tin hơn từ lệnh `git remote show`: @@ -876,7 +876,7 @@ Lệnh này liệt kê địa chỉ của kho chứa trung tâm cũng như thôn Local branch pushed with 'git push' master:master -Lệnh này hiển thị nhánh nào tự động được đẩy lên khi bạn chạy `git push` trên một nhánh nhất định. Nó cũng cho bạn thấy nhánh nào trên máy chủ trung tâm mà bạn chưa có, nhánh nào bạn có mà đã bị xóa trên máy chủ, và các nhánh nào sẽ tự động được gộp khi chạy lệnh `git pull`. +Lệnh này hiển thị nhánh nào tự động được đẩy lên khi bạn chạy `git push` trên một nhánh nhất định. Nó cũng cho bạn thấy nhánh nào trên máy chủ trung tâm mà bạn chưa có, nhánh nào bạn có mà đã bị xóa trên máy chủ, và các nhánh nào sẽ tự động được tích hợp khi chạy lệnh `git pull`. ### Xóa Và Đổi Tên Từ Xa ### diff --git a/vi/03-git-branching/01-chapter3.markdown b/vi/03-git-branching/01-chapter3.markdown index 8924dbe5e..6feadfe84 100644 --- a/vi/03-git-branching/01-chapter3.markdown +++ b/vi/03-git-branching/01-chapter3.markdown @@ -1,152 +1,152 @@ -# Git Branching # +# Phân Nhánh Trong Git # -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. +Hầu hết mỗi hệ quản trị phiên bản (VCS) đều hỗ trợ một dạng của phân nhánh. Phân nhánh có nghĩa là bạn phân tách ra từ luồng phát triển chính và tiếp tục làm việc mà không sợ làm ảnh hưởng đến luồng chính. Trong nhiều VCS, đây dường như là một quá trình đòi hỏi nhiều công sức và sự cố gắng, thường thì bạn tạo một bản sao mới từ thư mục chứa mã nguồn, nó có thể mất khá nhiều thời gian trên các dự án lớn. -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. +Nhiều người nhắc đến mô hình phân nhánh của Git như là "chức năng hủy diệt", và chính nó làm cho Git trở nên khác biệt trong cộng đồng VCS. Tại sao nó lại đặc biệt đến vậy? Cách Git phân nhánh "nhẹ" một cách đáng kinh ngạc, các hoạt động tạo nhánh xảy ra gần như ngay lập tức và việc di chuyển đi lại giữa các nhánh cũng thường rất nhanh. Không giống các VCSs khác, Git khuyến khích sử dụng rẽ nhánh và tích hợp thường xuyên cho workflow, thậm chí nhiều lần trong một ngày. Hiểu và thành thạo tính năng này cung cấp cho bạn một công cụ mạnh mẽ, độc đáo và có thể thay đổi được cách bạn thường phát triển phần mềm. -## What a Branch Is ## +## Nhánh Là Gì? ## -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. +Để có thể thực sử hiểu được cách phân nhánh của Git, chúng ta cần nhìn và xem xét lại cách Git lưu trữ dữ liệu. Như bạn đã biết từ Chương 1, Git không lưu trữ dữ liệu dưới dạng một chuỗi các thay đổi hoặc delta, mà thay vào đó là một chuỗi các ảnh (snapshot). -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. +Khi bạn commit, Git lưu trữ đối tượng commit mà có chứa một con trỏ tới ảnh của nội dung bạn đã tổ chức (stage), tác giả và thông điệp, hay 0 hoặc nhiều con trỏ khác trỏ tới một hoặc nhiều commit cha trực tiếp của commit đó: commit đầu tiên không có cha, commit bình thường có một cha, và nhiều cha cho commit là kết quả được tích hợp lại từ hai hoặc nhiều nhánh. -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: +Để hình dung ra vấn đề này, hãy giả sử bạn có một thư mục chứa ba tập tin, và bạn tổ chức tất cả chúng để commit. Quá trình tổ chức các tập tin sẽ thực hiện băm từng tập (sử dụng mã SHA-1 được đề cập ở Chương 1), lưu trữ phiên bản đó của tập tin trong kho chứa Git (Git xem chúng như là các blob), và thêm mã băm đó vào khu vực tổ chức: $ 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. +Lệnh `git commit` khi chạy sẽ băm tất cả các thư mục trong dự án và lưu chúng lại dưới dạng đối tượng `tree`. Sau đó Git tạo một đối tượng `commit` có chứa các thông tin mô tả (metadata) và một con trỏ trỏ tới đối tương `tree` gốc của dự án vì thế nó có thể tạo lại ảnh đó khi cần thiết. -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. +Kho chứa Git của bạn bây giờ có chứa năm đối tượng: một blob cho nội dung của từng tập tin, một "cây" liệt kê nội dung của thư mục và chỉ rõ tên tập tin nào được lưu trữ trong blob nào, và một commit có con trỏ trỏ tới cây gốc và tất cả các thông tin mô tả commit. Về mặt lý thuyết, dữ liệu trong kho chứa Git có hình dạng như trong Hình 3-1. Insert 18333fig0301.png -Figure 3-1. Single commit repository data. +Hình 3-1. Dữ liệu trong kho chứa với một commit. -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. +Nếu bạn thực hiện một số thay đổi và commit lại thì commit tiếp theo sẽ lưu một con trỏ tới commit ngay trước nó. Sau hai commit, lịch sử của dự án sẽ tương tự như trong Hình 3-2. Insert 18333fig0302.png -Figure 3-2. Git object data for multiple commits. +Hình 3-2. Các đối tượng dữ liệu của Git trong kho chứa nhiều commit. -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. +Một nhánh trong Git đơn thuần là một con trỏ có khả năng di chuyển được, trỏ đến một trong những commit này. Tên nhánh mặc định của Git là master. Như trong những lần commit đầu tiên, chúng đều được trỏ tới nhánh `master`. Và mỗi lần bạn thực hiện commit, nó sẽ được tự động ghi vào theo hướng tiến lên. (move forward) Insert 18333fig0303.png -Figure 3-3. Branch pointing into the commit data’s history. +Hình 3-3. Nhánh trỏ tới dữ liệu commit. -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: +Chuyện gì xảy ra nếu bạn tạo một nhánh mới? Làm như vậy sẽ tạo ra một con trỏ mới cho phép bạn di chuyển vòng quanh. Ví dụ bạn tạo một nhánh mới có tên testing. Việc này được thực hiện bằng lệnh `git branch`: $ git branch testing -This creates a new pointer at the same commit you’re currently on (see Figure 3-4). +Nó sẽ tạo một con trỏ mới, cùng trỏ tới commit hiện tại (mới nhất) của bạn (xem Hình 3-4). Insert 18333fig0304.png -Figure 3-4. Multiple branches pointing into the commit’s data history. +Hình 304. Nhiều nhánh cùng trỏ vào dữ liệu commit. -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). +Vậy làm sao Git có thể biết được rằng bạn đang làm việc trên nhánh nào? Git giữ một con trỏ đặc biệt có tên HEAD. Lưu ý khái niệm về HEAD ở đây khác biệt hoàn toàn với các VCS khác mà bạn có thể đã sử dụng qua, như là Subversion hoặc CVS. Trong Git, đây là một con trỏ tới nhánh nội bộ mà bạn đang làm việc. Trong trường hợp này, bạn vẫn đang trên nhánh master. Lệnh git branch chỉ tạo một nhánh mới chứ không tự chuyển sang nhánh đó cho bạn (xem Hình 3-5). Insert 18333fig0305.png -Figure 3-5. HEAD file pointing to the branch you’re on. +Hình 3-5. Tập tin HEAD trỏ tới nhánh mà bạn đang làm việc. -To switch to an existing branch, you run the `git checkout` command. Let’s switch to the new testing branch: +Để chuyển sang một nhánh đang tồn tại, bạn sử dụng lệnh `git checkout`. Hãy cùng chuyển sang nhánh testing mới: $ git checkout testing -This moves HEAD to point to the testing branch (see Figure 3-6). +Lệnh này sẽ chuyển con trỏ HEAD sang nhánh testing (xem Hình 3-6). Insert 18333fig0306.png -Figure 3-6. HEAD points to another branch when you switch branches. +Hình 3-6. HEAD trỏ tới nhánh khác khi bạn chuyển nhánh. -What is the significance of that? Well, let’s do another commit: +Ý nghĩa của việc này là gì? Hãy cùng thực hiện một commit khác: $ vim test.rb $ git commit -a -m 'made a change' -Figure 3-7 illustrates the result. +Hình 3-7 minh họa kết quả. Insert 18333fig0307.png -Figure 3-7. The branch that HEAD points to moves forward with each commit. +Hình 3-7. Nhánh mà HEAD trỏ tới di chuyển tiến lên phía trước theo từng 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: +Điều này thật thú vị, bởi vì nhánh testing của bạn bây giờ đã tiển hẳn lên phía trước, nhưng nhánh `master` thì vẫn trỏ tới commit ở thời điểm khi bạn chạy lệnh `git checkout` để chuyển nhánh. Hãy cùng chuyển trở lại nhánh `master`: $ git checkout master -Figure 3-8 shows the result. +Hình 3-8 hiển thị kết quả. Insert 18333fig0308.png -Figure 3-8. HEAD moves to another branch on a checkout. +Hình 3-8. HEAD chuyển sang nhánh khác khi 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. +Lệnh này vừa thực hiện hai việc. Nó di chuyển lại con trỏ về nhánh `master`, và sau đó nó phục hồi lại các tập tin trong thư mục làm việc của bạn trở lại snapshot mà `master` trỏ tới. Điều này cũng có nghĩa là các thay đổi bạn thực hiện từ thời điểm này trở đi sẽ tách ra so với phiên bản cũ hơn của dự án. Nó "tua lại" các thay đổi cần thiết mà bạn đã thực hiện trên nhánh `testing` một cách tạm thời để bạn có thể đi theo một hướng khác. -Let’s make a few changes and commit again: +Hãy cùng tạo một vài thay đổi và commit lại một lần nữa: $ 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. +Bây giờ lịch sử của dự án đã bị tách ra (xem Hình 3-9). Bạn tạo mới và chuyển sang một nhánh, thực hiện một số thay đổi trên đó, và rồi chuyển ngược lại nhánh chính và tạo thêm các thay đổi khác. Cả hai sự thay đổi này bị cô lập với nhau ở hai nhánh riêng biệt: bạn có thể chuyển đi hoặc lại giữa cách nhánh và tích hợp chúng lại với nhau khi cần thiết. Và bạn đã thực hiện những việc trên một cách đơn giản với lệnh `branch` và `checkout`. Insert 18333fig0309.png -Figure 3-9. The branch histories have diverged. +Hình 3-9. Lịch sử các nhánh đã bị phân tách. -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). +Bởi vì một nhánh trong Git thực tế là một tập tin đơn giản chứa một mã băm SHA-1 có độ dài 40 ký tự của commit mà nó trỏ tới, chính vì thế tạo mới cũng như hủy các nhánh đi rất đơn giản. Tạo mới một nhánh nhanh tương đương với việc ghi 41 bytes vào một tập tin (40 ký tự cộng thêm một dòng mới). -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. +Điều này đối lập rất lớn với cách mà các VCS khác phân nhánh, chính là copy toàn bộ các tập tin hiện có của dự án sang một thư mục thứ hai. Việc này có thể mất khoảng vài giây, thậm chí vài phút, phụ thuộc vào dung lượng của dự án, trong khi đó trong Git thì quá trình này luôn xảy ra ngay lập tức. Thêm một lý do nữa là, chúng ta đang lưu trữ cha của các commit, nên việc tìm kiếm gốc/cơ sở để tích hợp lại được thực hiện một cách tự động và rất dễ dàng. Những tính năng này giúp khuyến khích các lập trình viên tạo và sử dụng nhánh thường xuyên hơn. -Let’s see why you should do so. +Hãy cùng xem tại sao bạn nên làm như vậy. -## Basic Branching and Merging ## +## Cơ Bản Về Phân Nhánh và Tích Hợp ## -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: +Hãy cùng xem qua một ví dụ đơn giản về phân nhánh và tích hợp với một quy trình làm việc mà có thể bạn sẽ sử dụng nó vào thực tế. Bạn sẽ thực hiện theo các bước sau: -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. +1. Làm việc trên một web site +2. Tạo nhánh cho một câu chuyện mới mà bạn đang làm. +3. Làm việc trên nhánh đó. -At this stage, you’ll receive a call that another issue is critical and you need a hotfix. You’ll do the following: +Đến lúc này, bạn nhận được thông báo rằng có một vấn đề nghiêm trọng cần được khắc phục ngay. Bạn sẽ làm theo các bước sau: -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. +1. Chuyển lại về nhánh sản xuất (production) +2. Tạo mới một nhánh khác để khắc phục lỗi +3. Sau khi đã kiểm tra ổn định, tích hợp nhánh đó lại và đưa vào hoạt động. +4. Chuyển ngược lại với câu chuyện của bạn và tiếp tục làm việc. -### Basic Branching ### +### Cơ Bản về Phân Nhánh ### -First, let’s say you’re working on your project and have a couple of commits already (see Figure 3-10). +Đầu tiên, giả sử bạn đang làm việc trên một dự án đã có một số commit từ trước (xem Hình 3-10). Insert 18333fig0310.png -Figure 3-10. A short and simple commit history. +Hình 3-10. Một lịch sử commit ngắn và đơn giản. -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: +Bạn quyết định sẽ giải quyết vấn đề số #53 sử dụng bất kỳ hệ thống giám sát vấn đề (issue-tracking) nào mà công ty bạn đang dùng. Để cho rõ ràng, Git không cung cấp kèm bất kỳ hệ thống giám sát vấn đề nào; nhưng bởi vì vấn đề số #53 là cái mà bạn sẽ tập trung vào nên bạn sẽ tạo một nhánh mới để làm việc trên đó. Để tạo một nhánh và chuyển sang nhánh đó đồng thời, bạn có thể chạy lệnh `git checkout` với tham số `-b`: $ git checkout -b iss53 Switched to a new branch "iss53" -This is shorthand for: +Đây là cách sử dụng vắn tắt của: $ git branch iss53 $ git checkout iss53 -Figure 3-11 illustrates the result. +Hình 3-11 minh họa kết quả. Insert 18333fig0311.png -Figure 3-11. Creating a new branch pointer. +Hình 3-11. Tạo con trỏ nhánh mới. -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): +Bạn làm việc trên đó và sau đó thực hiện một số commit. Làm như vậy sẽ khiến nhánh `iss53` di chuyển tiến lên, vì bạn đã checkout nó (hay, HEAD đang trỏ đến nó; xem Hình 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. +Hình 3-12. Nhánh iss53 đã di chuyển tiến lên cùng với thay đổi của bạn. -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. +Bây giờ bạn nhận được thông báo rằng có một vấn đề với trang web, và bạn cần khắc phục nó ngay lập tức. Với Git, bạn không phải triển khai bản vá lỗi cùng với các thay đổi bạn đã thực hiện trên nhánh `iss53`, và bạn không phải tốn quá nhiều công sức để khôi phục lại các thay đổi đó trước khi áp dụng bản vá vào sản xuất. Tất cả những gì bạn cần phải làm là chuyển lại nhánh master. -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: +Tuy nhiên, trước khi làm điều này, bạn nên lưu ý rằng nếu thư mục làm việc hoặc khu vực tổ chức có chứa các thay đổi chưa được commit mà xung đột với nhánh bạn đang làm việc, Git sẽ không cho phép bạn chuyển nhánh. Tốt nhất là bạn nên ở trạng thái làm việc "sạch" (đã commit hết) trước khi chuyển nhánh. Có các cách khác để khắc phục vấn đề này (đó là stashing và sửa commit) mà chúng ta sẽ bàn tới sau. Hiện tại, bạn đã commit hết các thay đổi, vì vậy bạn có thể chuyển lại nhánh master: $ 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. +Tại thời điểm này, thư mục làm việc của dự án giống hệt như trước khi bạn bắt đầu giải quyết vấn đề #53, và bạn có thể tập trung vào việc sửa lỗi. Điểm quan trọng cần ghi nhớ: Git khôi phục lại thư mục làm việc của bạn để nó giống như snapshot của commit mà nhánh bạn đang làm việc trỏ tới. Nó thêm, xóa, và sửa các tập tin một cách tự động để đảm bảo rằng thư mục làm việc của bạn giống như lần commit cuối cùng. -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): +Tiếp theo, bạn có mỗi lỗi cần phải sửa. Hãy tạo mỗi nhánh để làm việc này cho tới khi nó được hoàn thành (xem Hình 3-13): $ git checkout -b hotfix Switched to a new branch "hotfix" @@ -156,9 +156,9 @@ Next, you have a hotfix to make. Let’s create a hotfix branch on which to work 1 files changed, 0 insertions(+), 1 deletions(-) Insert 18333fig0313.png -Figure 3-13. hotfix branch based back at your master branch point. +Hình 3-13. Nhánh hotfix dựa trên nhánh master. -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: +Bạn có thể chạy để kiểm tra, để chắc chắn rằng bản vá lỗi hoạt động đúng theo ý bạn muốn, và sau đó tích hợp nó lại nhánh chính để triển khai. Bạn có thể làm sử dụng lệnh `git merge` để làm việc này: $ git checkout master $ git merge hotfix @@ -167,19 +167,19 @@ You can run your tests, make sure the hotfix is what you want, and merge it back 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". +Bạn sẽ nhận thấy rằng cụm từ "Fast forward" trong lần tích hợp đó. Bởi vì commit được trở tới bởi nhánh mà bạn tích hợp vào lại trực tiếp là upstream của commit hiện tại, vì vậy Git di chuyển con trỏ về phía trước. Nói cách khác, khi bạn cố gắng tích hợp một commit với một commit khác mà có thể truy cập được từ lịch sử của commit trước thì Git sẽ đơn giản hóa bằng cách di chuyển con trỏ về phía trước vì không có sự rẽ nhánh nào để tích hợp - đây được gọi là "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). +Thay đổi của bạn bây giờ ở trong snapshot của commit được trỏ tới bởi nhánh `master`, và bạn có thể triển khai thay đổi này (xem Hình 3-14). Insert 18333fig0314.png -Figure 3-14. Your master branch points to the same place as your hotfix branch after the merge. +Hình 3-14. Nhánh master và nhánh hotfix cùng trỏ tới một điểm sau khi tích hợp. -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`: +Sau khi triển khai xong bản vá lỗi quan trọng đó, bạn đã sẵn sàng để quay lại với công việc bị gián đoạn trước đó. Tuy nhiên, việc đầu tiên cần làm là xóa nhánh `hotfix` đi, vì bạn không còn cần tới nó nữa - nhánh `master` trỏ tới cùng một điểm. Bạn có thể xóa nó đi bằng cách sử dụng tham số `-d` cho lệnh `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): +Bây giờ bạn đã có thể chuyển lại nhánh mà bạn đang làm việc trước đó về vấn đề #53 và tiếp tục làm việc (xem Hình 3-15): $ git checkout iss53 Switched to branch "iss53" @@ -189,13 +189,13 @@ Now you can switch back to your work-in-progress branch on issue #53 and continu 1 files changed, 1 insertions(+), 0 deletions(-) Insert 18333fig0315.png -Figure 3-15. Your iss53 branch can move forward independently. +Hình 3-15. Nhánh iss53 có thể di chuyển về phía trước một cách độc lập. -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. +Điều đáng chú ý ở đây là những công việc bạn đã thực hiện ở nhánh `hotfix` không bao gồm trong nhánh `iss53`. Nếu bạn muốn đưa chúng vào, bạn có thể tích hợp nhánh `master` vào nhánh `iss53` bằng cách chạy lệnh `git merge master`, hoặc bạn có thể chờ đợi đến khi bạn quyết định tích hợp nhánh `iss53` ngược trở lại nhánh `master` về sau. -### Basic Merging ### +### Cơ Bản Về Tích Hợp ### -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: +Giả sử bạn đã quyết định việc giải quyết vấn đề #53 đã hoàn thành và sẵn sàng để tích hợp vào nhánh `master`. Để làm được điều này, bạn sẽ tích hợp nhánh `iss53` lại, giống như bạn đã làm với nhánh `hotfix` trước đó. Tất cả những gì cần phải làm là chuyển sang (check out) nhánh mà bạn muốn được tích hợp vào và chạy lệnh `git merge`: $ git checkout master $ git merge iss53 @@ -203,32 +203,32 @@ Suppose you’ve decided that your issue #53 work is complete and ready to be me 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. +Lần này có hơi khác so với lần tích hợp `hotfix` trước đó. Trong trường hợp này, lịch sử phát triển của bạn đã bị phân nhánh tại một thời điểm nào đó trước kia. Bởi vì commit trên nhánh mà bạn đang làm việc (master) không phải là "cha" trực tiếp của nhánh mà bạn đang tích hợp vào, Git phải làm một số việc. Trường hợp này, Git thực hiện một tích hợp 3-chiều, sử dụng hai snapshot được trỏ tới bởi các đầu mút của nhánh và "cha chung" của cả hai. Hình 3-16 minh họa ba snapshot mà Git sử dụng để thực hiện phép tích hợp trong trường hợp này. Insert 18333fig0316.png -Figure 3-16. Git automatically identifies the best common-ancestor merge base for branch merging. +Hình 3-16. Git tự động nhận dạng "cha chung" phù hợp nhất để tích hợp các nhánh lại với nhau. -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. +Thay vì việc chỉ di chuyển con trỏ về phía trước, Git tạo một snapshot mới - được hợp thành từ lần tích hợp 3-chiều này và cũng tự tạo một commit mới trỏ tới nó (xem Hình 3-17). Nó được biết tới như là "commit tích hợp" (merge commit) và nó đặc biệt vì có nhiều hơn một cha. -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. +Đáng để chỉ ra rằng Git tự quyết định cha chung phù hợp nhất để sử dụng làm cơ sở cho việc tích hợp; điểm này khác với CVS hay Subversion (các phiên bản trước 1.5), khi mà các lập trình viên phải tự xác định cơ sở phù hợp nhất để tích hợp. Điều này khiến cho việc tích hợp trong Git trở nên dễ dàng hơn rất nhiều so với các hệ quản trị phiên bản khác. Insert 18333fig0317.png -Figure 3-17. Git automatically creates a new commit object that contains the merged work. +Hình 3-17. Git tự động tạo đối tượng commit mới chứa đựng các thay đổi đã tích hợp. -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: +Bây giờ công việc của bạn đã được tích hợp lại với nhau, bạn không cần thiết phải giữ lại nhánh `iss53` nữa. Bạn có thể xóa nó đi và sau đó tự xóa vấn đề này trong hệ thống quản lý vấn đề của bạn: $ git branch -d iss53 -### Basic Merge Conflicts ### +### Mâu Thuẫn Khi Tích Hợp ### -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: +Đôi khi, quá trình này không diễn ra một cách suôn sẻ. Nếu bạn thay đổi cùng một nội dung của cùng một tập tin ở hai nhánh khác nhau mà bạn đang muốn tích hợp vào, Git không thể tích hợp chúng một cách gọn gàng. Nếu bản vá lỗi cho vấn đề #53 cùng thay đổi một phần của một tập tin giống như nhánh `hotfix`, bạn sẽ nhận được một sự xung đột khi tiến hành tích hợp như sau: $ 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`: +Git chưa tự tạo commit tích hợp mới. Nó tạm dừng quá trình này lại cho đến khi bạn giải quyết xong xung đột. Nếu bạn muốn xem tập tin nào chưa được tích hợp tại bất kỳ thời điểm nào sau khi xung đột xảy ra, bạn có thể sử dụng lệnh `git status`: [master*]$ git status index.html: needs merge @@ -240,7 +240,7 @@ Git hasn’t automatically created a new merge commit. It has paused the process # 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: +Với bất kỳ xung đột nào xảy ra mà chưa được giải quyết, chúng sẽ được liệt kê là unmerged (chưa được tích hợp). Git thêm các dấu hiệu chuẩn riêng để giải quyết xung đột vào các tập tin có xảy ra xung đột, vì thế bạn có thể mở và giải quyết các xung đột đó một cách thủ công. Tập tin của bạn sẽ chứa một phần tương tự như sau: <<<<<<< HEAD:index.html @@ -250,14 +250,13 @@ Anything that has merge conflicts and hasn’t been resolved is listed as unmerg >>>>>>> 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: +Điều này có nghĩa là phiên bản trong HEAD (nhánh master, vì nó là nhánh bạn đã check out khi chạy lệnh merge) là phần mới nhất của đoạn đó (mọi thứ phía trên `=======`), trong khi phiên bản ở nhánh `iss53` chính là phần phía dưới. Để giải quyết vấn đề này, bạn phải chọn một trong hai phần hoặc tự gộp nội dung của chúng lại. Ví dụ, có thể bạn giải quyết xung đột này bằng cách thay thế toàn bộ đoạn code đó bằng: -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: +Cách giải quyết này có chứa nội dung của cả hai phần, và tôi đã xóa bỏ hoàn toàn các dòng `<<<<<<<`, `=======`, và `>>>>>>>`. Sau khi giải quyết xong tất cả các phần này trong các tập tin bị xung đột, chạy lệnh `git add` cho từng tập tin để đánh dấu là chúng đã được giải quyết. Tổ chức chúng cùng đồng nghĩa với việc đánh dấu là đã được giải quyết trong Git. Nếu bạn muốn sử dụng một công cụ có giao diện đồ họa để giải quyết những vấn đề này, bạn có thể sử dụng `git mergetool`, Git sẽ tự động mở chương trình tương ứng và trợ giúp bạn giải quyết các xung đột: $ git mergetool merge tool candidates: kdiff3 tkdiff xxdiff meld gvimdiff opendiff emerge vimdiff @@ -268,11 +267,11 @@ If you want to use a graphical tool to resolve these issues, you can run `git me {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. +Nếu bạn muốn sử dụng một công cụ tích hợp khác thay vì chương trình mặc định (Git sử dụng `opendiff` cho tôi trong trường hợp này vì tôi đang sử dụng một máy tính Mac), bạn có thể xem danh sách các chương trình tương thích bằng cách chạy lệnh "merge tool candidates". Gõ tên chương trình bạn muốn sử dung. Trong Chương 7, chúng ta sẽ cùng bàn luận về việc làm thế nào để thay đổi giá trị mặc định này. -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. +Sau khi thoát khỏi chương trình hỗ trợ tích hợp, Git sẽ hỏi bạn nếu tích hợp thành công. Nếu bạn trả lời đúng, nó sẽ đánh dấu tập tin đó là đã giải quyết cho bạn. -You can run `git status` again to verify that all conflicts have been resolved: +Bạn có thể chạy `git status` lại một lần nữa để xác thực rằng tất cả các xung đột đã được giải quyết: $ git status # On branch master @@ -282,7 +281,7 @@ You can run `git status` again to verify that all conflicts have been resolved: # 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: +Nếu bạn hài lòng với điều này, và chắc chắn rằng tất cả các xung đột đã được tổ chức, bạn có thể chạy lệnh `git commit` để hoàn thành commit tích hợp. Thông điệp mặc định của commit có dạng như sau: Merge branch 'iss53' @@ -295,66 +294,68 @@ If you’re happy with that, and you verify that everything that had conflicts h # 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. +Bạn có sửa lại nội dung này với các chi tiết về việc bạn đã giải quyết như thế nào nếu bạn cho rằng các thông tin đó sẽ có ích cho các thành viên khác sau này - tại sao bạn lại làm như vậy, nếu như chúng còn chưa rõ ràng. -## Branch Management ## +## Quản Lý Các Nhánh ## -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. +Bạn đã tạo mới, tích hợp, và xóa một số nhánh, bây giờ hãy cùng xem một số công cụ giúp việc quản lý nhánh trở nên dễ dàng hơn khi tần suất sử dụng nhánh của bạn ngày càng nhiều. -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: +Lệnh `git branch` thực hiện nhiều việc hơn là chỉ tạo và xóa nhánh. Nếu bạn chạy nó không có tham số, bạn sẽ có danh sách của tất cả các nhánh hiện tại: $ 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`: +Lưu ý về ký tự `*` đứng trước nhánh `master`: nó chỉ cho bạn thấy nhánh mà bạn đang làm việc (Checkout). Có nghĩa là nếu bạn commit ở thời điểm hiện tại, thì nhánh `master` sẽ di chuyển tiến lên phía trước với các thay đổi mới. Để xem commit mới nhất trên từng nhánh, bạn có thể chạy lệnh `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`: +Một lựa chọn hữu ích khác để tìm ra trạng thái của các nhánh là lọc qua các nhánh bạn đã hoặc chưa tích hợp vào nhánh hiện tại. Các lựa chọn để sử dụng cho mục đích này gồm `--merged` và `--no-merged`. Để biết nhánh nào đã được tích hợp vào nhánh hiện tại, bạn có thể sử dụng `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. +Bởi vì bạn đã tích hợp nhánh `iss53` vào trước đó, bạn sẽ thấy nó ở trong danh sách này. Cách nhánh trong danh sách không có dấu `*` ở phía trước thường an toàn để xóa bằng cách sử dụng `git branch -d`; bạn đã tích hợp các thay đổi trong đó vào một nhánh khác, vì thế bạn sẽ không hề bị mất bất cứ dữ liệu gì. -To see all the branches that contain work you haven’t yet merged in, you can run `git branch --no-merged`: +Để xem cách nhánh chứa các công việc/thay đổi chưa được tích hợp vào, bạn có thể chạy lệnh `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: +Lệnh này lại hiện thị các nhánh khác. Bởi vì chúng bao gồm các công việc mà bạn chưa tích hợp vào, xóa nó đi bằng lệnh `git branch -d` sẽ báo lỗi: $ 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. +Nếu bạn thực sự muốn xóa nó đi và chấp nhận mất các thay đổi, bạn có thể bắt buộc bằng cách sử dụng tham số `-D`, như hướng dẫn trong thông báo trên. -## Branching Workflows ## +## Quy Trình Làm Việc Phân Nhánh ## -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. +Bây giờ bạn đã có được các kiến thức cơ bản về phân nhánh và tích hợp, vậy bạn có thể hay nên làm gì với chúng. Trong phần này, chúng ta sẽ đề cập tới một số quy trình làm việc phổ biến áp dụng phân nhánh, vì thế bạn có thể tự quyết định có áp dụng chúng vào quy trình làm việc riêng của bạn hay không. -### Long-Running Branches ### +### Nhánh Lâu Đời ### -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. +Bởi vì Git sử dụng tích hợp 3 chiều đơn giản, nên tích hợp từ nhánh này vào nhánh khác nhiều lần trong cùng một giai đoạn thường dễ dàng. Có nghĩa là bạn có thể có nhiều nhánh luôn mở và sử dụng chúng cho các giai đoạn phát triển khác nhau; bạn có thể tích hợp từ một số nhánh nào đó vào các nhánh khác một cách thường xuyên. -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. +Nhiều lập trình viên Git sử dụng quy trình làm việc dựa theo phương pháp này, chẳng hạn như chỉ chứa mã nguồn ổn định hoàn toàn ở nhánh `master` - hầu như là mã nguồn đã phát hành hoặc chuẩn bị phát hành. Họ có một nhánh song song khác có tên develop hoặc next, nơi mà họ làm việc hoặc sử dụng để kiểm tra độ ổn định - nó không nhất thiết luôn luôn phải ổn định, tuy nhiên mỗi khi nó đạt được trạng thái ổn định, nó sẽ được tích hợp vào nhánh `master`. Chúng được sử dụng với vai trò là các nhánh chủ đề (topic branch) - các nhánh có vòng đời ngắn, giống như nhánh `iss53` trước đó - để đảm bảo chúng qua được các bài kiểm tra và không gây ra lỗi. -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). +Trong thực tế, chúng ta đang nói về các con trỏ di chuyển dọc theo đường thẳng của các commit. Các nhánh ổn định hơn thường ở phía cuối của đường thẳng, còn các nhánh đang phát triển thường ở phía đầu hàng (xem Hình 3-18). Insert 18333fig0318.png -Figure 3-18. More stable branches are generally farther down the commit history. +Hình 3-18. Nhánh ổn định hơn thường ở phía cuối hàng trong lịch sử commit. -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). +Sẽ dễ hình dung hơn khi nghĩ về chúng như là các xi-lô, nơi mà tập hợp các commit cô đặc dần thành một xi-lô ổn định hơn khi đã được kiểm tra đầy đủ (xem Hình 3-19). Insert 18333fig0319.png -Figure 3-19. It may be helpful to think of your branches as silos. +Hình 3-19. Có lẽ sẽ dễ hiểu hơn khi coi các nhánh là các xi-lô. + +Bạn có thể tiếp tục làm theo cách này cho nhiều tầng ổn định khác nhau. Nhiều dự án lớn có nhánh `proposed` hoặc `pu` (proposed updates) được sử dụng cho các nhánh chưa đủ điều kiện để tích hợp vào `next` hoặc `master`. 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. From d730643df638f852eefe5c8ef8670d6aa0d3031a Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 23:09:07 +0100 Subject: [PATCH 022/690] Reviewing translation --- it/06-git-tools/01-chapter6.markdown | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 9efcffa29..604ba8225 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -94,25 +94,20 @@ Puoi consultare il reflog con il comando 'git reflog': 1c36188... HEAD@{5}: rebase -i (squash): updating HEAD 7e05da5... HEAD@{6}: rebase -i (pick): updating HEAD -Ogni volta che il *branch* è aggiornato, Git registra l'informazione in questa -lista temporanea. Si possono specificare anche *commit* più vecchi. Se si vuole -vedere il quinto valore precedente della *HEAD* del proprio *repository*, si può -usare il riferimento '@{n}' che si vede nel *output* di reflog: +Ogni volta che un *branch* viene aggiornato per qualsiasi ragione, Git memorizza questa informazione in questa cronologia temporanea. E puoi anche specificare *commit* più vecchie. Se vuoi vedere la cronologia a partire dalla quinta commit più vecchia a partire dalla *HEAD* del tuo *repository*, puoi usare il riferimento '@{n}' che vedi nel *output* di reflog: $ git show HEAD@{5} -Si può anche usare questa sintassi per vedere dove era un *branch* una certa -quantità di tempo fa. Per esempio, per vedere dov'era il 'master' *branch* ieri, -si può scrivere: +Puoi usare usare questa sintassi anche per vedere dove era un *branch* a una certa data. Se vuoi vedere, per esempio, dov'era il 'master' *branch* ieri, puoi scrivere: $ git show master@{yesterday} Questo mostra dove era il *branch* ieri. Questa tecnica funziona solo per i dati -che sono ancora nel *reflog*, non è possibile usarla per vedere *commit* più -vecchi di qualche mese. +che sono ancora nel *reflog* e non puoi quindi usarla per vedere *commit* più +vecchie di qualche mese. -Per vedere le informazioni del *reflog* formattate come il '*git log*', si può -lanciare il comando 'git log -g': +Per vedere le informazioni del *reflog* formattate come l’output di '*git log*', puoi +eseguire il comando 'git log -g': $ git log -g master commit 734713bc047d87bf7eac9674765ae793478c50d3 @@ -131,12 +126,7 @@ lanciare il comando 'git log -g': Merge commit 'phedders/rdocs' -E' importante notare che l'informazione del *reflog* è strettamente locale - è -un log di cosa è stato fatto nel proprio *repository*. I riferimenti non saranno -uguali nella copia del *repository* tenuta da qualcun altro. -Lanciare 'git show HEAD@{2.months-ago}' funzionerà solo se il progetto è stato -clonato almeno due mesi fa - se è stato clonato cinque minuti prima non verrà -restituito alcun risultato. +E' importante notare che l'informazione del *reflog* è strettamente locale: è un log di cosa hai fatto nel tuo *repository*. I riferimenti non saranno uguali sui cloni degli altri. Appena dopo aver clonato un *repository* il tuo reflog sarà vuoto perché ancora non hai svolto nessuna attività sul tuo *repository*. Eseguendo 'git show HEAD@{2.months.ago}' funzionerà solo se hai clonato il progetto almeno due mesi fa: se è stato clonato cinque minuti fa non otterrai nessun risultato. ### Riferimenti di discendenza ### From 1b3cc066089c1b61dccdf85d8fba3ebc30da1ef6 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 23:15:53 +0100 Subject: [PATCH 023/690] Reviewing translation --- it/06-git-tools/01-chapter6.markdown | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 604ba8225..15b084b9a 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -128,12 +128,10 @@ eseguire il comando 'git log -g': E' importante notare che l'informazione del *reflog* è strettamente locale: è un log di cosa hai fatto nel tuo *repository*. I riferimenti non saranno uguali sui cloni degli altri. Appena dopo aver clonato un *repository* il tuo reflog sarà vuoto perché ancora non hai svolto nessuna attività sul tuo *repository*. Eseguendo 'git show HEAD@{2.months.ago}' funzionerà solo se hai clonato il progetto almeno due mesi fa: se è stato clonato cinque minuti fa non otterrai nessun risultato. -### Riferimenti di discendenza ### +### Riferimenti ancestrali ### -L'altro modo per specificare un *commit* è attraverso la sua discendenza. Se -viene posizionato un `^` alla fine di un riferimento, Git lo interpreta come il -genitore di quel determinato *commit*. -Supponiamo che si guardi la lista delle modifiche effettuate nel progetto: +L'altro modo principale per specificare una *commit* è attraverso i suoi ascendenti. Se metti un `^` alla fine di un riferimento, Git lo risolve interpretandolo come il padre +padre di quella determinata *commit*. Immagina di guardare la cronologia del tuo progetto: $ git log --pretty=format:'%h %s' --graph * 734713b fixed refs handling, added gc auto, updated tests @@ -145,8 +143,7 @@ Supponiamo che si guardi la lista delle modifiche effettuate nel progetto: * 1c36188 ignore *.gem * 9b29157 add open3_detach to gemspec file list -E' possibile vedere il precedente *commit* specificando `HEAD^`, che significa -"il genitore di HEAD": +È possibile vedere la *commit* precedente specificando `HEAD^`, che significa "il genitore di HEAD": $ git show HEAD^ commit d921970aadf03b3cf0e71becdaab3147ba71cdef From 8274af5adb147632b926daae9bd497f16a133e91 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 23:16:32 +0100 Subject: [PATCH 024/690] Reviewing translation --- it/06-git-tools/01-chapter6.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 15b084b9a..9a0191656 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -143,7 +143,7 @@ padre di quella determinata *commit*. Immagina di guardare la cronologia del tuo * 1c36188 ignore *.gem * 9b29157 add open3_detach to gemspec file list -È possibile vedere la *commit* precedente specificando `HEAD^`, che significa "il genitore di HEAD": +Puoi quindi vedere la *commit* precedente specificando `HEAD^`, che significa "il genitore di HEAD": $ git show HEAD^ commit d921970aadf03b3cf0e71becdaab3147ba71cdef From 7f30733ba450bd4d4fca6cc2a52ccdfba96db59e Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 23:18:24 +0100 Subject: [PATCH 025/690] Reviewing translation --- it/06-git-tools/01-chapter6.markdown | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 9a0191656..2e597b7fb 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -153,11 +153,9 @@ Puoi quindi vedere la *commit* precedente specificando `HEAD^`, che significa "i Merge commit 'phedders/rdocs' -Si può anche specificare un numero dopo `^` - per esempio, `d921970^2` significa -"il secondo genitore di d921870." Questa sintassi è utile per fare il *merge* di -*commit* che hanno più di un genitore. -Il primo genitore è il *branch* dove ci si trova al momento del *merge*, e il -secondo è il *commit* sul *branch* di cui è stato fatto il *merge*: +Puoi anche specificare un numero dopo `^`: per esempio `d921970^2` significa +"il secondo genitore di d921870." Questa sintassi è utile solo per fare il *merge* di +*commit* che hanno più di un genitore. Il primo genitore è il *branch* dove ti trovi al momento del *merge*, e il secondo è la *commit* sul *branch* da cui hai fatto il *merge*: $ git show d921970^ commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b From 0d69a9f6f9f6bdf739988c2e2c95947a0daee38c Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 23:26:31 +0100 Subject: [PATCH 026/690] Reviewing translation --- it/06-git-tools/01-chapter6.markdown | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 2e597b7fb..f232b8859 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -171,8 +171,7 @@ Puoi anche specificare un numero dopo `^`: per esempio `d921970^2` significa Some rdoc changes -Un altro modo per specificare la discendenza è `~`. Anche questo si riferisce al -primo genitore, quindi `HEAD~` e `HEAD^` sono equivalenti. La differenza si nota +Un altro modo riferimento ancestrale è `~`. Questo si riferisce anche al primo genitore, quindi `HEAD~` e `HEAD^` sono equivalenti. La differenza si nota quando viene specificato un numero. `HEAD~2` significa "il primo genitore del primo genitore", o "il nonno" - attraversa i primi genitori il numero di volte specificato. Per esempio, nella From dc4780291b2004164b45e6bd8c757b70cacb2284 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 23:31:13 +0100 Subject: [PATCH 027/690] Finished reviewing translation ready to translate new text --- it/06-git-tools/01-chapter6.markdown | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index f232b8859..262e771cc 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -171,11 +171,8 @@ Puoi anche specificare un numero dopo `^`: per esempio `d921970^2` significa Some rdoc changes -Un altro modo riferimento ancestrale è `~`. Questo si riferisce anche al primo genitore, quindi `HEAD~` e `HEAD^` sono equivalenti. La differenza si nota -quando viene specificato un numero. -`HEAD~2` significa "il primo genitore del primo genitore", o "il nonno" - -attraversa i primi genitori il numero di volte specificato. Per esempio, nella -lista mostrata precedentemente, `HEAD~3` sarebbe +Un altro modo riferimento ancestrale è `~`. Questo si riferisce anche al genitore, quindi `HEAD~` e `HEAD^` sono equivalenti. La differenza si nota quando specifichi un numero. `HEAD~2` significa "il genitore del genitore", o "il nonno”: attraversa i primi genitori il numero di volte che specifichi. Per esempio, nella +cronologia precedente, `HEAD~3` sarebbe $ git show HEAD~3 commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d @@ -184,8 +181,7 @@ lista mostrata precedentemente, `HEAD~3` sarebbe ignore *.gem -Potrebbe essere anche scritto come `HEAD^^^`, che è sempre il primo genitore del -primo genitore del primo genitore: +Che può anche essere scritto come `HEAD^^^` che, di nuovo, è sempre il genitore del genitore del genitore: $ git show HEAD^^^ commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d @@ -194,6 +190,4 @@ primo genitore del primo genitore: ignore *.gem -E' possibile anche combinare queste sintassi - si può prendere il secondo -genitore del precedente riferimento (assumendo che si tratti di un *merge -commit*) usando `HEAD~3^2`, e così via. +È anche possibile combinare queste sintassi: puoi prendere il nonno del riferimento precedente (assumendo che si tratti di una commit di *merge*) usando `HEAD~3^2`, e così via. From 9527bcd791661066eeaa121241c4c2712e959859 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 23:36:57 +0100 Subject: [PATCH 028/690] Translated "Commit Ranges" --- it/06-git-tools/01-chapter6.markdown | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 262e771cc..0f77a3e99 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -190,4 +190,10 @@ Che può anche essere scritto come `HEAD^^^` che, di nuovo, è sempre il genitor ignore *.gem -È anche possibile combinare queste sintassi: puoi prendere il nonno del riferimento precedente (assumendo che si tratti di una commit di *merge*) usando `HEAD~3^2`, e così via. +È anche possibile combinare queste sintassi: puoi prendere il nonno del riferimento precedente (assumendo che si tratti di una commit di *merge*) usando `HEAD~3^2`, e così via. + +### Intervalli di Commit ### + +Ora che sai come specificare delle commit singole, vediamo come specificare intervalli di commit. Ciò è particolarmente utile per gestire i tuoi branch: se hai molti branch puoi usare gli intervalli per rispondere a domande come “cosa c’è nel tuo branch di cui io non ho ancora fatto il merge?” + + From 569f47f9390d0c91d38380f2e1c464578034e3b3 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 3 Jan 2014 23:39:52 +0100 Subject: [PATCH 029/690] Started "Double Dot" --- it/06-git-tools/01-chapter6.markdown | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 0f77a3e99..0af6f17db 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -196,4 +196,9 @@ Che può anche essere scritto come `HEAD^^^` che, di nuovo, è sempre il genitor Ora che sai come specificare delle commit singole, vediamo come specificare intervalli di commit. Ciò è particolarmente utile per gestire i tuoi branch: se hai molti branch puoi usare gli intervalli per rispondere a domande come “cosa c’è nel tuo branch di cui io non ho ancora fatto il merge?” +#### Doppio punto #### +Il modo più comune per specificare un intervallo è con il doppio punto che, praticamente, chiede a Git di risolvere l’intervallo tra commit che sia raggiungibile da una commit, ma che non sia raggiungibile dall’altra. Per esempio, immaginiamo di avere una cronologia come nell’immagine 6-1 + +Insert 18333fig0601.png +Figure 6-1. Esempio di cronologia per selezione di intervalli. From 24b9b821a0aefab5c4418327b6cfcd7349650ff3 Mon Sep 17 00:00:00 2001 From: Tuan Vu Date: Sat, 4 Jan 2014 02:52:56 +0000 Subject: [PATCH 030/690] update chapter 3 --- vi/03-git-branching/01-chapter3.markdown | 34 ++++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/vi/03-git-branching/01-chapter3.markdown b/vi/03-git-branching/01-chapter3.markdown index 6feadfe84..d8f26deb5 100644 --- a/vi/03-git-branching/01-chapter3.markdown +++ b/vi/03-git-branching/01-chapter3.markdown @@ -355,39 +355,39 @@ Sẽ dễ hình dung hơn khi nghĩ về chúng như là các xi-lô, nơi mà t Insert 18333fig0319.png Hình 3-19. Có lẽ sẽ dễ hiểu hơn khi coi các nhánh là các xi-lô. -Bạn có thể tiếp tục làm theo cách này cho nhiều tầng ổn định khác nhau. Nhiều dự án lớn có nhánh `proposed` hoặc `pu` (proposed updates) được sử dụng cho các nhánh chưa đủ điều kiện để tích hợp vào `next` hoặc `master`. +Bạn có thể tiếp tục làm theo cách này cho nhiều tầng ổn định khác nhau. Nhiều dự án lớn có nhánh `proposed` hoặc `pu` (proposed updates) được sử dụng cho các nhánh chưa đủ điều kiện để tích hợp vào `next` hoặc `master`. Ý tưởng ở đây là, các nhánh ở các tầng khác nhau của sự ổn định; khi chúng đạt tới một mức ổn định hơn nào đó, chúng sẽ được tích hợp vào tầng trên nó. +Tóm lại, có nhiều nhánh tồn lại lâu dài không thật sự cần thiết, nhưng nó thường rất hữu ích, đặc biệt là khi bạn làm việc với các dự án lớn và phức tạp. -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. +### Nhánh Chủ Đề ### -### Topic Branches ### +Nhánh chủ đề (topic branches) thì ngược lại, nó lại khá hữu ích cho các dự án ở bất kỳ cỡ nào. Một nhánh chủ đề là nhánh có vòng đời ngắn mà bạn tạo để phát triển một tính năng nào đó hoặc tương tự. Nó giống như một thứ gì đó mà bạn chưa từng làm với một VCS trước đây bởi vì nhìn chung nó đòi hỏi rất nhiều nỗ lực để tạo mới cũng như tích hợp các nhánh lại với nhau. -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. +Như bạn đã thấy trong phần trước với các nhánh `iss53` và `hotfix` bạn đã tạo ra. Bạn thực hiện một số commit trên đó và xóa chúng đi ngay sau khi tính hợp chúng lại với nhánh chính. Kỹ thuật này cho phép bạn chuyển ngữ cảnh một cách nhanh chóng và toàn diện - vì công việc của bạn tách biệt hoàn toàn ở các xi-lô nơi mà tất cả các thay đổi ở nhánh đó chỉ liên quan đến chủ đề đó, điều này khiến cho việc xem xét lại (review) mã nguồn hoặc tương tự trở nên dễ dàng hơn rất nhiều. Bạn có thể giữ các thay đổi ở đó trong bất kỳ khoảng thời gian nào bạn muốn, có thể tính bằng phút, ngày, hoặc tháng, và sau đó tích hợp lại khi chúng đã sẵn sàng, không quan trọng thứ tự chúng được tạo ra hay làm việc. -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. +Hãy cùng xét một ví dụ về thực hiện một số công việc (trên nhánh `master`), tạo nhánh cho một vấn đề cần giải quyết (`iss91`), làm việc trên đó một chút, tạo một nhánh thứ hai cùng giải quyết vấn đề đó nhưng theo một cách khác (`iss91v2`), quay trở lại nhánh `master` và làm việc trong một khoảng thời gian nhất định, sau đó tạo một nhánh khác từ đó cho một ý tưởng mà bạn không chắc chắn là nó có phải là ý hay hay không (nhánh `dumbidea`). Lúc này lịch sử commit của bạn sẽ giống Hình 3-20. Insert 18333fig0320.png -Figure 3-20. Your commit history with multiple topic branches. +Hình 3-20. Lịch sử commit với nhiều nhánh chủ đề. -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. +Bây giờ, giả sử bạn quyết định lựa chọn cách giải quyết thứ hai (`iss91v2`); và bạn trình bày ý tưởng `dumbidea` cho các đồng nghiệp, điều mà bạn không ngờ tới rằng mọi người lại cho đó là một ý tưởng tuyệt vời. Bạn đã có thể bỏ đi nhánh ban đầu `iss91` (mất commit C5 và C6) và tích hợp hai commit còn lại. Lịch sử của bạn lúc này sẽ giống Hình 3-21. Insert 18333fig0321.png -Figure 3-21. Your history after merging in dumbidea and iss91v2. +Hình 3-21. Lịch sử commit sau khi tích hợp dumbidea và 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. +Ghi nhớ một điều quan trọng là khi bạn làm tất cả những việc này, các nhánh hoàn toàn nằm ở máy nội bộ. Khi bạn phân nhánh và tích hợp, tất cả mọi thứ xảy ra trên kho chứa Git của bạn - không có giao tiếp tới máy chủ nào xảy ra. -## Remote Branches ## +## Nhánh Từ Xa ## -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. +Nhánh từ xa là các tham chiếu tới trạng thái của các nhánh trên kho chứa từ xa/trung tâm của bạn. Chúng là các nhánh nội bộ mà bạn không thể di chuyển; chúng chỉ di chuyển một cách tự động mỗi khi bạn thực hiện bất kỳ giao tiếp nào qua mạng lưới. Nhánh từ xa hoạt động như là các bookmark (dấu) để nhắc nhở bạn các nhánh trên kho chứa trung tâm của bạn ở đâu vào lần cuối cùng bạn kết nối tới. -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`. +Chúng có dạng `(remote)/(branch)`. Ví dụ, nếu bạn muốn xem nhánh `master` trên nhánh từ xa `origin` của bạn như thế nào từ lần giao tiếp cuối cùng, bạn sẽ dùng `origin/master`. Nếu bạn đang giải quyết một vấn đề với đối tác và họ đẩy dữ liệu lên nhánh `iss53`, bạn có thể có riêng nhánh `iss53` trên máy nội bộ; nhưng nhánh trên máy chủ sẽ trỏ tới commit tại `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). +Điều này có thể hơi khó hiểu một chút, vậy hãy cùng xem một ví dụ. Giả sử bạn có một máy chủ Git trên mạng của bạn tại địa chỉ `git.ourcompany.com`. Nếu bạn tạo bản sao từ đây, Git sẽ tự động đặt tên nó là `origin` cho bạn, tải về toàn bộ dữ liệu, tạo một con trỏ tới nhánh `master` và đặt tên nội bộ cho nó là `origin/master`; và bạn không thể di chuyển nó. Git cũng cung cấp cho bạn nhánh `master` riêng, bắt đầu cùng một vị trí với `master` của origin để cho bạn có thể bắt đầu làm việc (xem Hình 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. +Hình 3-22. Một bản sao Git cung cấp cho bạn nhánh master riêng và nhánh origin/master trỏ tới nhánh master của origin. + + 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). From 2e306d4754051ab1aa9c0cd466646ab24b41934a Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sat, 4 Jan 2014 11:03:53 +0100 Subject: [PATCH 031/690] Translated "Double Dot" --- it/06-git-tools/01-chapter6.markdown | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 0af6f17db..1a2a13c6a 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -202,3 +202,23 @@ Il modo più comune per specificare un intervallo è con il doppio punto che, pr Insert 18333fig0601.png Figure 6-1. Esempio di cronologia per selezione di intervalli. + +Vuoi vedere cosa sia nel tuo branch sperimentale che non sia ancora stato incluso nel branch master: puoi chiedere a Git di mostrarti il log esclusivamente di quelle commit con `master..experiment`: questo significa “tutte le commit raggiungibili da experiment che non siano raggiungibili da master”. Affinché questi esempi siano sintetici ma chiari, invece del log effettivamente scritto da Git, userò le lettere degli oggetti commit del diagramma: + + $ git log master..experiment + D + C + +Se, invece vuoi vedere il contrario, ovvero tutte le commit in `master` che non siano in `experiment`, puoi invertire i nomi dei branch: `experiment..master` ti mostra tutto ciò che è in `master` e che non sia raggiungibile da `experiment`: + + $ git log experiment..master + F + E + +Questo è utile se vuoi mantenere il branch `experiment` aggiornato e sapere di cosa stai per fare il merge. Un’altro caso in cui si usa spesso questa sintassi è quando stai per fare una push verso un repository remoto: + + $ git log origin/master..HEAD + +Questo comando mostra tutte le commit nel tuo branch che non sono nel branch `master` del tuo repository remoto `origin`. Se esegui `git push` quando il tuo branch è associato a `origin/master`, le commit elencate da `git log origin/master..HEAD` saranno le commit che saranno inviate al server. +Puoi anche omettere una delle parti della sintassi, e Git assumerà che sia HEAD. Puoi per esempio ottenere lo stesso risultato dell’esempio precedente scrivendo `git log origin/master..`: Git sostituisce la parte mancante con HEAD. + From ee7f909251e3319febfa4337a61438e4a802e58f Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sat, 4 Jan 2014 11:21:49 +0100 Subject: [PATCH 032/690] Translated "Multiple Points" --- it/06-git-tools/01-chapter6.markdown | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 1a2a13c6a..4f0c06524 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -222,3 +222,17 @@ Questo è utile se vuoi mantenere il branch `experiment` aggiornato e sapere di Questo comando mostra tutte le commit nel tuo branch che non sono nel branch `master` del tuo repository remoto `origin`. Se esegui `git push` quando il tuo branch è associato a `origin/master`, le commit elencate da `git log origin/master..HEAD` saranno le commit che saranno inviate al server. Puoi anche omettere una delle parti della sintassi, e Git assumerà che sia HEAD. Puoi per esempio ottenere lo stesso risultato dell’esempio precedente scrivendo `git log origin/master..`: Git sostituisce la parte mancante con HEAD. +#### Punti multipli #### + +La sintassi del doppio punto è utile come la stenografia, ma potresti voler specificare più di due branch, così come vedere le commit che sono nei vari branch e che non sono nel tuo branch attuale. Git ti permette di farlo sia con il carattere `^` che con l’opzione `--not` prima di ciascun riferimento del quale vuoi vedere le commit non raggiungibili. Quindi questi tre comandi sono equivalenti: + + $ git log refA..refB + $ git log ^refA refB + $ git log refB --not refA + +Questo è interessante, perché con questa sintassi puoi specificare più di due riferimenti nella tua query, cosa che non puoi fare con il doppio punto. Se per esempio vuoi vedere tutte le commit che siano raggiungibili da `refA` o da `refB` ma non da `refC` puoi usare una delle seguenti alternative: + + $ git log refA refB ^refC + $ git log refA refB --not refC + +Questo la rende un sistema potente di query di revisione che dovrebbe aiutarti a capire cosa c’è nei tuo branch. \ No newline at end of file From 22c2e5711316bfc680e4b393bbd4847314a7c677 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sat, 4 Jan 2014 11:23:58 +0100 Subject: [PATCH 033/690] Renamed "Doppio Punto" Per coerenza con il paragrafo seguente "Tre punti" --- it/06-git-tools/01-chapter6.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 4f0c06524..0bbdc6821 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -196,7 +196,7 @@ Che può anche essere scritto come `HEAD^^^` che, di nuovo, è sempre il genitor Ora che sai come specificare delle commit singole, vediamo come specificare intervalli di commit. Ciò è particolarmente utile per gestire i tuoi branch: se hai molti branch puoi usare gli intervalli per rispondere a domande come “cosa c’è nel tuo branch di cui io non ho ancora fatto il merge?” -#### Doppio punto #### +#### Due punti #### Il modo più comune per specificare un intervallo è con il doppio punto che, praticamente, chiede a Git di risolvere l’intervallo tra commit che sia raggiungibile da una commit, ma che non sia raggiungibile dall’altra. Per esempio, immaginiamo di avere una cronologia come nell’immagine 6-1 From 0f8eeff5595e0180261da91ad52825f249ae5ecb Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sat, 4 Jan 2014 19:47:33 +0100 Subject: [PATCH 034/690] Translated "Triple Dot" --- it/06-git-tools/01-chapter6.markdown | 31 ++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 0bbdc6821..f83a8e306 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -198,7 +198,7 @@ Ora che sai come specificare delle commit singole, vediamo come specificare inte #### Due punti #### -Il modo più comune per specificare un intervallo è con il doppio punto che, praticamente, chiede a Git di risolvere l’intervallo tra commit che sia raggiungibile da una commit, ma che non sia raggiungibile dall’altra. Per esempio, immaginiamo di avere una cronologia come nell’immagine 6-1 +Il modo più comune per specificare un intervallo è con i due punti che, praticamente, chiedono a Git di risolvere l’intervallo tra commit che sia raggiungibile da una commit, ma che non sia raggiungibile dall’altra. Per esempio, immaginiamo di avere una cronologia come nell’immagine 6-1 Insert 18333fig0601.png Figure 6-1. Esempio di cronologia per selezione di intervalli. @@ -224,15 +224,38 @@ Puoi anche omettere una delle parti della sintassi, e Git assumerà che sia HEAD #### Punti multipli #### -La sintassi del doppio punto è utile come la stenografia, ma potresti voler specificare più di due branch, così come vedere le commit che sono nei vari branch e che non sono nel tuo branch attuale. Git ti permette di farlo sia con il carattere `^` che con l’opzione `--not` prima di ciascun riferimento del quale vuoi vedere le commit non raggiungibili. Quindi questi tre comandi sono equivalenti: +La sintassi dei due punti è utile come la stenografia, ma potresti voler specificare più di due branch, così come vedere le commit che sono nei vari branch e che non sono nel tuo branch attuale. Git ti permette di farlo sia con il carattere `^` che con l’opzione `--not` prima di ciascun riferimento del quale vuoi vedere le commit non raggiungibili. Quindi questi tre comandi sono equivalenti: $ git log refA..refB $ git log ^refA refB $ git log refB --not refA -Questo è interessante, perché con questa sintassi puoi specificare più di due riferimenti nella tua query, cosa che non puoi fare con il doppio punto. Se per esempio vuoi vedere tutte le commit che siano raggiungibili da `refA` o da `refB` ma non da `refC` puoi usare una delle seguenti alternative: +Questo è interessante, perché con questa sintassi puoi specificare più di due riferimenti nella tua query, cosa che non puoi fare con i due punti. Se per esempio vuoi vedere tutte le commit che siano raggiungibili da `refA` o da `refB` ma non da `refC` puoi usare una delle seguenti alternative: $ git log refA refB ^refC $ git log refA refB --not refC -Questo la rende un sistema potente di query di revisione che dovrebbe aiutarti a capire cosa c’è nei tuo branch. \ No newline at end of file +Questo la rende un sistema potente di query di revisione che dovrebbe aiutarti a capire cosa c’è nei tuo branch. + +#### Tre punti #### + +L’ultima sintassi per la selezione di intervalli è quella dei tre punti che indica tutte le commit raggiungibili da ciascuno dei riferimenti ma non da entrambi. Rivedi la cronologia delle commit nella Figura 6-1. +Se vuoi vedere cosa sia in `master` o in `experiment` ma non i riferimenti comuni puoi eseguire questo comando + + $ git log master...experiment + F + E + D + C + +Che ti mostra l’output normale del *log*, ma solo con le informazioni di quelle quattro commit nel solito ordinamento cronologico. + +In questo è comune usare il parametro `--left-right` con il comando `log`, che mostra da che parte è la commit nell’intervallo selezionato, che rende i dati molto più utili: + + $ git log --left-right master...experiment + < F + < E + > D + > C + +Con questi strumenti puoi dire facilmente a Git quale o quali commit vuoi ispezionare. \ No newline at end of file From 5d2d9128ba3c7405817e659051a6c2ec5cc187d3 Mon Sep 17 00:00:00 2001 From: Tuan Vu Date: Sun, 5 Jan 2014 04:11:24 +0000 Subject: [PATCH 035/690] [vi] Finished chapter 3 --- vi/03-git-branching/01-chapter3.markdown | 143 +++++++++++------------ 1 file changed, 71 insertions(+), 72 deletions(-) diff --git a/vi/03-git-branching/01-chapter3.markdown b/vi/03-git-branching/01-chapter3.markdown index d8f26deb5..56fb8f8d0 100644 --- a/vi/03-git-branching/01-chapter3.markdown +++ b/vi/03-git-branching/01-chapter3.markdown @@ -387,33 +387,31 @@ Chúng có dạng `(remote)/(branch)`. Ví dụ, nếu bạn muốn xem nhánh ` Insert 18333fig0322.png Hình 3-22. Một bản sao Git cung cấp cho bạn nhánh master riêng và nhánh origin/master trỏ tới nhánh master của origin. - - -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). +Nếu bạn thực hiện một số thay đổi trên nhánh `master` nội bộ, và cùng thời điểm đó, một người nào đó đẩy lên `git.ourcompany.com` và cập nhật nhánh master của nó, thì lịch sử của bạn sẽ di chuyển về phía trước khác đi. Miễn là bạn không kết nối tới máy chủ thì con trỏ `origin/master` sẽ vẫn không đổi (xem Hình 3-23). Insert 18333fig0323.png -Figure 3-23. Working locally and having someone push to your remote server makes each history move forward differently. +Hình 3-23. Làm việc nội bộ và ai đó đẩy lên máy chủ khiến cho lịch sử thay đổi khác biệt nhau. -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). +Để đồng bộ hóa các thay đổi, bạn chạy lệnh `git fetch origin`. Lệnh này sẽ tìm kiếm máy chủ nào là origin (trong trường hợp này là `git.ourcompany.com`), truy xuất toàn bộ dữ liệu mà bạn chưa có từ đó, và cập nhật cơ sở dữ liệu nội bộ của bạn, di chuyển con trỏ `origin/master` tới vị trí mới được cập nhật (xem Hình 3-24). Insert 18333fig0324.png -Figure 3-24. The git fetch command updates your remote references. +Hình 3-24. Lệnh git fetch cập nhật các tham chiếu từ xa. -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). +Để minh họa cho việc có nhiều máy chủ từ xa và các nhánh từ xa của các dự án thuộc các máy chủ đó, giả sử bạn có một máy chủ Git nội bộ khác sử dụng riêng cho các nhóm "thần tốc". Máy chủ này có địa chỉ là `git.team1.ourcompany.com`. Bạn có thể thêm nó như là một tham chiếu từ xa tới dự án bạn đang làm việc bằng cách chạy lệnh `git remote add` như đã giới thiệu ở Chương 2. Đặt tên cho remote đó là `teamone`, đó sẽ là tên rút gọn thay thế cho địa chỉ đầy đủ kia (xem Hình 3-25). Insert 18333fig0325.png -Figure 3-25. Adding another server as a remote. +Hình 3-25. Thêm một máy chủ từ xa khác. -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). +Bây giờ bạn có thể chạy lệnh `git fetch teamone` để truy xất toàn bộ nội dung mà bạn chưa có từ máy chủ `teamone`. Bởi vì máy chủ đó có chứa một tập con dữ liệu từ máy chủ `origin` đang có, Git không truy xuất dữ liệu nào cả mà thiết lập một nhánh từ xa mới là `teamone/master` để trỏ tới commit mà `teamone` đang có như là nhánh `master` (xem Hình 3-26). Insert 18333fig0326.png -Figure 3-26. You get a reference to teamone’s master branch position locally. +Hình 3-26. Bạn sẽ có một tham chiếu tới vị trí nội bộ của nhánh `master` của teamone. -### Pushing ### +### Đẩy Lên ### -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. +Khi bạn muốn chia sẻ một nhánh với mọi người, bạn cẩn phải đẩy nó lên một máy chủ mà bạn có quyền ghi trên đó. Nhánh nội bộ của bạn sẽ không tự động thực hiện quá trình đồng bộ hóa - mà bạn phải tự đẩy lên cách nhánh mà bạn muốn chia sẻ. Theo cách này, bạn có thể có các nhánh riêng tư cho những công việc mà bạn không muốn chia sẻ, và chỉ đẩy lên các nhánh chủ đề mà bạn muốn mọi người cùng tham gia đóng góp. -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)`: +Nếu bạn có một nhánh là `serverfix` mà bạn muốn mọi người cùng cộng tác, bạn có thể đẩy nó lên theo cách mà chúng ta đã làm đối với nhánh đầu tiên. Chạy `git push (remote) (branch)`: $ git push origin serverfix Counting objects: 20, done. @@ -423,9 +421,9 @@ If you have a branch named `serverfix` that you want to work on with others, you 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. +Đây là một cách làm tắt. Git tự động mở rộng nhánh `serverfix` thành `refs/heads/serverfix:refs/heads/serverfix`, có nghĩa là, "Hãy sử dụng nhánh nội bộ serverfix của tôi và đẩy nó lên để cập nhật nhánh serverfix trên máy chủ từ xa." Chúng ta sẽ đi sâu vào phần `refs/heads/` ở Chương 9, nhưng bạn thường có thể bỏ qua nó. Bạn cũng có thể chạy lệnh sau `git push origin serverfix:serverfix`, cách này cũng cho kết quả tương tự - nó có nghĩa là "Hãy sử dụng serverfix của tôi để tạo một serverfix trên máy chủ". Bạn có thể sử dụng định dạng này để đẩy một nhánh nội bộ lên một nhánh từ xa với một tên khác. Nếu bạn không muốn gọi nó là `serverfix` trên máy chủ, bạn có thể chạy lệnh sau `git push origin serverfix:awesomebranch` để đẩy nhánh nội bộ `serverfix` vào nhánh `awesomebranch` trên máy chủ trung tâm. -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`: +Lần tới một trong các đồng nghiệp của bạn truy xuất nó từ trên máy chủ, họ sẽ có một tham chiếu tới phiên bản trên máy chủ của `serverfix` dưới tên `origin/serverfix`: $ git fetch origin remote: Counting objects: 20, done. @@ -435,165 +433,166 @@ The next time one of your collaborators fetches from the server, they will get a 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. +Điều quan trọng cần chú ý ở đây là khi bạn truy xuất dữ liệu từ máy chủ mà có kèm theo nhánh mới, Git sẽ không tự động tạo phiên bản nội bộ của nhánh đó. Nói cách khác, trong trường hợp này, bạn sẽ không có nhánh `serverfix` mới - bạn chỉ có một con trỏ tới `origin/serverfix` mà bạn không thể chỉnh sửa. -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: +Để tích hợp công việc hiện tại vào nhánh bạn đang làm việc, bạn có thể chạy `git merge origin/serverfix`. Nếu bạn muốn nhánh `serverfix` riêng để có thể làm việc trên đó, bạn có thể tách nó ra khỏi nhánh trung tâm bằng cách: $ 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. +Cách này sẽ tạo cho bạn một nhánh nội bộ mà bạn có thể làm việc, bắt đầu cùng một vị trí với `origin/serverfix`. -### Tracking Branches ### +### Theo Dõi Các Nhánh ### -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. +Check out một nhánh nội bộ từ một nhánh trung tâm tự động tạo ra một _tracking branch_. Tracking branches là các nhánh nội bộ có liên quan trực tiếp với một nhánh trung tâm. Nếu bạn đang ở trên một tracking branch và chạy `git push`, Git tự động biết nó sẽ phải đẩy lên nhánh nào, máy chủ nào. Ngoài ra, chạy `git pull` khi đang ở trên một trong những nhánh này sẽ truy xuất toàn bộ các tham chiếu từ xa và sau đó tự động tích hợp chúng với các nhánh từ xa tương ứng. -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: +Khi bạn tạo bản sao của một kho chứa, thông thường Git tự động tạp một nhánh `master` để theo dõi `origin/master`. Đó là lý do tại sao `git push` và `git pull` có thể chạy tốt mà không cần bất kỳ tham số nào. Tuy nhiên, bạn có thể cài đặt các tracking branch khác nếu muốn - các nhánh này không theo dõi nhánh trên `origin` cũng như `master`. Một ví dụ đơn giản giống như bạn vừa thấy: `git checkout -b [branch] [remotename]/[branch]`. Nếu bạn đang sử dụng Git phiên bản 1.6.2 trở lên, bạn có thể sử dụng `--track`: $ 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: +Để cài đặt một nhánh nội bộ sử dụng tên khác với tên mặc định trên nhánh trung tâm, bạn có thể dễ dàng sử dụng phiên bản đầu tiên với một tên nội bộ khác: $ 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. +Bây giờ, nhánh nội bộ sf sẽ tự động "kéo và đẩy" từ origin/serverfix. -### Deleting Remote Branches ### +### Xóa Nhánh Trung Tâm ### -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: +Giả sử bạn và đồng nghiệp đã hoàn thành một chức năng nào đó và đã tích hợp nó vào nhánh `master` trung tâm (hoặc bất kỳ nhánh nào khác sử dụng cho việc lưu trữ các phiên bản ổn định). Bạn có thể xóa một nhánh trung tâm đi sử dụng cú pháp sau `git push [remotename] :[branch]`. Nếu bạn muốn xóa nhánh `serverfix` trên máy chủ, bạn có thể chạy lệnh sau: $ 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]`.” +Vậy là đã xong, nhánh đó đã bị xóa khỏi máy chủ. Có thể bạn muốn đánh dấu trang này lại, vì bạn sẽ cần đến câu lệnh này và có thể bạn sẽ quên cú pháp của nó. Một cách để nhớ lệnh này là xem lại cú pháp chúng ta đã nhắc tới trước đó `git push [remotename] [localbranch]:[remotebranch]`. Nếu bạn bỏ qua phần `[localbranch]`, thì cơ bản bạn đang thực hiện "Không sử dụng gì từ phía nội bộ để tạo nhánh `[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. +Trong Git, có hai cách chính để tích hợp các thay đổi từ nhánh này vào nhánh khác: đó là `merge` và `rebase`. Trong phần này bạn sẽ được tìm hiểu rebase là gì, sử dụng nó như thế nào, tại sao nó được coi là một công cụ khá tuyệt vời, và trong trường hợp nào thì không nên sử dụng nó. -### The Basic Rebase ### +### Cơ Bản về 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. +Nếu bạn xem lại ví dụ trước trong phần Tích Hợp (xem Hình 3-27), bạn có thể thấy rằng bạn đã phân nhánh công việc của bạn và thực hiện commit trên hai nhánh khác nhau. Insert 18333fig0327.png -Figure 3-27. Your initial diverged commit history. +Hình 3-17. Lần phân nhánh đầu tiên. -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. +Cách đơn giản nhất để tích hợp các nhánh, như chúng ta đã đề cập từ trước, đó là lệnh `merge`. Nó thực hiện tích hợp 3-chiều giữa hai snapshot mới nhất của hai nhánh (C3 và C4) và cha chung gần nhất của cả hai (C2), tạo mới một snapshot khác (và commit), như trong Hình 3-28. Insert 18333fig0328.png -Figure 3-28. Merging a branch to integrate the diverged work history. +Hình 3-28. Gộp nhánh lại để hợp nhất công việc bị tách ra trước đây. -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. +Tuy nhiên, còn có một cách khác: bạn có thể sử dụng bản vá của thay đổi được đưa ra ở C3 và áp dụng nó lên trên C4. Trong Git, đây được gọi là _rebasing_. Bằng cách sử dụng lệnh `rebase`, bạn có thể sử dụng tất cả các thay đổi được commit ở một nhánh và "chạy lại" (replay) chúng trên một nhánh khác. -In this example, you’d run the following: +Trong ví dụ này, bạn thực hiện như sau: $ 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. +Nó thực hiện bằng cách đi tới commit cha chung của hai nhánh (nhánh bạn đang làm việc và nhánh bạn đang muốn rebase), tìm sự khác biệt trong mỗi commit của nhánh mà bạn đang làm việc, lưu lại các thay đổi đó vào một tập tin tạm thời, khôi phục lại nhánh hiện tại về cùng một commit với nhánh bạn đang rebase, và cuối cùng áp dụng lần lượt các thay đổi. Hình 3-29 minh họa toàn bộ quá trình này. Insert 18333fig0329.png -Figure 3-29. Rebasing the change introduced in C3 onto C4. +Hình 3-29. Quá trình rebase thay đổi ở C3 vào C4. -At this point, you can go back to the master branch and do a fast-forward merge (see Figure 3-30). +Đến lúc này, bạn có thể quay lại nhánh `master` và thực hiện fast-forward merge (xem Hình 3-30). Insert 18333fig0330.png -Figure 3-30. Fast-forwarding the master branch. +Hình 3-30. Di chuyển nhánh master lên phía trước. + +Bây giờ snapshot mà C3 trỏ tới cũng giống như snapshot được trở tới bởi C5 trong ví dụ sử dụng merge. Không có sự khác biệt nào khi so sánh kết quả của hai phương pháp này, nhưng sử dụng rebase sẽ cho chúng ta lịch sử rõ ràng hơn. Nếu bạn xem xét lịch sử của nhánh mà chúng ta rebase vào, nó giống như một đường thẳng: mọi thứ dường như xảy ra theo trình tự, thậm chí ban đầu nó diễn ra song song. -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. +Bình thường, bạn sử dụng cách này để đảm bảo rằng các commit được áp dụng một cách rõ ràng, rành mạch trên nhánh remote - có lẽ là một dự án mà bạn đang đóng góp chứ không phải duy trì nó. Trong trường hợp này, bạn thực hiện công việc trên một nhánh và sau đó rebase trở lại nhánh `origin/master` khi đã sẵn sàng. Theo cách này thì người duy trì dự án đó không phải thực hiện việc tích hợp - mà chỉ chi chuyển tiến lên phía trước (fast-forwar) hoặc đơn giản là áp dụng chúng vào. -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. +Lưu ý rằng snapshot được trỏ tới bởi commit cuối cùng, cho dù nó là kết quả của việc rebase hay merge, thì nó vẫn giống nhau - chỉ khác nhau về các bước thực hiện mà thôi. Quá trình rebase được thực hiện bằng cách thực hiện lại các thay đổi từ nhánh này qua nhánh khác theo thứ tự chúng đã được thực hiện, trong khi đó merge lại lấy hai điểm kết thúc và gộp chúng lại với nhau. -### More Interesting Rebases ### +### Rebase Nâng Cao ### -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. +Bạn cũng có thể thực hiện rebase trên một đối tượng khác mà không phải là nhánh rebase. Xem ví dụ Hình 3-31. Bạn tạo một nhánh chủ để (`server`) để thêm một số tính năng server-side vào dự án, và thực hiện một số commit. Sau đó bạn tạo một nhánh khác để thực hiện một số thay đổi cho phía client (`client`) và cũng commit vài lần. Cuối cùng, bạn quay trở lại nhánh server và thực hiện thêm một số commit nữa. Insert 18333fig0331.png -Figure 3-31. A history with a topic branch off another topic branch. +Hình 3-31. Nhánh chủ đề được tạo từ một nhánh chủ đề khác. -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`: +Giả sử bạn quyết định tích hợp các thay đổi phía client vào nhánh chính cho bản phát hành sắp tới, nhưng bạn vẫn muốn giữ các thay đổi server-side cho đến khi nó được kiểm tra kỹ lưỡng. Bạn có thể lấy các thay đổi ở client mà không có mặt ở server (C8 và C9) sau đó chạy lại (replay) chúng trên nhánh master bằng cách sử dụng lựa chọn `--onto` cho lệnh `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. +Lệnh này cơ bản nói rằng, "Hãy check out nhánh client, tìm ra các bản vá từ commit chung của nhánh `client` và `server`, sau đó thực thi lại vào nhánh `master`." Nó hơi phức tạp một chút nhưng kết quả như Hình 3-32 thì lại rất tuyệt. Insert 18333fig0332.png -Figure 3-32. Rebasing a topic branch off another topic branch. +Hình 3-32. Quá trình rebase nhánh chủ đề khỏi một nhánh chủ đề khác. -Now you can fast-forward your master branch (see Figure 3-33): +Bây giờ bạn có thể di chuyển con trỏ của nhánh master tiến lên phía trước (xem Hình 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. +Hình 3-33. Di chuyển nhánh master lên phía trước để bao gồm các thay đổi của nhánh client. -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`): +Giả sử rằng bạn quyết định kéo về cả nhánh trên máy chủ. Bạn có thể rebase nhánh trên máy chủ đó vào nhánh master mà không phải checkout trước bằng lệnh `git rebase [basebranch] [topicbranch]` - lệnh này sẽ checkout nhánh chủ để (trong trường hợp này là `server`) cho bạn và áp dụng lại các thay đổi vào nhánh cơ sở (base) `master`: $ git rebase master server -This replays your `server` work on top of your `master` work, as shown in Figure 3-34. +Lệnh này sẽ thực hiện lại các thay đổi trên nhánh `server` chèn vào nhánh `master` như trong Hình 3-34. Insert 18333fig0334.png -Figure 3-34. Rebasing your server branch on top of your master branch. +Hình 3-34. Rebase nhánh server chèn lên nhánh master. -Then, you can fast-forward the base branch (`master`): +Sau đó bạn có thể di chuyển con trỏ nhánh base (`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: +Bạn có thể xóa nhánh `client` và `server` vì tất cả công việc đã được tích hợp vào master và bạn không cần đến chúng nữa, lịch sử quả toàn bộ quá trình vừa rồi giống như Hình 3-35: $ git branch -d client $ git branch -d server Insert 18333fig0335.png -Figure 3-35. Final commit history. +Hình 3-35. Lịch sử commit cuối cùng. -### The Perils of Rebasing ### +### Rủi Ro của Rebase ### -Ahh, but the bliss of rebasing isn’t without its drawbacks, which can be summed up in a single line: +Mặc dù rebase rất hữu ích nhưng nó cũng có không ít những mặt hạn chế, điều này có thể tổng kết bằng câu sau đây: -**Do not rebase commits that you have pushed to a public repository.** +**Không được rebase các commit mà bạn đã đẩy lên một kho chứa công khai.** -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. +Miễn là bạn làm theo hướng dẫn này, sẽ không có chuyện gì xảy ra. Nếu không, mọi người sẽ ghét bạn, và bạn sẽ bị bạn bè và gia đình coi thường. -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. +Khi bạn thực hiện rebase, bạn đang bỏ đi các commit đã tồn tại và tái tạo lại các commit mới tương tự nhưng thực ra khác biệt. Nếu bạn đẩy commit ở một nơi nào đó và mọi người kéo xuống máy của họ, sau đó bạn sửa lại các commit đó bằng lệnh `git rebase` và đẩy lên một lần nữa, đồng nghiệp của bạn sẽ phải tích hợp lại công việc của họ và mọi thứ sẽ rối tung lên khi bạn cố gắng kéo các thay đổi của họ ngược lại máy bạn. -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. +Hãy cùng xem một ví dụ làm sao việc rebase công khai có thể gây sự cố. Giả sử bạn tạo bản sao từ một máy chủ trung tâm và thực hiện một số thay đổi từ đó. Lịch sử commit của bạn sẽ giống như Hình 3-36. Insert 18333fig0336.png -Figure 3-36. Clone a repository, and base some work on it. +Hình 3-36. Tạo bản sao một kho chứa, và base một số thay đổi vào đó. -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. +Bây giờ, một người khác thực hiện một số thay đổi khác có kèm theo một lần tích hợp (merge), và đẩy lên máy chủ trung tâm. Bạn truy xuất chúng và tích hợp nhánh trung tâm mới đó vào của bạn, lúc này lịch sử của bạn sẽ giống như Hình 3-37. Insert 18333fig0337.png -Figure 3-37. Fetch more commits, and merge them into your work. +Hình 3-37. Truy xuất thêm các commit và tích hợp lại. -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. +Tiếp theo, người đã đẩy tích hợp đó quyết định lại và rebase lại những thay đổi của họ; họ thực hiện `git push --force` để ghi đè lịch sử trên máy chủ. Sau đó bạn truy xuất lại dữ liệu từ máy chủ, đưa về các commit mới. Insert 18333fig0338.png -Figure 3-38. Someone pushes rebased commits, abandoning commits you’ve based your work on. +Hình 3-38. Một người nào đó đẩy lên các commit rebase, bỏ đi các commit có chứa thay đổi của bạn. -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). +Lúc này, bạn phải tích hợp lại một lần nữa các thay đổi này, mặc dù trước đó bạn đã làm rồi. Quá trình rebase thay đổi mã băm SHA-1 của các commit này vì thế đối với Git chúng giống như các commit mới, mà thực tế thì bạn đã có C4 trong lịch sử của bạn (xem Hình 3-39). Insert 18333fig0339.png -Figure 3-39. You merge in the same work again into a new merge commit. +Hình 3-39. Bạn tích hợp các thay đổi tương tự lại một lần nữa vào một commit tích hợp mới. -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. +Bạn phải tích hợp thay đổi đó để có thể theo kịp với các lập trình viên khác về sau này. Sau khi thực hiện việc này, lịch sử commit của bạn sẽ bao gồm cả hai commit C4 và C4' có mã SHA-1 khác nhau nhưng lại có cùng chung nội dung thay đổi cũng như thông điệp commit. Nếu bạn chạy lệnh `git log` trong trường hợp này bạn sẽ thấy hai commit cùng chung ngày commit và thông điệp, điều này sẽ gây khó hiểu cho bạn. Hơn nữa, nếu bạn đẩy chúng ngược lên máy chủ, bạn sẽ đưa vào một lần nữa tất cả các commit đã rebase đó và sẽ gây khó hiểu cho nhiều người khác nữa. -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. +Nếu bạn sử dụng rebase như là cách để dọn dẹp các commit trước khi đẩy chúng lên, và nếu như bạn chỉ rebase commit chưa bao giờ được công khai, thì sẽ không có chuyện gì xảy ra. Nếu bạn rebase các commit đã được công khai và mọi người có thể đã tích hợp (base) nó vào công việc của họ thì bạn có thể gặp phải các vấn đề thực sự khó chị. -## Summary ## +## Tổng Kết ## -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. +Chúng ta đã đề cập tới các khái niệm cơ bản về phân nhánh và tích hợp trong Git. Bạn nên nắm vững việc tạo mới, di chuyển giữa các nhánh và tích hợp các nhánh nội bộ lại với nhau. Bạn cũng nên có khả năng chia sẽ các nhánh bằng cách đẩy chúng lên một máy chủ trung tâm, cộng tác với các thành viên khác trên các nhánh dùng chung và rebase chúng trước khi chia sẻ. \ No newline at end of file From b487a47a4092655e3068a7284084ed9ab8aa2da4 Mon Sep 17 00:00:00 2001 From: Tuan Vu Date: Fri, 3 Jan 2014 18:44:48 +0000 Subject: [PATCH 036/690] =?UTF-8?q?using=20't=C3=ADch=20h=E1=BB=A3p'=20ins?= =?UTF-8?q?tead=20of=20'g=E1=BB=99p'=20as=20translation=20for=20merge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vi/02-git-basics/01-chapter2.markdown | 22 +-- vi/03-git-branching/01-chapter3.markdown | 211 ++++++++++++----------- 2 files changed, 117 insertions(+), 116 deletions(-) diff --git a/vi/02-git-basics/01-chapter2.markdown b/vi/02-git-basics/01-chapter2.markdown index 73ef3e6a7..5904099a7 100644 --- a/vi/02-git-basics/01-chapter2.markdown +++ b/vi/02-git-basics/01-chapter2.markdown @@ -107,7 +107,7 @@ Hãy sửa một tập tin đang được theo dõi. Nếu bạn sửa một t # modified: benchmarks.rb # -Tập tin `benchmarks.rb` nằm trong danh sách "Các thay đổi chưa được tổ chức/đánh dấu để commit" - có nghĩa là một tập tin đang được theo dõi đã bị thay đổi trong thư mục làm việc nhưng chưa được "staged". Để làm việc này, bạn chạy lệnh `git add` (đó là một câu lệnh đa chức năng - bạn có thể dùng nó để bắt đầu theo dõi tập tin, tổ chức tập tin, hoặc các việc khác như đánh dấu đã giải quyết xong các tập tin có nội dung mâu thuẫn nhau khi gộp). Chạy `git add` để "stage" tập tin `benchmarks.rb` và sau đó chạy lại lệnh `git status`: +Tập tin `benchmarks.rb` nằm trong danh sách "Các thay đổi chưa được tổ chức/đánh dấu để commit" - có nghĩa là một tập tin đang được theo dõi đã bị thay đổi trong thư mục làm việc nhưng chưa được "staged". Để làm việc này, bạn chạy lệnh `git add` (đó là một câu lệnh đa chức năng - bạn có thể dùng nó để bắt đầu theo dõi tập tin, tổ chức tập tin, hoặc các việc khác như đánh dấu đã giải quyết xong các tập tin có nội dung mâu thuẫn nhau khi tích hợp). Chạy `git add` để "stage" tập tin `benchmarks.rb` và sau đó chạy lại lệnh `git status`: $ git add benchmarks.rb $ git status @@ -589,7 +589,7 @@ The lines must be formatted as follows Có thể bạn băn khoăn về sự khác nhau giữa _tác giả_ (author) và _người commit_ (committer). _Tác giả_ là người đầu tiên viết bản vá (patch), trong khi đó _người commit_ là người cuối cùng áp dụng miếng vá đó. Như vậy, nếu bạn gửi một bản vá cho một dự án và một trong các thành viên chính của dự án "áp dụng" (chấp nhận) bản vá đó, cả hai sẽ cùng được ghi nhận công trạng (credit) - bạn với vai trò là tác giả và thành viên của dự án trong vai trò người commit. Chúng ta sẽ bàn kỹ hơn một chút về sự khác nhau này trong *Chương 5*. -Lựa chọn `oneline` và `formar` đặc biệt hữu ích khi sử dụng với một tham số khác của `log` là `--graph`. Khi sử dụng, tham số này sẽ thêm một biểu đồ sử dụng dựa trên các ký tự ASCII hiển thị nhánh và lịch sử gộp các tập tin của bạn, chúng ta có thể thấy trong dự án Grit như sau: +Lựa chọn `oneline` và `formar` đặc biệt hữu ích khi sử dụng với một tham số khác của `log` là `--graph`. Khi sử dụng, tham số này sẽ thêm một biểu đồ sử dụng dựa trên các ký tự ASCII hiển thị nhánh và lịch sử tích hợp các tập tin của bạn, chúng ta có thể thấy trong dự án Grit như sau: $ git log --pretty=format:"%h %s" --graph * 2d3acf9 ignore errors from SIGCHLD on trap @@ -619,7 +619,7 @@ The lines must be formatted as follows --name-status Hiển thị các tập tin bị ảnh hưởng với các thông tin như thêm mới/sửa/xoá. --abbrev-commit Chỉ hiện thị một số ký tự đầu của mã băm SHA-1 thay vì tất cả 40. --relative-date Hiển thị ngày ở định dạng tương đối (ví dụ, "2 weeks ago") thay vì định dạng đầy đủ. - --graph Hiển thị biểu đồ ASCII của nhánh và lịch sử gộp cùng với thông tin đầu ra khác. + --graph Hiển thị biểu đồ ASCII của nhánh và lịch sử tích hợp cùng với thông tin đầu ra khác. --pretty Hiện thị các commit sử dụng một định dạng khác. Các lựa chọn bao gồm oneline, short, full, fuller và format (cho phép bạn sử dụng định dạng riêng). --oneline Một lựa chọn ngắn, thuận tiện cho `--pretty=oneline --abbrev-commit`. @@ -651,7 +651,7 @@ The lines must be formatted as follows --author Chỉ hiện thị các commit mà tên tác giả thoả mãn điều kiện nhất định. --committer Chỉ hiện thị các commit mà tên người commit thoả mãn điều kiện nhất định. -Ví dụ, bạn muốn xem các commit đã thay đổi các tập tin thử nghiệm trong lịch sử mã nguồn của Git, được commit bởi Junio Hâmno trng tháng 10 năm 2008 mà chưa được gộp/trộn, bạn có thể chạy lệnh sau: +Ví dụ, bạn muốn xem các commit đã thay đổi các tập tin thử nghiệm trong lịch sử mã nguồn của Git, được commit bởi Junio Hâmno trng tháng 10 năm 2008 mà chưa được tích hợp/gộp, bạn có thể chạy lệnh sau: $ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \ --before="2008-11-01" --no-merges -- t/ @@ -815,7 +815,7 @@ Bây giờ bạn có thể sử dụng `pb` trong các câu lệnh, nó có tác * [new branch] master -> pb/master * [new branch] ticgit -> pb/ticgit -Nhánh chính của Paul có thể truy cập cục bộ như là `pb/master` - bạn có thể gộp nó vào các nhánh của bạn, hoặc sử dụng nó như là một nhánh cục bộ ở thời điểm đó nếu như bạn muốn kiểm tra nó. +Nhánh chính của Paul có thể truy cập cục bộ như là `pb/master` - bạn có thể tích hợp nó vào các nhánh của bạn, hoặc sử dụng nó như là một nhánh cục bộ ở thời điểm đó nếu như bạn muốn kiểm tra nó. ### Truy Cập Và Kéo Về Từ Máy Chủ Trung Tâm ### @@ -823,11 +823,11 @@ Như bạn vừa thấy, để lấy dữ liệu của các dự án từ xa v $ git fetch [remote-name] -Lệnh này sẽ truy cập vào dự án từ xa đó và kéo xuống toàn bộ dữ liệu mà bạn chưa có trong đó cho bạn. Sau khi thực hiện xong bước này, bạn đã có các tham chiếu đến toàn bộ các nhánh của dự án từ xa đó, nơi mà bạn có thể gộp hoặc kiểm tra bất kỳ thời điểm nào. (Chúng ta sẽ đề cập chi tiết hơn về nhánh là gì và sử dụng chúng như thế nào ở *Chương 3*.) +Lệnh này sẽ truy cập vào dự án từ xa đó và kéo xuống toàn bộ dữ liệu mà bạn chưa có trong đó cho bạn. Sau khi thực hiện xong bước này, bạn đã có các tham chiếu đến toàn bộ các nhánh của dự án từ xa đó, nơi mà bạn có thể tích hợp hoặc kiểm tra bất kỳ thời điểm nào. (Chúng ta sẽ đề cập chi tiết hơn về nhánh là gì và sử dụng chúng như thế nào ở *Chương 3*.) -Nếu bạn tạo bản sao từ một kho chứa nào đó khác, lệnh này sẽ tự động kho chứa từ xa đó vào dưới tên *origin*. Vì thế, `git fetch origin` sẽ truy xuất (fetch) bất kỳ thay đổi mới nào được đẩy lên trên máy chủ từ sau khi bạn sao chép (hoặc lần truy xuất cuối cùng). Hãy ghi nhớ một điều quan trọng là lệnh `fetch` kéo tất cả dữ liệu về kho chứa trên máy của bạn - nó không tự động gộp với bất kỳ thay đổi nào mà bạn đang thực hiện. Bạn phải gộp nó một cách thủ không vào kho chứa nội bộ khi đã sẵn sàng. +Nếu bạn tạo bản sao từ một kho chứa nào đó khác, lệnh này sẽ tự động kho chứa từ xa đó vào dưới tên *origin*. Vì thế, `git fetch origin` sẽ truy xuất (fetch) bất kỳ thay đổi mới nào được đẩy lên trên máy chủ từ sau khi bạn sao chép (hoặc lần truy xuất cuối cùng). Hãy ghi nhớ một điều quan trọng là lệnh `fetch` kéo tất cả dữ liệu về kho chứa trên máy của bạn - nó không tự động tích hợp với bất kỳ thay đổi nào mà bạn đang thực hiện. Bạn phải tích hợp nó một cách thủ không vào kho chứa nội bộ khi đã sẵn sàng. -Nếu bạn có một nhánh được cài đặt để theo dõi một nhánh từ xa khác (xem phần tiếp theo và *Chương 3* để biết thêm chi tiết), bạn có thể sử dụng lệnh `git pull` để tự động truy xuất và sau đó gộp nhánh từ xa vào nhánh nội bộ. Đây có thể là cách dễ dàng và thoải mái hơn cho bạn; và mặc định thì, lệnh `git clone` tự động cài đặt nhánh chính nội bộ (local master branch) để theo dõi nhanh chính trên máy chủ từ xa (remote master branch) - nơi mà bạn sao chép về, (giả sử máy chủ từ xa có một nhánh chính). Thường thì khi chạy lệnh `git pull` nó sẽ truy xuất dữ liệu từ máy chủ trung tâm nơi lần đầu bạn sao chép và cố gắng tự động gộp chúng vào kho chứa hiện thời nơi bạn đang làm việc. +Nếu bạn có một nhánh được cài đặt để theo dõi một nhánh từ xa khác (xem phần tiếp theo và *Chương 3* để biết thêm chi tiết), bạn có thể sử dụng lệnh `git pull` để tự động truy xuất và sau đó tích hợp nhánh từ xa vào nhánh nội bộ. Đây có thể là cách dễ dàng và thoải mái hơn cho bạn; và mặc định thì, lệnh `git clone` tự động cài đặt nhánh chính nội bộ (local master branch) để theo dõi nhanh chính trên máy chủ từ xa (remote master branch) - nơi mà bạn sao chép về, (giả sử máy chủ từ xa có một nhánh chính). Thường thì khi chạy lệnh `git pull` nó sẽ truy xuất dữ liệu từ máy chủ trung tâm nơi lần đầu bạn sao chép và cố gắng tự động tích hợp chúng vào kho chứa hiện thời nơi bạn đang làm việc. ### Đẩy Lên Máy Chủ Trung Tâm ### @@ -835,7 +835,7 @@ Nếu bạn có một nhánh được cài đặt để theo dõi một nhánh t $ git push origin master -Lệnh này chỉ hoạt động nếu bạn sao chép từ một máy chủ mà trên đó bạn được cấp phép quyền ghi và chưa có ai khác đẩy dữ liệu lên tại thời điểm đó. Nếu bạn và ai khác cùng sao chép tại cùng một thời điểm; người kia đẩy ngược lên, sau đó bạn cũng muốn đẩy lên, thì hành động của bạn sẽ bị từ chối ngay tức khắc. Trước hết bạn phải thực hiện kéo các thay đổi mà người đó đã thực hiện và sát nhập/gộp nó vào của bạn, sau đó bạn mới được phép đẩy lên. Xem *Chương 3* để hiểu chi tiết hơn về làm thế nào để đẩy lên máy chủ trung tâm. +Lệnh này chỉ hoạt động nếu bạn sao chép từ một máy chủ mà trên đó bạn được cấp phép quyền ghi và chưa có ai khác đẩy dữ liệu lên tại thời điểm đó. Nếu bạn và ai khác cùng sao chép tại cùng một thời điểm; người kia đẩy ngược lên, sau đó bạn cũng muốn đẩy lên, thì hành động của bạn sẽ bị từ chối ngay tức khắc. Trước hết bạn phải thực hiện kéo các thay đổi mà người đó đã thực hiện và tích hợp/gộp nó vào của bạn, sau đó bạn mới được phép đẩy lên. Xem *Chương 3* để hiểu chi tiết hơn về làm thế nào để đẩy lên máy chủ trung tâm. ### Kiểm Tra Một Máy Chủ Trung Tâm ### @@ -850,7 +850,7 @@ Nếu bạn muốn xem chi tiết hơn các thông tin về một kho chứa tru master ticgit -Lệnh này liệt kê địa chỉ của kho chứa trung tâm cũng như thông tin các nhánh đang theo dõi. Nó cho bạn biết rằng nếu như bạn đang ở nhánh master và chạy lệnh git pull, nó sẽ tự động gộp nhánh này với nhánh trung tâm sau khi truy xuất toàn bộ các tham chiếu từ xa. Nó cũng liệt kê tất cả các tham chiếu từ xa mà nó đã kéo xuống đó. +Lệnh này liệt kê địa chỉ của kho chứa trung tâm cũng như thông tin các nhánh đang theo dõi. Nó cho bạn biết rằng nếu như bạn đang ở nhánh master và chạy lệnh git pull, nó sẽ tự động tích hợp nhánh này với nhánh trung tâm sau khi truy xuất toàn bộ các tham chiếu từ xa. Nó cũng liệt kê tất cả các tham chiếu từ xa mà nó đã kéo xuống đó. Đây là một ví dụ đơn giản mà bạn thường xuyên gặp phải. Khi bạn sử dụng Git thường xuyên hơn, bạn sẽ thường thấy nhiều thông tin hơn từ lệnh `git remote show`: @@ -876,7 +876,7 @@ Lệnh này liệt kê địa chỉ của kho chứa trung tâm cũng như thôn Local branch pushed with 'git push' master:master -Lệnh này hiển thị nhánh nào tự động được đẩy lên khi bạn chạy `git push` trên một nhánh nhất định. Nó cũng cho bạn thấy nhánh nào trên máy chủ trung tâm mà bạn chưa có, nhánh nào bạn có mà đã bị xóa trên máy chủ, và các nhánh nào sẽ tự động được gộp khi chạy lệnh `git pull`. +Lệnh này hiển thị nhánh nào tự động được đẩy lên khi bạn chạy `git push` trên một nhánh nhất định. Nó cũng cho bạn thấy nhánh nào trên máy chủ trung tâm mà bạn chưa có, nhánh nào bạn có mà đã bị xóa trên máy chủ, và các nhánh nào sẽ tự động được tích hợp khi chạy lệnh `git pull`. ### Xóa Và Đổi Tên Từ Xa ### diff --git a/vi/03-git-branching/01-chapter3.markdown b/vi/03-git-branching/01-chapter3.markdown index 8924dbe5e..6feadfe84 100644 --- a/vi/03-git-branching/01-chapter3.markdown +++ b/vi/03-git-branching/01-chapter3.markdown @@ -1,152 +1,152 @@ -# Git Branching # +# Phân Nhánh Trong Git # -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. +Hầu hết mỗi hệ quản trị phiên bản (VCS) đều hỗ trợ một dạng của phân nhánh. Phân nhánh có nghĩa là bạn phân tách ra từ luồng phát triển chính và tiếp tục làm việc mà không sợ làm ảnh hưởng đến luồng chính. Trong nhiều VCS, đây dường như là một quá trình đòi hỏi nhiều công sức và sự cố gắng, thường thì bạn tạo một bản sao mới từ thư mục chứa mã nguồn, nó có thể mất khá nhiều thời gian trên các dự án lớn. -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. +Nhiều người nhắc đến mô hình phân nhánh của Git như là "chức năng hủy diệt", và chính nó làm cho Git trở nên khác biệt trong cộng đồng VCS. Tại sao nó lại đặc biệt đến vậy? Cách Git phân nhánh "nhẹ" một cách đáng kinh ngạc, các hoạt động tạo nhánh xảy ra gần như ngay lập tức và việc di chuyển đi lại giữa các nhánh cũng thường rất nhanh. Không giống các VCSs khác, Git khuyến khích sử dụng rẽ nhánh và tích hợp thường xuyên cho workflow, thậm chí nhiều lần trong một ngày. Hiểu và thành thạo tính năng này cung cấp cho bạn một công cụ mạnh mẽ, độc đáo và có thể thay đổi được cách bạn thường phát triển phần mềm. -## What a Branch Is ## +## Nhánh Là Gì? ## -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. +Để có thể thực sử hiểu được cách phân nhánh của Git, chúng ta cần nhìn và xem xét lại cách Git lưu trữ dữ liệu. Như bạn đã biết từ Chương 1, Git không lưu trữ dữ liệu dưới dạng một chuỗi các thay đổi hoặc delta, mà thay vào đó là một chuỗi các ảnh (snapshot). -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. +Khi bạn commit, Git lưu trữ đối tượng commit mà có chứa một con trỏ tới ảnh của nội dung bạn đã tổ chức (stage), tác giả và thông điệp, hay 0 hoặc nhiều con trỏ khác trỏ tới một hoặc nhiều commit cha trực tiếp của commit đó: commit đầu tiên không có cha, commit bình thường có một cha, và nhiều cha cho commit là kết quả được tích hợp lại từ hai hoặc nhiều nhánh. -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: +Để hình dung ra vấn đề này, hãy giả sử bạn có một thư mục chứa ba tập tin, và bạn tổ chức tất cả chúng để commit. Quá trình tổ chức các tập tin sẽ thực hiện băm từng tập (sử dụng mã SHA-1 được đề cập ở Chương 1), lưu trữ phiên bản đó của tập tin trong kho chứa Git (Git xem chúng như là các blob), và thêm mã băm đó vào khu vực tổ chức: $ 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. +Lệnh `git commit` khi chạy sẽ băm tất cả các thư mục trong dự án và lưu chúng lại dưới dạng đối tượng `tree`. Sau đó Git tạo một đối tượng `commit` có chứa các thông tin mô tả (metadata) và một con trỏ trỏ tới đối tương `tree` gốc của dự án vì thế nó có thể tạo lại ảnh đó khi cần thiết. -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. +Kho chứa Git của bạn bây giờ có chứa năm đối tượng: một blob cho nội dung của từng tập tin, một "cây" liệt kê nội dung của thư mục và chỉ rõ tên tập tin nào được lưu trữ trong blob nào, và một commit có con trỏ trỏ tới cây gốc và tất cả các thông tin mô tả commit. Về mặt lý thuyết, dữ liệu trong kho chứa Git có hình dạng như trong Hình 3-1. Insert 18333fig0301.png -Figure 3-1. Single commit repository data. +Hình 3-1. Dữ liệu trong kho chứa với một commit. -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. +Nếu bạn thực hiện một số thay đổi và commit lại thì commit tiếp theo sẽ lưu một con trỏ tới commit ngay trước nó. Sau hai commit, lịch sử của dự án sẽ tương tự như trong Hình 3-2. Insert 18333fig0302.png -Figure 3-2. Git object data for multiple commits. +Hình 3-2. Các đối tượng dữ liệu của Git trong kho chứa nhiều commit. -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. +Một nhánh trong Git đơn thuần là một con trỏ có khả năng di chuyển được, trỏ đến một trong những commit này. Tên nhánh mặc định của Git là master. Như trong những lần commit đầu tiên, chúng đều được trỏ tới nhánh `master`. Và mỗi lần bạn thực hiện commit, nó sẽ được tự động ghi vào theo hướng tiến lên. (move forward) Insert 18333fig0303.png -Figure 3-3. Branch pointing into the commit data’s history. +Hình 3-3. Nhánh trỏ tới dữ liệu commit. -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: +Chuyện gì xảy ra nếu bạn tạo một nhánh mới? Làm như vậy sẽ tạo ra một con trỏ mới cho phép bạn di chuyển vòng quanh. Ví dụ bạn tạo một nhánh mới có tên testing. Việc này được thực hiện bằng lệnh `git branch`: $ git branch testing -This creates a new pointer at the same commit you’re currently on (see Figure 3-4). +Nó sẽ tạo một con trỏ mới, cùng trỏ tới commit hiện tại (mới nhất) của bạn (xem Hình 3-4). Insert 18333fig0304.png -Figure 3-4. Multiple branches pointing into the commit’s data history. +Hình 304. Nhiều nhánh cùng trỏ vào dữ liệu commit. -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). +Vậy làm sao Git có thể biết được rằng bạn đang làm việc trên nhánh nào? Git giữ một con trỏ đặc biệt có tên HEAD. Lưu ý khái niệm về HEAD ở đây khác biệt hoàn toàn với các VCS khác mà bạn có thể đã sử dụng qua, như là Subversion hoặc CVS. Trong Git, đây là một con trỏ tới nhánh nội bộ mà bạn đang làm việc. Trong trường hợp này, bạn vẫn đang trên nhánh master. Lệnh git branch chỉ tạo một nhánh mới chứ không tự chuyển sang nhánh đó cho bạn (xem Hình 3-5). Insert 18333fig0305.png -Figure 3-5. HEAD file pointing to the branch you’re on. +Hình 3-5. Tập tin HEAD trỏ tới nhánh mà bạn đang làm việc. -To switch to an existing branch, you run the `git checkout` command. Let’s switch to the new testing branch: +Để chuyển sang một nhánh đang tồn tại, bạn sử dụng lệnh `git checkout`. Hãy cùng chuyển sang nhánh testing mới: $ git checkout testing -This moves HEAD to point to the testing branch (see Figure 3-6). +Lệnh này sẽ chuyển con trỏ HEAD sang nhánh testing (xem Hình 3-6). Insert 18333fig0306.png -Figure 3-6. HEAD points to another branch when you switch branches. +Hình 3-6. HEAD trỏ tới nhánh khác khi bạn chuyển nhánh. -What is the significance of that? Well, let’s do another commit: +Ý nghĩa của việc này là gì? Hãy cùng thực hiện một commit khác: $ vim test.rb $ git commit -a -m 'made a change' -Figure 3-7 illustrates the result. +Hình 3-7 minh họa kết quả. Insert 18333fig0307.png -Figure 3-7. The branch that HEAD points to moves forward with each commit. +Hình 3-7. Nhánh mà HEAD trỏ tới di chuyển tiến lên phía trước theo từng 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: +Điều này thật thú vị, bởi vì nhánh testing của bạn bây giờ đã tiển hẳn lên phía trước, nhưng nhánh `master` thì vẫn trỏ tới commit ở thời điểm khi bạn chạy lệnh `git checkout` để chuyển nhánh. Hãy cùng chuyển trở lại nhánh `master`: $ git checkout master -Figure 3-8 shows the result. +Hình 3-8 hiển thị kết quả. Insert 18333fig0308.png -Figure 3-8. HEAD moves to another branch on a checkout. +Hình 3-8. HEAD chuyển sang nhánh khác khi 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. +Lệnh này vừa thực hiện hai việc. Nó di chuyển lại con trỏ về nhánh `master`, và sau đó nó phục hồi lại các tập tin trong thư mục làm việc của bạn trở lại snapshot mà `master` trỏ tới. Điều này cũng có nghĩa là các thay đổi bạn thực hiện từ thời điểm này trở đi sẽ tách ra so với phiên bản cũ hơn của dự án. Nó "tua lại" các thay đổi cần thiết mà bạn đã thực hiện trên nhánh `testing` một cách tạm thời để bạn có thể đi theo một hướng khác. -Let’s make a few changes and commit again: +Hãy cùng tạo một vài thay đổi và commit lại một lần nữa: $ 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. +Bây giờ lịch sử của dự án đã bị tách ra (xem Hình 3-9). Bạn tạo mới và chuyển sang một nhánh, thực hiện một số thay đổi trên đó, và rồi chuyển ngược lại nhánh chính và tạo thêm các thay đổi khác. Cả hai sự thay đổi này bị cô lập với nhau ở hai nhánh riêng biệt: bạn có thể chuyển đi hoặc lại giữa cách nhánh và tích hợp chúng lại với nhau khi cần thiết. Và bạn đã thực hiện những việc trên một cách đơn giản với lệnh `branch` và `checkout`. Insert 18333fig0309.png -Figure 3-9. The branch histories have diverged. +Hình 3-9. Lịch sử các nhánh đã bị phân tách. -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). +Bởi vì một nhánh trong Git thực tế là một tập tin đơn giản chứa một mã băm SHA-1 có độ dài 40 ký tự của commit mà nó trỏ tới, chính vì thế tạo mới cũng như hủy các nhánh đi rất đơn giản. Tạo mới một nhánh nhanh tương đương với việc ghi 41 bytes vào một tập tin (40 ký tự cộng thêm một dòng mới). -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. +Điều này đối lập rất lớn với cách mà các VCS khác phân nhánh, chính là copy toàn bộ các tập tin hiện có của dự án sang một thư mục thứ hai. Việc này có thể mất khoảng vài giây, thậm chí vài phút, phụ thuộc vào dung lượng của dự án, trong khi đó trong Git thì quá trình này luôn xảy ra ngay lập tức. Thêm một lý do nữa là, chúng ta đang lưu trữ cha của các commit, nên việc tìm kiếm gốc/cơ sở để tích hợp lại được thực hiện một cách tự động và rất dễ dàng. Những tính năng này giúp khuyến khích các lập trình viên tạo và sử dụng nhánh thường xuyên hơn. -Let’s see why you should do so. +Hãy cùng xem tại sao bạn nên làm như vậy. -## Basic Branching and Merging ## +## Cơ Bản Về Phân Nhánh và Tích Hợp ## -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: +Hãy cùng xem qua một ví dụ đơn giản về phân nhánh và tích hợp với một quy trình làm việc mà có thể bạn sẽ sử dụng nó vào thực tế. Bạn sẽ thực hiện theo các bước sau: -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. +1. Làm việc trên một web site +2. Tạo nhánh cho một câu chuyện mới mà bạn đang làm. +3. Làm việc trên nhánh đó. -At this stage, you’ll receive a call that another issue is critical and you need a hotfix. You’ll do the following: +Đến lúc này, bạn nhận được thông báo rằng có một vấn đề nghiêm trọng cần được khắc phục ngay. Bạn sẽ làm theo các bước sau: -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. +1. Chuyển lại về nhánh sản xuất (production) +2. Tạo mới một nhánh khác để khắc phục lỗi +3. Sau khi đã kiểm tra ổn định, tích hợp nhánh đó lại và đưa vào hoạt động. +4. Chuyển ngược lại với câu chuyện của bạn và tiếp tục làm việc. -### Basic Branching ### +### Cơ Bản về Phân Nhánh ### -First, let’s say you’re working on your project and have a couple of commits already (see Figure 3-10). +Đầu tiên, giả sử bạn đang làm việc trên một dự án đã có một số commit từ trước (xem Hình 3-10). Insert 18333fig0310.png -Figure 3-10. A short and simple commit history. +Hình 3-10. Một lịch sử commit ngắn và đơn giản. -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: +Bạn quyết định sẽ giải quyết vấn đề số #53 sử dụng bất kỳ hệ thống giám sát vấn đề (issue-tracking) nào mà công ty bạn đang dùng. Để cho rõ ràng, Git không cung cấp kèm bất kỳ hệ thống giám sát vấn đề nào; nhưng bởi vì vấn đề số #53 là cái mà bạn sẽ tập trung vào nên bạn sẽ tạo một nhánh mới để làm việc trên đó. Để tạo một nhánh và chuyển sang nhánh đó đồng thời, bạn có thể chạy lệnh `git checkout` với tham số `-b`: $ git checkout -b iss53 Switched to a new branch "iss53" -This is shorthand for: +Đây là cách sử dụng vắn tắt của: $ git branch iss53 $ git checkout iss53 -Figure 3-11 illustrates the result. +Hình 3-11 minh họa kết quả. Insert 18333fig0311.png -Figure 3-11. Creating a new branch pointer. +Hình 3-11. Tạo con trỏ nhánh mới. -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): +Bạn làm việc trên đó và sau đó thực hiện một số commit. Làm như vậy sẽ khiến nhánh `iss53` di chuyển tiến lên, vì bạn đã checkout nó (hay, HEAD đang trỏ đến nó; xem Hình 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. +Hình 3-12. Nhánh iss53 đã di chuyển tiến lên cùng với thay đổi của bạn. -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. +Bây giờ bạn nhận được thông báo rằng có một vấn đề với trang web, và bạn cần khắc phục nó ngay lập tức. Với Git, bạn không phải triển khai bản vá lỗi cùng với các thay đổi bạn đã thực hiện trên nhánh `iss53`, và bạn không phải tốn quá nhiều công sức để khôi phục lại các thay đổi đó trước khi áp dụng bản vá vào sản xuất. Tất cả những gì bạn cần phải làm là chuyển lại nhánh master. -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: +Tuy nhiên, trước khi làm điều này, bạn nên lưu ý rằng nếu thư mục làm việc hoặc khu vực tổ chức có chứa các thay đổi chưa được commit mà xung đột với nhánh bạn đang làm việc, Git sẽ không cho phép bạn chuyển nhánh. Tốt nhất là bạn nên ở trạng thái làm việc "sạch" (đã commit hết) trước khi chuyển nhánh. Có các cách khác để khắc phục vấn đề này (đó là stashing và sửa commit) mà chúng ta sẽ bàn tới sau. Hiện tại, bạn đã commit hết các thay đổi, vì vậy bạn có thể chuyển lại nhánh master: $ 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. +Tại thời điểm này, thư mục làm việc của dự án giống hệt như trước khi bạn bắt đầu giải quyết vấn đề #53, và bạn có thể tập trung vào việc sửa lỗi. Điểm quan trọng cần ghi nhớ: Git khôi phục lại thư mục làm việc của bạn để nó giống như snapshot của commit mà nhánh bạn đang làm việc trỏ tới. Nó thêm, xóa, và sửa các tập tin một cách tự động để đảm bảo rằng thư mục làm việc của bạn giống như lần commit cuối cùng. -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): +Tiếp theo, bạn có mỗi lỗi cần phải sửa. Hãy tạo mỗi nhánh để làm việc này cho tới khi nó được hoàn thành (xem Hình 3-13): $ git checkout -b hotfix Switched to a new branch "hotfix" @@ -156,9 +156,9 @@ Next, you have a hotfix to make. Let’s create a hotfix branch on which to work 1 files changed, 0 insertions(+), 1 deletions(-) Insert 18333fig0313.png -Figure 3-13. hotfix branch based back at your master branch point. +Hình 3-13. Nhánh hotfix dựa trên nhánh master. -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: +Bạn có thể chạy để kiểm tra, để chắc chắn rằng bản vá lỗi hoạt động đúng theo ý bạn muốn, và sau đó tích hợp nó lại nhánh chính để triển khai. Bạn có thể làm sử dụng lệnh `git merge` để làm việc này: $ git checkout master $ git merge hotfix @@ -167,19 +167,19 @@ You can run your tests, make sure the hotfix is what you want, and merge it back 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". +Bạn sẽ nhận thấy rằng cụm từ "Fast forward" trong lần tích hợp đó. Bởi vì commit được trở tới bởi nhánh mà bạn tích hợp vào lại trực tiếp là upstream của commit hiện tại, vì vậy Git di chuyển con trỏ về phía trước. Nói cách khác, khi bạn cố gắng tích hợp một commit với một commit khác mà có thể truy cập được từ lịch sử của commit trước thì Git sẽ đơn giản hóa bằng cách di chuyển con trỏ về phía trước vì không có sự rẽ nhánh nào để tích hợp - đây được gọi là "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). +Thay đổi của bạn bây giờ ở trong snapshot của commit được trỏ tới bởi nhánh `master`, và bạn có thể triển khai thay đổi này (xem Hình 3-14). Insert 18333fig0314.png -Figure 3-14. Your master branch points to the same place as your hotfix branch after the merge. +Hình 3-14. Nhánh master và nhánh hotfix cùng trỏ tới một điểm sau khi tích hợp. -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`: +Sau khi triển khai xong bản vá lỗi quan trọng đó, bạn đã sẵn sàng để quay lại với công việc bị gián đoạn trước đó. Tuy nhiên, việc đầu tiên cần làm là xóa nhánh `hotfix` đi, vì bạn không còn cần tới nó nữa - nhánh `master` trỏ tới cùng một điểm. Bạn có thể xóa nó đi bằng cách sử dụng tham số `-d` cho lệnh `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): +Bây giờ bạn đã có thể chuyển lại nhánh mà bạn đang làm việc trước đó về vấn đề #53 và tiếp tục làm việc (xem Hình 3-15): $ git checkout iss53 Switched to branch "iss53" @@ -189,13 +189,13 @@ Now you can switch back to your work-in-progress branch on issue #53 and continu 1 files changed, 1 insertions(+), 0 deletions(-) Insert 18333fig0315.png -Figure 3-15. Your iss53 branch can move forward independently. +Hình 3-15. Nhánh iss53 có thể di chuyển về phía trước một cách độc lập. -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. +Điều đáng chú ý ở đây là những công việc bạn đã thực hiện ở nhánh `hotfix` không bao gồm trong nhánh `iss53`. Nếu bạn muốn đưa chúng vào, bạn có thể tích hợp nhánh `master` vào nhánh `iss53` bằng cách chạy lệnh `git merge master`, hoặc bạn có thể chờ đợi đến khi bạn quyết định tích hợp nhánh `iss53` ngược trở lại nhánh `master` về sau. -### Basic Merging ### +### Cơ Bản Về Tích Hợp ### -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: +Giả sử bạn đã quyết định việc giải quyết vấn đề #53 đã hoàn thành và sẵn sàng để tích hợp vào nhánh `master`. Để làm được điều này, bạn sẽ tích hợp nhánh `iss53` lại, giống như bạn đã làm với nhánh `hotfix` trước đó. Tất cả những gì cần phải làm là chuyển sang (check out) nhánh mà bạn muốn được tích hợp vào và chạy lệnh `git merge`: $ git checkout master $ git merge iss53 @@ -203,32 +203,32 @@ Suppose you’ve decided that your issue #53 work is complete and ready to be me 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. +Lần này có hơi khác so với lần tích hợp `hotfix` trước đó. Trong trường hợp này, lịch sử phát triển của bạn đã bị phân nhánh tại một thời điểm nào đó trước kia. Bởi vì commit trên nhánh mà bạn đang làm việc (master) không phải là "cha" trực tiếp của nhánh mà bạn đang tích hợp vào, Git phải làm một số việc. Trường hợp này, Git thực hiện một tích hợp 3-chiều, sử dụng hai snapshot được trỏ tới bởi các đầu mút của nhánh và "cha chung" của cả hai. Hình 3-16 minh họa ba snapshot mà Git sử dụng để thực hiện phép tích hợp trong trường hợp này. Insert 18333fig0316.png -Figure 3-16. Git automatically identifies the best common-ancestor merge base for branch merging. +Hình 3-16. Git tự động nhận dạng "cha chung" phù hợp nhất để tích hợp các nhánh lại với nhau. -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. +Thay vì việc chỉ di chuyển con trỏ về phía trước, Git tạo một snapshot mới - được hợp thành từ lần tích hợp 3-chiều này và cũng tự tạo một commit mới trỏ tới nó (xem Hình 3-17). Nó được biết tới như là "commit tích hợp" (merge commit) và nó đặc biệt vì có nhiều hơn một cha. -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. +Đáng để chỉ ra rằng Git tự quyết định cha chung phù hợp nhất để sử dụng làm cơ sở cho việc tích hợp; điểm này khác với CVS hay Subversion (các phiên bản trước 1.5), khi mà các lập trình viên phải tự xác định cơ sở phù hợp nhất để tích hợp. Điều này khiến cho việc tích hợp trong Git trở nên dễ dàng hơn rất nhiều so với các hệ quản trị phiên bản khác. Insert 18333fig0317.png -Figure 3-17. Git automatically creates a new commit object that contains the merged work. +Hình 3-17. Git tự động tạo đối tượng commit mới chứa đựng các thay đổi đã tích hợp. -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: +Bây giờ công việc của bạn đã được tích hợp lại với nhau, bạn không cần thiết phải giữ lại nhánh `iss53` nữa. Bạn có thể xóa nó đi và sau đó tự xóa vấn đề này trong hệ thống quản lý vấn đề của bạn: $ git branch -d iss53 -### Basic Merge Conflicts ### +### Mâu Thuẫn Khi Tích Hợp ### -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: +Đôi khi, quá trình này không diễn ra một cách suôn sẻ. Nếu bạn thay đổi cùng một nội dung của cùng một tập tin ở hai nhánh khác nhau mà bạn đang muốn tích hợp vào, Git không thể tích hợp chúng một cách gọn gàng. Nếu bản vá lỗi cho vấn đề #53 cùng thay đổi một phần của một tập tin giống như nhánh `hotfix`, bạn sẽ nhận được một sự xung đột khi tiến hành tích hợp như sau: $ 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`: +Git chưa tự tạo commit tích hợp mới. Nó tạm dừng quá trình này lại cho đến khi bạn giải quyết xong xung đột. Nếu bạn muốn xem tập tin nào chưa được tích hợp tại bất kỳ thời điểm nào sau khi xung đột xảy ra, bạn có thể sử dụng lệnh `git status`: [master*]$ git status index.html: needs merge @@ -240,7 +240,7 @@ Git hasn’t automatically created a new merge commit. It has paused the process # 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: +Với bất kỳ xung đột nào xảy ra mà chưa được giải quyết, chúng sẽ được liệt kê là unmerged (chưa được tích hợp). Git thêm các dấu hiệu chuẩn riêng để giải quyết xung đột vào các tập tin có xảy ra xung đột, vì thế bạn có thể mở và giải quyết các xung đột đó một cách thủ công. Tập tin của bạn sẽ chứa một phần tương tự như sau: <<<<<<< HEAD:index.html @@ -250,14 +250,13 @@ Anything that has merge conflicts and hasn’t been resolved is listed as unmerg >>>>>>> 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: +Điều này có nghĩa là phiên bản trong HEAD (nhánh master, vì nó là nhánh bạn đã check out khi chạy lệnh merge) là phần mới nhất của đoạn đó (mọi thứ phía trên `=======`), trong khi phiên bản ở nhánh `iss53` chính là phần phía dưới. Để giải quyết vấn đề này, bạn phải chọn một trong hai phần hoặc tự gộp nội dung của chúng lại. Ví dụ, có thể bạn giải quyết xung đột này bằng cách thay thế toàn bộ đoạn code đó bằng: -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: +Cách giải quyết này có chứa nội dung của cả hai phần, và tôi đã xóa bỏ hoàn toàn các dòng `<<<<<<<`, `=======`, và `>>>>>>>`. Sau khi giải quyết xong tất cả các phần này trong các tập tin bị xung đột, chạy lệnh `git add` cho từng tập tin để đánh dấu là chúng đã được giải quyết. Tổ chức chúng cùng đồng nghĩa với việc đánh dấu là đã được giải quyết trong Git. Nếu bạn muốn sử dụng một công cụ có giao diện đồ họa để giải quyết những vấn đề này, bạn có thể sử dụng `git mergetool`, Git sẽ tự động mở chương trình tương ứng và trợ giúp bạn giải quyết các xung đột: $ git mergetool merge tool candidates: kdiff3 tkdiff xxdiff meld gvimdiff opendiff emerge vimdiff @@ -268,11 +267,11 @@ If you want to use a graphical tool to resolve these issues, you can run `git me {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. +Nếu bạn muốn sử dụng một công cụ tích hợp khác thay vì chương trình mặc định (Git sử dụng `opendiff` cho tôi trong trường hợp này vì tôi đang sử dụng một máy tính Mac), bạn có thể xem danh sách các chương trình tương thích bằng cách chạy lệnh "merge tool candidates". Gõ tên chương trình bạn muốn sử dung. Trong Chương 7, chúng ta sẽ cùng bàn luận về việc làm thế nào để thay đổi giá trị mặc định này. -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. +Sau khi thoát khỏi chương trình hỗ trợ tích hợp, Git sẽ hỏi bạn nếu tích hợp thành công. Nếu bạn trả lời đúng, nó sẽ đánh dấu tập tin đó là đã giải quyết cho bạn. -You can run `git status` again to verify that all conflicts have been resolved: +Bạn có thể chạy `git status` lại một lần nữa để xác thực rằng tất cả các xung đột đã được giải quyết: $ git status # On branch master @@ -282,7 +281,7 @@ You can run `git status` again to verify that all conflicts have been resolved: # 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: +Nếu bạn hài lòng với điều này, và chắc chắn rằng tất cả các xung đột đã được tổ chức, bạn có thể chạy lệnh `git commit` để hoàn thành commit tích hợp. Thông điệp mặc định của commit có dạng như sau: Merge branch 'iss53' @@ -295,66 +294,68 @@ If you’re happy with that, and you verify that everything that had conflicts h # 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. +Bạn có sửa lại nội dung này với các chi tiết về việc bạn đã giải quyết như thế nào nếu bạn cho rằng các thông tin đó sẽ có ích cho các thành viên khác sau này - tại sao bạn lại làm như vậy, nếu như chúng còn chưa rõ ràng. -## Branch Management ## +## Quản Lý Các Nhánh ## -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. +Bạn đã tạo mới, tích hợp, và xóa một số nhánh, bây giờ hãy cùng xem một số công cụ giúp việc quản lý nhánh trở nên dễ dàng hơn khi tần suất sử dụng nhánh của bạn ngày càng nhiều. -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: +Lệnh `git branch` thực hiện nhiều việc hơn là chỉ tạo và xóa nhánh. Nếu bạn chạy nó không có tham số, bạn sẽ có danh sách của tất cả các nhánh hiện tại: $ 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`: +Lưu ý về ký tự `*` đứng trước nhánh `master`: nó chỉ cho bạn thấy nhánh mà bạn đang làm việc (Checkout). Có nghĩa là nếu bạn commit ở thời điểm hiện tại, thì nhánh `master` sẽ di chuyển tiến lên phía trước với các thay đổi mới. Để xem commit mới nhất trên từng nhánh, bạn có thể chạy lệnh `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`: +Một lựa chọn hữu ích khác để tìm ra trạng thái của các nhánh là lọc qua các nhánh bạn đã hoặc chưa tích hợp vào nhánh hiện tại. Các lựa chọn để sử dụng cho mục đích này gồm `--merged` và `--no-merged`. Để biết nhánh nào đã được tích hợp vào nhánh hiện tại, bạn có thể sử dụng `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. +Bởi vì bạn đã tích hợp nhánh `iss53` vào trước đó, bạn sẽ thấy nó ở trong danh sách này. Cách nhánh trong danh sách không có dấu `*` ở phía trước thường an toàn để xóa bằng cách sử dụng `git branch -d`; bạn đã tích hợp các thay đổi trong đó vào một nhánh khác, vì thế bạn sẽ không hề bị mất bất cứ dữ liệu gì. -To see all the branches that contain work you haven’t yet merged in, you can run `git branch --no-merged`: +Để xem cách nhánh chứa các công việc/thay đổi chưa được tích hợp vào, bạn có thể chạy lệnh `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: +Lệnh này lại hiện thị các nhánh khác. Bởi vì chúng bao gồm các công việc mà bạn chưa tích hợp vào, xóa nó đi bằng lệnh `git branch -d` sẽ báo lỗi: $ 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. +Nếu bạn thực sự muốn xóa nó đi và chấp nhận mất các thay đổi, bạn có thể bắt buộc bằng cách sử dụng tham số `-D`, như hướng dẫn trong thông báo trên. -## Branching Workflows ## +## Quy Trình Làm Việc Phân Nhánh ## -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. +Bây giờ bạn đã có được các kiến thức cơ bản về phân nhánh và tích hợp, vậy bạn có thể hay nên làm gì với chúng. Trong phần này, chúng ta sẽ đề cập tới một số quy trình làm việc phổ biến áp dụng phân nhánh, vì thế bạn có thể tự quyết định có áp dụng chúng vào quy trình làm việc riêng của bạn hay không. -### Long-Running Branches ### +### Nhánh Lâu Đời ### -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. +Bởi vì Git sử dụng tích hợp 3 chiều đơn giản, nên tích hợp từ nhánh này vào nhánh khác nhiều lần trong cùng một giai đoạn thường dễ dàng. Có nghĩa là bạn có thể có nhiều nhánh luôn mở và sử dụng chúng cho các giai đoạn phát triển khác nhau; bạn có thể tích hợp từ một số nhánh nào đó vào các nhánh khác một cách thường xuyên. -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. +Nhiều lập trình viên Git sử dụng quy trình làm việc dựa theo phương pháp này, chẳng hạn như chỉ chứa mã nguồn ổn định hoàn toàn ở nhánh `master` - hầu như là mã nguồn đã phát hành hoặc chuẩn bị phát hành. Họ có một nhánh song song khác có tên develop hoặc next, nơi mà họ làm việc hoặc sử dụng để kiểm tra độ ổn định - nó không nhất thiết luôn luôn phải ổn định, tuy nhiên mỗi khi nó đạt được trạng thái ổn định, nó sẽ được tích hợp vào nhánh `master`. Chúng được sử dụng với vai trò là các nhánh chủ đề (topic branch) - các nhánh có vòng đời ngắn, giống như nhánh `iss53` trước đó - để đảm bảo chúng qua được các bài kiểm tra và không gây ra lỗi. -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). +Trong thực tế, chúng ta đang nói về các con trỏ di chuyển dọc theo đường thẳng của các commit. Các nhánh ổn định hơn thường ở phía cuối của đường thẳng, còn các nhánh đang phát triển thường ở phía đầu hàng (xem Hình 3-18). Insert 18333fig0318.png -Figure 3-18. More stable branches are generally farther down the commit history. +Hình 3-18. Nhánh ổn định hơn thường ở phía cuối hàng trong lịch sử commit. -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). +Sẽ dễ hình dung hơn khi nghĩ về chúng như là các xi-lô, nơi mà tập hợp các commit cô đặc dần thành một xi-lô ổn định hơn khi đã được kiểm tra đầy đủ (xem Hình 3-19). Insert 18333fig0319.png -Figure 3-19. It may be helpful to think of your branches as silos. +Hình 3-19. Có lẽ sẽ dễ hiểu hơn khi coi các nhánh là các xi-lô. + +Bạn có thể tiếp tục làm theo cách này cho nhiều tầng ổn định khác nhau. Nhiều dự án lớn có nhánh `proposed` hoặc `pu` (proposed updates) được sử dụng cho các nhánh chưa đủ điều kiện để tích hợp vào `next` hoặc `master`. 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. From 5216930c5201b35464f704aa7cffb0e6a3ff9e53 Mon Sep 17 00:00:00 2001 From: Tuan Vu Date: Sat, 4 Jan 2014 02:52:56 +0000 Subject: [PATCH 037/690] update chapter 3 --- vi/03-git-branching/01-chapter3.markdown | 34 ++++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/vi/03-git-branching/01-chapter3.markdown b/vi/03-git-branching/01-chapter3.markdown index 6feadfe84..d8f26deb5 100644 --- a/vi/03-git-branching/01-chapter3.markdown +++ b/vi/03-git-branching/01-chapter3.markdown @@ -355,39 +355,39 @@ Sẽ dễ hình dung hơn khi nghĩ về chúng như là các xi-lô, nơi mà t Insert 18333fig0319.png Hình 3-19. Có lẽ sẽ dễ hiểu hơn khi coi các nhánh là các xi-lô. -Bạn có thể tiếp tục làm theo cách này cho nhiều tầng ổn định khác nhau. Nhiều dự án lớn có nhánh `proposed` hoặc `pu` (proposed updates) được sử dụng cho các nhánh chưa đủ điều kiện để tích hợp vào `next` hoặc `master`. +Bạn có thể tiếp tục làm theo cách này cho nhiều tầng ổn định khác nhau. Nhiều dự án lớn có nhánh `proposed` hoặc `pu` (proposed updates) được sử dụng cho các nhánh chưa đủ điều kiện để tích hợp vào `next` hoặc `master`. Ý tưởng ở đây là, các nhánh ở các tầng khác nhau của sự ổn định; khi chúng đạt tới một mức ổn định hơn nào đó, chúng sẽ được tích hợp vào tầng trên nó. +Tóm lại, có nhiều nhánh tồn lại lâu dài không thật sự cần thiết, nhưng nó thường rất hữu ích, đặc biệt là khi bạn làm việc với các dự án lớn và phức tạp. -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. +### Nhánh Chủ Đề ### -### Topic Branches ### +Nhánh chủ đề (topic branches) thì ngược lại, nó lại khá hữu ích cho các dự án ở bất kỳ cỡ nào. Một nhánh chủ đề là nhánh có vòng đời ngắn mà bạn tạo để phát triển một tính năng nào đó hoặc tương tự. Nó giống như một thứ gì đó mà bạn chưa từng làm với một VCS trước đây bởi vì nhìn chung nó đòi hỏi rất nhiều nỗ lực để tạo mới cũng như tích hợp các nhánh lại với nhau. -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. +Như bạn đã thấy trong phần trước với các nhánh `iss53` và `hotfix` bạn đã tạo ra. Bạn thực hiện một số commit trên đó và xóa chúng đi ngay sau khi tính hợp chúng lại với nhánh chính. Kỹ thuật này cho phép bạn chuyển ngữ cảnh một cách nhanh chóng và toàn diện - vì công việc của bạn tách biệt hoàn toàn ở các xi-lô nơi mà tất cả các thay đổi ở nhánh đó chỉ liên quan đến chủ đề đó, điều này khiến cho việc xem xét lại (review) mã nguồn hoặc tương tự trở nên dễ dàng hơn rất nhiều. Bạn có thể giữ các thay đổi ở đó trong bất kỳ khoảng thời gian nào bạn muốn, có thể tính bằng phút, ngày, hoặc tháng, và sau đó tích hợp lại khi chúng đã sẵn sàng, không quan trọng thứ tự chúng được tạo ra hay làm việc. -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. +Hãy cùng xét một ví dụ về thực hiện một số công việc (trên nhánh `master`), tạo nhánh cho một vấn đề cần giải quyết (`iss91`), làm việc trên đó một chút, tạo một nhánh thứ hai cùng giải quyết vấn đề đó nhưng theo một cách khác (`iss91v2`), quay trở lại nhánh `master` và làm việc trong một khoảng thời gian nhất định, sau đó tạo một nhánh khác từ đó cho một ý tưởng mà bạn không chắc chắn là nó có phải là ý hay hay không (nhánh `dumbidea`). Lúc này lịch sử commit của bạn sẽ giống Hình 3-20. Insert 18333fig0320.png -Figure 3-20. Your commit history with multiple topic branches. +Hình 3-20. Lịch sử commit với nhiều nhánh chủ đề. -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. +Bây giờ, giả sử bạn quyết định lựa chọn cách giải quyết thứ hai (`iss91v2`); và bạn trình bày ý tưởng `dumbidea` cho các đồng nghiệp, điều mà bạn không ngờ tới rằng mọi người lại cho đó là một ý tưởng tuyệt vời. Bạn đã có thể bỏ đi nhánh ban đầu `iss91` (mất commit C5 và C6) và tích hợp hai commit còn lại. Lịch sử của bạn lúc này sẽ giống Hình 3-21. Insert 18333fig0321.png -Figure 3-21. Your history after merging in dumbidea and iss91v2. +Hình 3-21. Lịch sử commit sau khi tích hợp dumbidea và 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. +Ghi nhớ một điều quan trọng là khi bạn làm tất cả những việc này, các nhánh hoàn toàn nằm ở máy nội bộ. Khi bạn phân nhánh và tích hợp, tất cả mọi thứ xảy ra trên kho chứa Git của bạn - không có giao tiếp tới máy chủ nào xảy ra. -## Remote Branches ## +## Nhánh Từ Xa ## -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. +Nhánh từ xa là các tham chiếu tới trạng thái của các nhánh trên kho chứa từ xa/trung tâm của bạn. Chúng là các nhánh nội bộ mà bạn không thể di chuyển; chúng chỉ di chuyển một cách tự động mỗi khi bạn thực hiện bất kỳ giao tiếp nào qua mạng lưới. Nhánh từ xa hoạt động như là các bookmark (dấu) để nhắc nhở bạn các nhánh trên kho chứa trung tâm của bạn ở đâu vào lần cuối cùng bạn kết nối tới. -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`. +Chúng có dạng `(remote)/(branch)`. Ví dụ, nếu bạn muốn xem nhánh `master` trên nhánh từ xa `origin` của bạn như thế nào từ lần giao tiếp cuối cùng, bạn sẽ dùng `origin/master`. Nếu bạn đang giải quyết một vấn đề với đối tác và họ đẩy dữ liệu lên nhánh `iss53`, bạn có thể có riêng nhánh `iss53` trên máy nội bộ; nhưng nhánh trên máy chủ sẽ trỏ tới commit tại `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). +Điều này có thể hơi khó hiểu một chút, vậy hãy cùng xem một ví dụ. Giả sử bạn có một máy chủ Git trên mạng của bạn tại địa chỉ `git.ourcompany.com`. Nếu bạn tạo bản sao từ đây, Git sẽ tự động đặt tên nó là `origin` cho bạn, tải về toàn bộ dữ liệu, tạo một con trỏ tới nhánh `master` và đặt tên nội bộ cho nó là `origin/master`; và bạn không thể di chuyển nó. Git cũng cung cấp cho bạn nhánh `master` riêng, bắt đầu cùng một vị trí với `master` của origin để cho bạn có thể bắt đầu làm việc (xem Hình 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. +Hình 3-22. Một bản sao Git cung cấp cho bạn nhánh master riêng và nhánh origin/master trỏ tới nhánh master của origin. + + 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). From d8d9ccedb182c85766db235da446a29d68337c8c Mon Sep 17 00:00:00 2001 From: Tuan Vu Date: Sun, 5 Jan 2014 04:11:24 +0000 Subject: [PATCH 038/690] [vi] Finished chapter 3 --- vi/03-git-branching/01-chapter3.markdown | 143 +++++++++++------------ 1 file changed, 71 insertions(+), 72 deletions(-) diff --git a/vi/03-git-branching/01-chapter3.markdown b/vi/03-git-branching/01-chapter3.markdown index d8f26deb5..56fb8f8d0 100644 --- a/vi/03-git-branching/01-chapter3.markdown +++ b/vi/03-git-branching/01-chapter3.markdown @@ -387,33 +387,31 @@ Chúng có dạng `(remote)/(branch)`. Ví dụ, nếu bạn muốn xem nhánh ` Insert 18333fig0322.png Hình 3-22. Một bản sao Git cung cấp cho bạn nhánh master riêng và nhánh origin/master trỏ tới nhánh master của origin. - - -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). +Nếu bạn thực hiện một số thay đổi trên nhánh `master` nội bộ, và cùng thời điểm đó, một người nào đó đẩy lên `git.ourcompany.com` và cập nhật nhánh master của nó, thì lịch sử của bạn sẽ di chuyển về phía trước khác đi. Miễn là bạn không kết nối tới máy chủ thì con trỏ `origin/master` sẽ vẫn không đổi (xem Hình 3-23). Insert 18333fig0323.png -Figure 3-23. Working locally and having someone push to your remote server makes each history move forward differently. +Hình 3-23. Làm việc nội bộ và ai đó đẩy lên máy chủ khiến cho lịch sử thay đổi khác biệt nhau. -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). +Để đồng bộ hóa các thay đổi, bạn chạy lệnh `git fetch origin`. Lệnh này sẽ tìm kiếm máy chủ nào là origin (trong trường hợp này là `git.ourcompany.com`), truy xuất toàn bộ dữ liệu mà bạn chưa có từ đó, và cập nhật cơ sở dữ liệu nội bộ của bạn, di chuyển con trỏ `origin/master` tới vị trí mới được cập nhật (xem Hình 3-24). Insert 18333fig0324.png -Figure 3-24. The git fetch command updates your remote references. +Hình 3-24. Lệnh git fetch cập nhật các tham chiếu từ xa. -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). +Để minh họa cho việc có nhiều máy chủ từ xa và các nhánh từ xa của các dự án thuộc các máy chủ đó, giả sử bạn có một máy chủ Git nội bộ khác sử dụng riêng cho các nhóm "thần tốc". Máy chủ này có địa chỉ là `git.team1.ourcompany.com`. Bạn có thể thêm nó như là một tham chiếu từ xa tới dự án bạn đang làm việc bằng cách chạy lệnh `git remote add` như đã giới thiệu ở Chương 2. Đặt tên cho remote đó là `teamone`, đó sẽ là tên rút gọn thay thế cho địa chỉ đầy đủ kia (xem Hình 3-25). Insert 18333fig0325.png -Figure 3-25. Adding another server as a remote. +Hình 3-25. Thêm một máy chủ từ xa khác. -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). +Bây giờ bạn có thể chạy lệnh `git fetch teamone` để truy xất toàn bộ nội dung mà bạn chưa có từ máy chủ `teamone`. Bởi vì máy chủ đó có chứa một tập con dữ liệu từ máy chủ `origin` đang có, Git không truy xuất dữ liệu nào cả mà thiết lập một nhánh từ xa mới là `teamone/master` để trỏ tới commit mà `teamone` đang có như là nhánh `master` (xem Hình 3-26). Insert 18333fig0326.png -Figure 3-26. You get a reference to teamone’s master branch position locally. +Hình 3-26. Bạn sẽ có một tham chiếu tới vị trí nội bộ của nhánh `master` của teamone. -### Pushing ### +### Đẩy Lên ### -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. +Khi bạn muốn chia sẻ một nhánh với mọi người, bạn cẩn phải đẩy nó lên một máy chủ mà bạn có quyền ghi trên đó. Nhánh nội bộ của bạn sẽ không tự động thực hiện quá trình đồng bộ hóa - mà bạn phải tự đẩy lên cách nhánh mà bạn muốn chia sẻ. Theo cách này, bạn có thể có các nhánh riêng tư cho những công việc mà bạn không muốn chia sẻ, và chỉ đẩy lên các nhánh chủ đề mà bạn muốn mọi người cùng tham gia đóng góp. -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)`: +Nếu bạn có một nhánh là `serverfix` mà bạn muốn mọi người cùng cộng tác, bạn có thể đẩy nó lên theo cách mà chúng ta đã làm đối với nhánh đầu tiên. Chạy `git push (remote) (branch)`: $ git push origin serverfix Counting objects: 20, done. @@ -423,9 +421,9 @@ If you have a branch named `serverfix` that you want to work on with others, you 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. +Đây là một cách làm tắt. Git tự động mở rộng nhánh `serverfix` thành `refs/heads/serverfix:refs/heads/serverfix`, có nghĩa là, "Hãy sử dụng nhánh nội bộ serverfix của tôi và đẩy nó lên để cập nhật nhánh serverfix trên máy chủ từ xa." Chúng ta sẽ đi sâu vào phần `refs/heads/` ở Chương 9, nhưng bạn thường có thể bỏ qua nó. Bạn cũng có thể chạy lệnh sau `git push origin serverfix:serverfix`, cách này cũng cho kết quả tương tự - nó có nghĩa là "Hãy sử dụng serverfix của tôi để tạo một serverfix trên máy chủ". Bạn có thể sử dụng định dạng này để đẩy một nhánh nội bộ lên một nhánh từ xa với một tên khác. Nếu bạn không muốn gọi nó là `serverfix` trên máy chủ, bạn có thể chạy lệnh sau `git push origin serverfix:awesomebranch` để đẩy nhánh nội bộ `serverfix` vào nhánh `awesomebranch` trên máy chủ trung tâm. -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`: +Lần tới một trong các đồng nghiệp của bạn truy xuất nó từ trên máy chủ, họ sẽ có một tham chiếu tới phiên bản trên máy chủ của `serverfix` dưới tên `origin/serverfix`: $ git fetch origin remote: Counting objects: 20, done. @@ -435,165 +433,166 @@ The next time one of your collaborators fetches from the server, they will get a 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. +Điều quan trọng cần chú ý ở đây là khi bạn truy xuất dữ liệu từ máy chủ mà có kèm theo nhánh mới, Git sẽ không tự động tạo phiên bản nội bộ của nhánh đó. Nói cách khác, trong trường hợp này, bạn sẽ không có nhánh `serverfix` mới - bạn chỉ có một con trỏ tới `origin/serverfix` mà bạn không thể chỉnh sửa. -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: +Để tích hợp công việc hiện tại vào nhánh bạn đang làm việc, bạn có thể chạy `git merge origin/serverfix`. Nếu bạn muốn nhánh `serverfix` riêng để có thể làm việc trên đó, bạn có thể tách nó ra khỏi nhánh trung tâm bằng cách: $ 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. +Cách này sẽ tạo cho bạn một nhánh nội bộ mà bạn có thể làm việc, bắt đầu cùng một vị trí với `origin/serverfix`. -### Tracking Branches ### +### Theo Dõi Các Nhánh ### -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. +Check out một nhánh nội bộ từ một nhánh trung tâm tự động tạo ra một _tracking branch_. Tracking branches là các nhánh nội bộ có liên quan trực tiếp với một nhánh trung tâm. Nếu bạn đang ở trên một tracking branch và chạy `git push`, Git tự động biết nó sẽ phải đẩy lên nhánh nào, máy chủ nào. Ngoài ra, chạy `git pull` khi đang ở trên một trong những nhánh này sẽ truy xuất toàn bộ các tham chiếu từ xa và sau đó tự động tích hợp chúng với các nhánh từ xa tương ứng. -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: +Khi bạn tạo bản sao của một kho chứa, thông thường Git tự động tạp một nhánh `master` để theo dõi `origin/master`. Đó là lý do tại sao `git push` và `git pull` có thể chạy tốt mà không cần bất kỳ tham số nào. Tuy nhiên, bạn có thể cài đặt các tracking branch khác nếu muốn - các nhánh này không theo dõi nhánh trên `origin` cũng như `master`. Một ví dụ đơn giản giống như bạn vừa thấy: `git checkout -b [branch] [remotename]/[branch]`. Nếu bạn đang sử dụng Git phiên bản 1.6.2 trở lên, bạn có thể sử dụng `--track`: $ 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: +Để cài đặt một nhánh nội bộ sử dụng tên khác với tên mặc định trên nhánh trung tâm, bạn có thể dễ dàng sử dụng phiên bản đầu tiên với một tên nội bộ khác: $ 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. +Bây giờ, nhánh nội bộ sf sẽ tự động "kéo và đẩy" từ origin/serverfix. -### Deleting Remote Branches ### +### Xóa Nhánh Trung Tâm ### -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: +Giả sử bạn và đồng nghiệp đã hoàn thành một chức năng nào đó và đã tích hợp nó vào nhánh `master` trung tâm (hoặc bất kỳ nhánh nào khác sử dụng cho việc lưu trữ các phiên bản ổn định). Bạn có thể xóa một nhánh trung tâm đi sử dụng cú pháp sau `git push [remotename] :[branch]`. Nếu bạn muốn xóa nhánh `serverfix` trên máy chủ, bạn có thể chạy lệnh sau: $ 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]`.” +Vậy là đã xong, nhánh đó đã bị xóa khỏi máy chủ. Có thể bạn muốn đánh dấu trang này lại, vì bạn sẽ cần đến câu lệnh này và có thể bạn sẽ quên cú pháp của nó. Một cách để nhớ lệnh này là xem lại cú pháp chúng ta đã nhắc tới trước đó `git push [remotename] [localbranch]:[remotebranch]`. Nếu bạn bỏ qua phần `[localbranch]`, thì cơ bản bạn đang thực hiện "Không sử dụng gì từ phía nội bộ để tạo nhánh `[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. +Trong Git, có hai cách chính để tích hợp các thay đổi từ nhánh này vào nhánh khác: đó là `merge` và `rebase`. Trong phần này bạn sẽ được tìm hiểu rebase là gì, sử dụng nó như thế nào, tại sao nó được coi là một công cụ khá tuyệt vời, và trong trường hợp nào thì không nên sử dụng nó. -### The Basic Rebase ### +### Cơ Bản về 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. +Nếu bạn xem lại ví dụ trước trong phần Tích Hợp (xem Hình 3-27), bạn có thể thấy rằng bạn đã phân nhánh công việc của bạn và thực hiện commit trên hai nhánh khác nhau. Insert 18333fig0327.png -Figure 3-27. Your initial diverged commit history. +Hình 3-17. Lần phân nhánh đầu tiên. -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. +Cách đơn giản nhất để tích hợp các nhánh, như chúng ta đã đề cập từ trước, đó là lệnh `merge`. Nó thực hiện tích hợp 3-chiều giữa hai snapshot mới nhất của hai nhánh (C3 và C4) và cha chung gần nhất của cả hai (C2), tạo mới một snapshot khác (và commit), như trong Hình 3-28. Insert 18333fig0328.png -Figure 3-28. Merging a branch to integrate the diverged work history. +Hình 3-28. Gộp nhánh lại để hợp nhất công việc bị tách ra trước đây. -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. +Tuy nhiên, còn có một cách khác: bạn có thể sử dụng bản vá của thay đổi được đưa ra ở C3 và áp dụng nó lên trên C4. Trong Git, đây được gọi là _rebasing_. Bằng cách sử dụng lệnh `rebase`, bạn có thể sử dụng tất cả các thay đổi được commit ở một nhánh và "chạy lại" (replay) chúng trên một nhánh khác. -In this example, you’d run the following: +Trong ví dụ này, bạn thực hiện như sau: $ 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. +Nó thực hiện bằng cách đi tới commit cha chung của hai nhánh (nhánh bạn đang làm việc và nhánh bạn đang muốn rebase), tìm sự khác biệt trong mỗi commit của nhánh mà bạn đang làm việc, lưu lại các thay đổi đó vào một tập tin tạm thời, khôi phục lại nhánh hiện tại về cùng một commit với nhánh bạn đang rebase, và cuối cùng áp dụng lần lượt các thay đổi. Hình 3-29 minh họa toàn bộ quá trình này. Insert 18333fig0329.png -Figure 3-29. Rebasing the change introduced in C3 onto C4. +Hình 3-29. Quá trình rebase thay đổi ở C3 vào C4. -At this point, you can go back to the master branch and do a fast-forward merge (see Figure 3-30). +Đến lúc này, bạn có thể quay lại nhánh `master` và thực hiện fast-forward merge (xem Hình 3-30). Insert 18333fig0330.png -Figure 3-30. Fast-forwarding the master branch. +Hình 3-30. Di chuyển nhánh master lên phía trước. + +Bây giờ snapshot mà C3 trỏ tới cũng giống như snapshot được trở tới bởi C5 trong ví dụ sử dụng merge. Không có sự khác biệt nào khi so sánh kết quả của hai phương pháp này, nhưng sử dụng rebase sẽ cho chúng ta lịch sử rõ ràng hơn. Nếu bạn xem xét lịch sử của nhánh mà chúng ta rebase vào, nó giống như một đường thẳng: mọi thứ dường như xảy ra theo trình tự, thậm chí ban đầu nó diễn ra song song. -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. +Bình thường, bạn sử dụng cách này để đảm bảo rằng các commit được áp dụng một cách rõ ràng, rành mạch trên nhánh remote - có lẽ là một dự án mà bạn đang đóng góp chứ không phải duy trì nó. Trong trường hợp này, bạn thực hiện công việc trên một nhánh và sau đó rebase trở lại nhánh `origin/master` khi đã sẵn sàng. Theo cách này thì người duy trì dự án đó không phải thực hiện việc tích hợp - mà chỉ chi chuyển tiến lên phía trước (fast-forwar) hoặc đơn giản là áp dụng chúng vào. -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. +Lưu ý rằng snapshot được trỏ tới bởi commit cuối cùng, cho dù nó là kết quả của việc rebase hay merge, thì nó vẫn giống nhau - chỉ khác nhau về các bước thực hiện mà thôi. Quá trình rebase được thực hiện bằng cách thực hiện lại các thay đổi từ nhánh này qua nhánh khác theo thứ tự chúng đã được thực hiện, trong khi đó merge lại lấy hai điểm kết thúc và gộp chúng lại với nhau. -### More Interesting Rebases ### +### Rebase Nâng Cao ### -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. +Bạn cũng có thể thực hiện rebase trên một đối tượng khác mà không phải là nhánh rebase. Xem ví dụ Hình 3-31. Bạn tạo một nhánh chủ để (`server`) để thêm một số tính năng server-side vào dự án, và thực hiện một số commit. Sau đó bạn tạo một nhánh khác để thực hiện một số thay đổi cho phía client (`client`) và cũng commit vài lần. Cuối cùng, bạn quay trở lại nhánh server và thực hiện thêm một số commit nữa. Insert 18333fig0331.png -Figure 3-31. A history with a topic branch off another topic branch. +Hình 3-31. Nhánh chủ đề được tạo từ một nhánh chủ đề khác. -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`: +Giả sử bạn quyết định tích hợp các thay đổi phía client vào nhánh chính cho bản phát hành sắp tới, nhưng bạn vẫn muốn giữ các thay đổi server-side cho đến khi nó được kiểm tra kỹ lưỡng. Bạn có thể lấy các thay đổi ở client mà không có mặt ở server (C8 và C9) sau đó chạy lại (replay) chúng trên nhánh master bằng cách sử dụng lựa chọn `--onto` cho lệnh `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. +Lệnh này cơ bản nói rằng, "Hãy check out nhánh client, tìm ra các bản vá từ commit chung của nhánh `client` và `server`, sau đó thực thi lại vào nhánh `master`." Nó hơi phức tạp một chút nhưng kết quả như Hình 3-32 thì lại rất tuyệt. Insert 18333fig0332.png -Figure 3-32. Rebasing a topic branch off another topic branch. +Hình 3-32. Quá trình rebase nhánh chủ đề khỏi một nhánh chủ đề khác. -Now you can fast-forward your master branch (see Figure 3-33): +Bây giờ bạn có thể di chuyển con trỏ của nhánh master tiến lên phía trước (xem Hình 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. +Hình 3-33. Di chuyển nhánh master lên phía trước để bao gồm các thay đổi của nhánh client. -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`): +Giả sử rằng bạn quyết định kéo về cả nhánh trên máy chủ. Bạn có thể rebase nhánh trên máy chủ đó vào nhánh master mà không phải checkout trước bằng lệnh `git rebase [basebranch] [topicbranch]` - lệnh này sẽ checkout nhánh chủ để (trong trường hợp này là `server`) cho bạn và áp dụng lại các thay đổi vào nhánh cơ sở (base) `master`: $ git rebase master server -This replays your `server` work on top of your `master` work, as shown in Figure 3-34. +Lệnh này sẽ thực hiện lại các thay đổi trên nhánh `server` chèn vào nhánh `master` như trong Hình 3-34. Insert 18333fig0334.png -Figure 3-34. Rebasing your server branch on top of your master branch. +Hình 3-34. Rebase nhánh server chèn lên nhánh master. -Then, you can fast-forward the base branch (`master`): +Sau đó bạn có thể di chuyển con trỏ nhánh base (`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: +Bạn có thể xóa nhánh `client` và `server` vì tất cả công việc đã được tích hợp vào master và bạn không cần đến chúng nữa, lịch sử quả toàn bộ quá trình vừa rồi giống như Hình 3-35: $ git branch -d client $ git branch -d server Insert 18333fig0335.png -Figure 3-35. Final commit history. +Hình 3-35. Lịch sử commit cuối cùng. -### The Perils of Rebasing ### +### Rủi Ro của Rebase ### -Ahh, but the bliss of rebasing isn’t without its drawbacks, which can be summed up in a single line: +Mặc dù rebase rất hữu ích nhưng nó cũng có không ít những mặt hạn chế, điều này có thể tổng kết bằng câu sau đây: -**Do not rebase commits that you have pushed to a public repository.** +**Không được rebase các commit mà bạn đã đẩy lên một kho chứa công khai.** -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. +Miễn là bạn làm theo hướng dẫn này, sẽ không có chuyện gì xảy ra. Nếu không, mọi người sẽ ghét bạn, và bạn sẽ bị bạn bè và gia đình coi thường. -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. +Khi bạn thực hiện rebase, bạn đang bỏ đi các commit đã tồn tại và tái tạo lại các commit mới tương tự nhưng thực ra khác biệt. Nếu bạn đẩy commit ở một nơi nào đó và mọi người kéo xuống máy của họ, sau đó bạn sửa lại các commit đó bằng lệnh `git rebase` và đẩy lên một lần nữa, đồng nghiệp của bạn sẽ phải tích hợp lại công việc của họ và mọi thứ sẽ rối tung lên khi bạn cố gắng kéo các thay đổi của họ ngược lại máy bạn. -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. +Hãy cùng xem một ví dụ làm sao việc rebase công khai có thể gây sự cố. Giả sử bạn tạo bản sao từ một máy chủ trung tâm và thực hiện một số thay đổi từ đó. Lịch sử commit của bạn sẽ giống như Hình 3-36. Insert 18333fig0336.png -Figure 3-36. Clone a repository, and base some work on it. +Hình 3-36. Tạo bản sao một kho chứa, và base một số thay đổi vào đó. -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. +Bây giờ, một người khác thực hiện một số thay đổi khác có kèm theo một lần tích hợp (merge), và đẩy lên máy chủ trung tâm. Bạn truy xuất chúng và tích hợp nhánh trung tâm mới đó vào của bạn, lúc này lịch sử của bạn sẽ giống như Hình 3-37. Insert 18333fig0337.png -Figure 3-37. Fetch more commits, and merge them into your work. +Hình 3-37. Truy xuất thêm các commit và tích hợp lại. -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. +Tiếp theo, người đã đẩy tích hợp đó quyết định lại và rebase lại những thay đổi của họ; họ thực hiện `git push --force` để ghi đè lịch sử trên máy chủ. Sau đó bạn truy xuất lại dữ liệu từ máy chủ, đưa về các commit mới. Insert 18333fig0338.png -Figure 3-38. Someone pushes rebased commits, abandoning commits you’ve based your work on. +Hình 3-38. Một người nào đó đẩy lên các commit rebase, bỏ đi các commit có chứa thay đổi của bạn. -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). +Lúc này, bạn phải tích hợp lại một lần nữa các thay đổi này, mặc dù trước đó bạn đã làm rồi. Quá trình rebase thay đổi mã băm SHA-1 của các commit này vì thế đối với Git chúng giống như các commit mới, mà thực tế thì bạn đã có C4 trong lịch sử của bạn (xem Hình 3-39). Insert 18333fig0339.png -Figure 3-39. You merge in the same work again into a new merge commit. +Hình 3-39. Bạn tích hợp các thay đổi tương tự lại một lần nữa vào một commit tích hợp mới. -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. +Bạn phải tích hợp thay đổi đó để có thể theo kịp với các lập trình viên khác về sau này. Sau khi thực hiện việc này, lịch sử commit của bạn sẽ bao gồm cả hai commit C4 và C4' có mã SHA-1 khác nhau nhưng lại có cùng chung nội dung thay đổi cũng như thông điệp commit. Nếu bạn chạy lệnh `git log` trong trường hợp này bạn sẽ thấy hai commit cùng chung ngày commit và thông điệp, điều này sẽ gây khó hiểu cho bạn. Hơn nữa, nếu bạn đẩy chúng ngược lên máy chủ, bạn sẽ đưa vào một lần nữa tất cả các commit đã rebase đó và sẽ gây khó hiểu cho nhiều người khác nữa. -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. +Nếu bạn sử dụng rebase như là cách để dọn dẹp các commit trước khi đẩy chúng lên, và nếu như bạn chỉ rebase commit chưa bao giờ được công khai, thì sẽ không có chuyện gì xảy ra. Nếu bạn rebase các commit đã được công khai và mọi người có thể đã tích hợp (base) nó vào công việc của họ thì bạn có thể gặp phải các vấn đề thực sự khó chị. -## Summary ## +## Tổng Kết ## -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. +Chúng ta đã đề cập tới các khái niệm cơ bản về phân nhánh và tích hợp trong Git. Bạn nên nắm vững việc tạo mới, di chuyển giữa các nhánh và tích hợp các nhánh nội bộ lại với nhau. Bạn cũng nên có khả năng chia sẽ các nhánh bằng cách đẩy chúng lên một máy chủ trung tâm, cộng tác với các thành viên khác trên các nhánh dùng chung và rebase chúng trước khi chia sẻ. \ No newline at end of file From 7afe5f0b1b0c38cfd3c9ca2514ebb0934bc7942d Mon Sep 17 00:00:00 2001 From: Tuan Vu Date: Sun, 5 Jan 2014 04:17:55 +0000 Subject: [PATCH 039/690] [vi] Fix typo on Chapter 2 --- vi/02-git-basics/01-chapter2.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vi/02-git-basics/01-chapter2.markdown b/vi/02-git-basics/01-chapter2.markdown index 5904099a7..460b5455a 100644 --- a/vi/02-git-basics/01-chapter2.markdown +++ b/vi/02-git-basics/01-chapter2.markdown @@ -589,7 +589,7 @@ The lines must be formatted as follows Có thể bạn băn khoăn về sự khác nhau giữa _tác giả_ (author) và _người commit_ (committer). _Tác giả_ là người đầu tiên viết bản vá (patch), trong khi đó _người commit_ là người cuối cùng áp dụng miếng vá đó. Như vậy, nếu bạn gửi một bản vá cho một dự án và một trong các thành viên chính của dự án "áp dụng" (chấp nhận) bản vá đó, cả hai sẽ cùng được ghi nhận công trạng (credit) - bạn với vai trò là tác giả và thành viên của dự án trong vai trò người commit. Chúng ta sẽ bàn kỹ hơn một chút về sự khác nhau này trong *Chương 5*. -Lựa chọn `oneline` và `formar` đặc biệt hữu ích khi sử dụng với một tham số khác của `log` là `--graph`. Khi sử dụng, tham số này sẽ thêm một biểu đồ sử dụng dựa trên các ký tự ASCII hiển thị nhánh và lịch sử tích hợp các tập tin của bạn, chúng ta có thể thấy trong dự án Grit như sau: +Lựa chọn `oneline` và `format` đặc biệt hữu ích khi sử dụng với một tham số khác của `log` là `--graph`. Khi sử dụng, tham số này sẽ thêm một biểu đồ sử dụng dựa trên các ký tự ASCII hiển thị nhánh và lịch sử tích hợp các tập tin của bạn, chúng ta có thể thấy trong dự án Grit như sau: $ git log --pretty=format:"%h %s" --graph * 2d3acf9 ignore errors from SIGCHLD on trap From 03b06a90f4c4a3d80f778bc781f8a84fc1909751 Mon Sep 17 00:00:00 2001 From: Tuan Vu Date: Sun, 5 Jan 2014 04:24:40 +0000 Subject: [PATCH 040/690] [vi] made some changes on Chapter 3 --- vi/03-git-branching/01-chapter3.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/vi/03-git-branching/01-chapter3.markdown b/vi/03-git-branching/01-chapter3.markdown index 56fb8f8d0..83d9fd012 100644 --- a/vi/03-git-branching/01-chapter3.markdown +++ b/vi/03-git-branching/01-chapter3.markdown @@ -376,11 +376,11 @@ Hình 3-21. Lịch sử commit sau khi tích hợp dumbidea và iss91v2. Ghi nhớ một điều quan trọng là khi bạn làm tất cả những việc này, các nhánh hoàn toàn nằm ở máy nội bộ. Khi bạn phân nhánh và tích hợp, tất cả mọi thứ xảy ra trên kho chứa Git của bạn - không có giao tiếp tới máy chủ nào xảy ra. -## Nhánh Từ Xa ## +## Nhánh Remote ## -Nhánh từ xa là các tham chiếu tới trạng thái của các nhánh trên kho chứa từ xa/trung tâm của bạn. Chúng là các nhánh nội bộ mà bạn không thể di chuyển; chúng chỉ di chuyển một cách tự động mỗi khi bạn thực hiện bất kỳ giao tiếp nào qua mạng lưới. Nhánh từ xa hoạt động như là các bookmark (dấu) để nhắc nhở bạn các nhánh trên kho chứa trung tâm của bạn ở đâu vào lần cuối cùng bạn kết nối tới. +Nhánh từ xa (remote) là các tham chiếu tới trạng thái của các nhánh trên kho chứa trung tâm của bạn. Chúng là các nhánh nội bộ mà bạn không thể di chuyển; chúng chỉ di chuyển một cách tự động mỗi khi bạn thực hiện bất kỳ giao tiếp nào qua mạng lưới. Nhánh remote hoạt động như là các bookmark (dấu) để nhắc nhở bạn các nhánh trên kho chứa trung tâm của bạn ở đâu vào lần cuối cùng bạn kết nối tới. -Chúng có dạng `(remote)/(branch)`. Ví dụ, nếu bạn muốn xem nhánh `master` trên nhánh từ xa `origin` của bạn như thế nào từ lần giao tiếp cuối cùng, bạn sẽ dùng `origin/master`. Nếu bạn đang giải quyết một vấn đề với đối tác và họ đẩy dữ liệu lên nhánh `iss53`, bạn có thể có riêng nhánh `iss53` trên máy nội bộ; nhưng nhánh trên máy chủ sẽ trỏ tới commit tại `origin/iss53`. +Chúng có dạng `(remote)/(branch)`. Ví dụ, nếu bạn muốn xem nhánh `master` trên nhánh remote `origin` của bạn như thế nào từ lần giao tiếp cuối cùng, bạn sẽ dùng `origin/master`. Nếu bạn đang giải quyết một vấn đề với đối tác và họ đẩy dữ liệu lên nhánh `iss53`, bạn có thể có riêng nhánh `iss53` trên máy nội bộ; nhưng nhánh trên máy chủ sẽ trỏ tới commit tại `origin/iss53`. Điều này có thể hơi khó hiểu một chút, vậy hãy cùng xem một ví dụ. Giả sử bạn có một máy chủ Git trên mạng của bạn tại địa chỉ `git.ourcompany.com`. Nếu bạn tạo bản sao từ đây, Git sẽ tự động đặt tên nó là `origin` cho bạn, tải về toàn bộ dữ liệu, tạo một con trỏ tới nhánh `master` và đặt tên nội bộ cho nó là `origin/master`; và bạn không thể di chuyển nó. Git cũng cung cấp cho bạn nhánh `master` riêng, bắt đầu cùng một vị trí với `master` của origin để cho bạn có thể bắt đầu làm việc (xem Hình 3-22). From c37a85f782048ff57c85d1c83bede3a06661e4ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-No=C3=ABl=20Rouvignac?= Date: Sun, 5 Jan 2014 09:17:44 +0100 Subject: [PATCH 041/690] Typo in 8.2 Git and Other Systems - Migrating to Git "metioned" => "mentioned" --- az/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/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 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/az/08-git-and-other-scms/01-chapter8.markdown b/az/08-git-and-other-scms/01-chapter8.markdown index 9aaf5c4e9..2465ffaa5 100644 --- a/az/08-git-and-other-scms/01-chapter8.markdown +++ b/az/08-git-and-other-scms/01-chapter8.markdown @@ -602,7 +602,7 @@ The last thing you need to do is to return the current mark so it can be passed return mark -NOTE: If you are running on Windows you'll need to make sure that you add one extra step. As metioned before, Windows uses CRLF for new line characters while git fast-import expects only LF. To get around this problem and make git fast-import happy, you need to tell ruby to use LF instead of CRLF: +NOTE: If you are running on Windows you'll need to make sure that you add one extra step. As mentioned before, Windows uses CRLF for new line characters while git fast-import expects only LF. To get around this problem and make git fast-import happy, you need to tell ruby to use LF instead of CRLF: $stdout.binmode diff --git a/de/08-git-and-other-scms/01-chapter8.markdown b/de/08-git-and-other-scms/01-chapter8.markdown index 757762e12..f183fdd11 100644 --- a/de/08-git-and-other-scms/01-chapter8.markdown +++ b/de/08-git-and-other-scms/01-chapter8.markdown @@ -818,7 +818,7 @@ Das letzte, das wir jetzt noch machen müssen, ist, die gegenwärtige Marke zur return mark - + $stdout.binmode diff --git a/en/08-git-and-other-scms/01-chapter8.markdown b/en/08-git-and-other-scms/01-chapter8.markdown index 7fddeda69..4e6671c27 100644 --- a/en/08-git-and-other-scms/01-chapter8.markdown +++ b/en/08-git-and-other-scms/01-chapter8.markdown @@ -601,7 +601,7 @@ The last thing you need to do is to return the current mark so it can be passed return mark -NOTE: If you are running on Windows you’ll need to make sure that you add one extra step. As metioned before, Windows uses CRLF for new line characters while git fast-import expects only LF. To get around this problem and make git fast-import happy, you need to tell ruby to use LF instead of CRLF: +NOTE: If you are running on Windows you’ll need to make sure that you add one extra step. As mentioned before, Windows uses CRLF for new line characters while git fast-import expects only LF. To get around this problem and make git fast-import happy, you need to tell ruby to use LF instead of CRLF: $stdout.binmode diff --git a/es/08-git-and-other-scms/01-chapter8.markdown b/es/08-git-and-other-scms/01-chapter8.markdown index 981a56d40..8df7dc775 100644 --- a/es/08-git-and-other-scms/01-chapter8.markdown +++ b/es/08-git-and-other-scms/01-chapter8.markdown @@ -598,7 +598,7 @@ The last thing you need to do is to return the current mark so it can be passed return mark -NOTE: If you are running on Windows you'll need to make sure that you add one extra step. As metioned before, Windows uses CRLF for new line characters while git fast-import expects only LF. To get around this problem and make git fast-import happy, you need to tell ruby to use LF instead of CRLF: +NOTE: If you are running on Windows you'll need to make sure that you add one extra step. As mentioned before, Windows uses CRLF for new line characters while git fast-import expects only LF. To get around this problem and make git fast-import happy, you need to tell ruby to use LF instead of CRLF: $stdout.binmode 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 9aaf5c4e9..2465ffaa5 100644 --- a/no-nb/08-git-and-other-scms/01-chapter8.markdown +++ b/no-nb/08-git-and-other-scms/01-chapter8.markdown @@ -602,7 +602,7 @@ The last thing you need to do is to return the current mark so it can be passed return mark -NOTE: If you are running on Windows you'll need to make sure that you add one extra step. As metioned before, Windows uses CRLF for new line characters while git fast-import expects only LF. To get around this problem and make git fast-import happy, you need to tell ruby to use LF instead of CRLF: +NOTE: If you are running on Windows you'll need to make sure that you add one extra step. As mentioned before, Windows uses CRLF for new line characters while git fast-import expects only LF. To get around this problem and make git fast-import happy, you need to tell ruby to use LF instead of CRLF: $stdout.binmode diff --git a/pl/08-git-and-other-scms/01-chapter8.markdown b/pl/08-git-and-other-scms/01-chapter8.markdown index 90a3dcfc2..19155bca8 100644 --- a/pl/08-git-and-other-scms/01-chapter8.markdown +++ b/pl/08-git-and-other-scms/01-chapter8.markdown @@ -843,7 +843,7 @@ Używasz ponownie metody `export_data`, którą zdefiniowałeś wcześniej, poni UWAGA: Jeżeli pracujesz na systemie Windows, musisz upewnić się, że dodajesz jeszcze jeden krok. Jak wspomniałem wcześniej, system Windows używa znaków CRLF jak znaczników końca linii, a `git fast-import` oczekuje tylko LF. Aby obejść ten problem i uszczęśliwić `git fast-import`, musisz wskazać ruby, aby używał znaków LF zamiast CRLF: - + $stdout.binmode From b219ebc84b18c1c44b5671e8c2281824728c138f Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 13:37:05 +0100 Subject: [PATCH 042/690] Translated "Submodules" --- it/06-git-tools/01-chapter6.markdown | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index f83a8e306..2b1831bb9 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -258,4 +258,12 @@ In questo è comune usare il parametro `--left-right` con il comando `log`, che > D > C -Con questi strumenti puoi dire facilmente a Git quale o quali commit vuoi ispezionare. \ No newline at end of file +Con questi strumenti puoi dire facilmente a Git quale o quali commit vuoi ispezionare. + +## Moduli ## + +Capita spesso che, mentre stai lavorando a un progetto, debba includerne un altro. Potrebbe essere una libreria sviluppata da terze parti o che tu stai sviluppando separatamente e lo stai usando in vari super-progetti. In questi casi si pone un problema comune: si vuole essere in grado di trattare i due progetti separatamente ma essere tuttavia in grado di utilizzarne uno all'interno dell'altro. + +Vediamo un esempio. Immagina di stare sviluppando un sito web creando dei feed Atom e, invece di scrivere da zero il codice per generare il contenuto Atom, decidi di utilizzare una libreria. Molto probabilmente dovrai includere del codice da una libreria condivisa come un’installazione di CPAN o una gem di Ruby, o copiare il sorgente nel tuo progetto. Il problema dell’includere la libreria è che è difficile personalizzarla e spesso più difficile da distribuire, perché è necessario assicurarsi che ogni client abbia a disposizione quella libreria. Il problema di includere il codice nel tuo progetto è che è difficile incorporare le modifiche eventualmente fatte nel progetto iniziale quando questo venisse aggiornato. + +Git risolve questo problema utilizzando i moduli. I moduli consentono di avere un repository Git come una directory di un altro repository Git, che ti permette di clonare un altro repository nel tuo progetto e mantenere le commit separate. \ No newline at end of file From 5ab0f2e246e641fc20ae8a777d3988a872d9fec0 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 13:54:43 +0100 Subject: [PATCH 043/690] Translating "Starting with Submodules" --- it/06-git-tools/01-chapter6.markdown | 33 +++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 2b1831bb9..b3dcd7f3d 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -266,4 +266,35 @@ Capita spesso che, mentre stai lavorando a un progetto, debba includerne un altr Vediamo un esempio. Immagina di stare sviluppando un sito web creando dei feed Atom e, invece di scrivere da zero il codice per generare il contenuto Atom, decidi di utilizzare una libreria. Molto probabilmente dovrai includere del codice da una libreria condivisa come un’installazione di CPAN o una gem di Ruby, o copiare il sorgente nel tuo progetto. Il problema dell’includere la libreria è che è difficile personalizzarla e spesso più difficile da distribuire, perché è necessario assicurarsi che ogni client abbia a disposizione quella libreria. Il problema di includere il codice nel tuo progetto è che è difficile incorporare le modifiche eventualmente fatte nel progetto iniziale quando questo venisse aggiornato. -Git risolve questo problema utilizzando i moduli. I moduli consentono di avere un repository Git come una directory di un altro repository Git, che ti permette di clonare un altro repository nel tuo progetto e mantenere le commit separate. \ No newline at end of file +Git risolve questo problema utilizzando i moduli. I moduli consentono di avere un repository Git come una directory di un altro repository Git, che ti permette di clonare un altro repository nel tuo progetto e mantenere le commit separate. + +### Lavorare con i moduli ### + +Si supponga di voler aggiungere la libreria Rack (un’interfaccia gateway per server web in Ruby) al progetto, mantenendo le tue modifiche alla libreria e continuando a integrare le modifiche fatte a monte alla libreria. La prima cosa da fare è clonare il repository esterno nella subdirectory: aggiungi i progetti esterni come moduli col comando `git modulo aggiungono`: + + $ git submodule add git://github.com/chneukirchen/rack.git rack + Initialized empty Git repository in /opt/subtest/rack/.git/ + remote: Counting objects: 3181, done. + remote: Compressing objects: 100% (1534/1534), done. + remote: Total 3181 (delta 1951), reused 2623 (delta 1603) + Receiving objects: 100% (3181/3181), 675.42 KiB | 422 KiB/s, done. + Resolving deltas: 100% (1951/1951), done. + +Ora, all'interno del tuo progetto, hai la directory `rack` che contiene il progetto Rack. Puoi andare in questa directory, fare le tue modifiche e aggiungere il tuo repository remoto per fare la push delle tue modifiche e prendere quelle disponibili, così come incorporare le modifiche del repository originale, e molto altro. Se esegui `git status` subito dopo aver aggiunto il modulo, vedrai due cose: + + $ git status + # On branch master + # Changes to be committed: + # (use "git reset HEAD ..." to unstage) + # + # new file: .gitmodules + # new file: rack + # + +Prima di tutto nota il file `.gitmodules`: è un file di configurazione che memorizza la mappatura tra l’URL del progetto e la directory locale dove lo hai scaricato: + + $ cat .gitmodules + [submodule "rack"] + path = rack + url = git://github.com/chneukirchen/rack.git + From fe8d604dc1feefad05798659be5dc8e0084216f0 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 14:05:09 +0100 Subject: [PATCH 044/690] Translating "Starting with Submodules" --- it/06-git-tools/01-chapter6.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index b3dcd7f3d..1503613ed 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -298,3 +298,4 @@ Prima di tutto nota il file `.gitmodules`: è un file di configurazione che memo path = rack url = git://github.com/chneukirchen/rack.git +Se hai più di un modulo, avrei più voci in questo file. È importante notare che anche questo file è versionato con tutti gli altri file, come il tuo `.gitignore` e viene trasferito con tutto il resto del tuo progetto. Questo è il modo in cui gli altri che clonano questo progetto sanno dove trovare i progetti dei moduli. \ No newline at end of file From 55ed35a4f57ebb750a6cf208b9290503336b3885 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 16:25:13 +0100 Subject: [PATCH 045/690] Translating "Starting with Submodules" --- it/06-git-tools/01-chapter6.markdown | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 1503613ed..d2ec49670 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -298,4 +298,10 @@ Prima di tutto nota il file `.gitmodules`: è un file di configurazione che memo path = rack url = git://github.com/chneukirchen/rack.git -Se hai più di un modulo, avrei più voci in questo file. È importante notare che anche questo file è versionato con tutti gli altri file, come il tuo `.gitignore` e viene trasferito con tutto il resto del tuo progetto. Questo è il modo in cui gli altri che clonano questo progetto sanno dove trovare i progetti dei moduli. \ No newline at end of file +Se hai più di un modulo, avrei più voci in questo file. È importante notare che anche questo file è versionato con tutti gli altri file, come il tuo `.gitignore` e viene trasferito con tutto il resto del tuo progetto. Questo è il modo in cui gli altri che clonano questo progetto sanno dove trovare i progetti dei moduli. + +L'altro elenco in stato git uscita `` è la voce rack. Se si esegue `git diff` su questo, si vede qualcosa di interessante: + +Sebbene `rack` sia una directory della tua directory di lavoro, Git lo vede come un modulo e non tiene traccia del suo contenuto quando non sei in quella directory. Git invece lo memorizza come una commit particolare da quel repository. Quando committi delle modifiche in quella directory, il super-project nota che l’HEAD è cambiato e registra la commit esatta dove sei; In questo modo, quando altri clonano questo progetto, possono ricreare esattamente l'ambiente. + +Questo è un punto importante con i moduli: li memorizzi come la ‘commit esatta dove sono. Non puoi memorizzare un modulo su `master` o qualche altro riferimento simbolico. \ No newline at end of file From 72493151d21c9a3b6a0892282abcee07e6b58550 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 16:35:13 +0100 Subject: [PATCH 046/690] Finished translating "Starting with Submodules" Starting with "Cloning a Project with Submodules" --- it/06-git-tools/01-chapter6.markdown | 30 +++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index d2ec49670..5c63b1c13 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -304,4 +304,32 @@ L'altro elenco in stato git uscita `` è la voce rack. Se si esegue `git diff` s Sebbene `rack` sia una directory della tua directory di lavoro, Git lo vede come un modulo e non tiene traccia del suo contenuto quando non sei in quella directory. Git invece lo memorizza come una commit particolare da quel repository. Quando committi delle modifiche in quella directory, il super-project nota che l’HEAD è cambiato e registra la commit esatta dove sei; In questo modo, quando altri clonano questo progetto, possono ricreare esattamente l'ambiente. -Questo è un punto importante con i moduli: li memorizzi come la ‘commit esatta dove sono. Non puoi memorizzare un modulo su `master` o qualche altro riferimento simbolico. \ No newline at end of file +Questo è un punto importante con i moduli: li memorizzi come la ‘commit esatta dove sono. Non puoi memorizzare un modulo su `master` o qualche altro riferimento simbolico. + +Quando committi vedi una cosa simile: + + $ git commit -m 'first commit with submodule rack' + [master 0550271] first commit with submodule rack + 2 files changed, 4 insertions(+), 0 deletions(-) + create mode 100644 .gitmodules + create mode 160000 rack + +Nota il modo 160000 di ogni voce di rack. Questo è un modo speciale di Git che significa che stai memorizzando una commit per una directory piuttosto che una subdirectory o un file. + +Puoi trattare la directory `rack` come un progetto separato e puoi aggiornare occasionalmente il tuo super-project con un puntatore all’ultima commit del sotto-project. Tutti i comandi di Git lavorano indipendentemente nelle due directories: + + $ git log -1 + commit 0550271328a0038865aad6331e620cd7238601bb + Author: Scott Chacon + Date: Thu Apr 9 09:03:56 2009 -0700 + + first commit with submodule rack + $ cd rack/ + $ git log -1 + commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 + Author: Christian Neukirchen + Date: Wed Mar 25 14:49:04 2009 +0100 + + Document version change + +### Clonare un progetto con moduli ### \ No newline at end of file From 38cbd27f0725cf187a22a12d00011436ca2fca28 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 16:45:59 +0100 Subject: [PATCH 047/690] Translating "Cloning a Project with Submodules" --- it/06-git-tools/01-chapter6.markdown | 59 +++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 5c63b1c13..6434554ba 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -332,4 +332,61 @@ Puoi trattare la directory `rack` come un progetto separato e puoi aggiornare oc Document version change -### Clonare un progetto con moduli ### \ No newline at end of file +### Clonare un progetto con moduli ### + +Cloneremo ora un progetto con dei moduli. Quando ne ricevi uno, avrai una directory che contiene i moduli, ma nessun file: + + $ git clone git://github.com/schacon/myproject.git + Initialized empty Git repository in /opt/myproject/.git/ + remote: Counting objects: 6, done. + remote: Compressing objects: 100% (4/4), done. + remote: Total 6 (delta 0), reused 0 (delta 0) + Receiving objects: 100% (6/6), done. + $ cd myproject + $ ls -l + total 8 + -rw-r--r-- 1 schacon admin 3 Apr 9 09:11 README + drwxr-xr-x 2 schacon admin 68 Apr 9 09:11 rack + $ ls rack/ + $ + +La directory `rack` c’è, ma è vuota. Devi eseguire due comandi: `git submodule init` per inizializzare il tuo file di configurazione locale e `git submodule update` per scaricare tutti i dati del progetto e scaricare le commit opportune elencate nel tuo super-progetto: + + $ git submodule init + Submodule 'rack' (git://github.com/chneukirchen/rack.git) registered for path 'rack' + $ git submodule update + Initialized empty Git repository in /opt/myproject/rack/.git/ + remote: Counting objects: 3181, done. + remote: Compressing objects: 100% (1534/1534), done. + remote: Total 3181 (delta 1951), reused 2623 (delta 1603) + Receiving objects: 100% (3181/3181), 675.42 KiB | 173 KiB/s, done. + Resolving deltas: 100% (1951/1951), done. + Submodule path 'rack': checked out '08d709f78b8c5b0fbeb7821e37fa53e69afcf433' + +Ora la tua directory `rack` è nello stesso stato in cui era quando hai committal precedentemente. Se qualche altro sviluppatore facesse delle modifiche a rack e le committasse, quando tu scaricherai quel riferimento e lo integrerai nel tuo repository vedrai qualcosa di strano: + + $ git merge origin/master + Updating 0550271..85a3eee + Fast forward + rack | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + [master*]$ git status + # 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) + # + # modified: rack + # + +Quello di cui hai fatto il merge è fondamentalmente un cambiamento al puntatore del tuo modulo, ma non aggiorna il codice nella directory del modulo e sembra quindi che la tua directory di lavoro sia in uno stato ‘sporco’: + + $ git diff + diff --git a/rack b/rack + index 6c5e70b..08d709f 160000 + --- a/rack + +++ b/rack + @@ -1 +1 @@ + -Subproject commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 + +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 + From a3c075a26ab19529105a9dcbee920ac4991c61a5 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 16:56:22 +0100 Subject: [PATCH 048/690] Translated "Cloning a Project with Submodules" --- it/06-git-tools/01-chapter6.markdown | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 6434554ba..414a65b6c 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -390,3 +390,32 @@ Quello di cui hai fatto il merge è fondamentalmente un cambiamento al puntatore -Subproject commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 +Questo succede perché il tuo puntatore del modulo non è lo stesso della directory del modulo. Per correggerlo devi eseguire di nuovo `git submodule update` again: + + $ git submodule update + remote: Counting objects: 5, done. + remote: Compressing objects: 100% (3/3), done. + remote: Total 3 (delta 1), reused 2 (delta 0) + Unpacking objects: 100% (3/3), done. + From git@github.com:schacon/rack + 08d709f..6c5e70b master -> origin/master + Submodule path 'rack': checked out '6c5e70b984a60b3cecd395edd5b48a7575bf58e0' + +E devi farlo ogni volta che scarichi delle modifiche al modulo nel progetto principale: è strano, ma funziona. + +Un problema comune si verifica quando uno sviluppatore fa delle modifiche in un modulo ma non le trasmette al server pubblico, ma committa il puntatore a questo stato quando fa la pusg del superproject. Quando altri sviluppatori provano ad eseguire `git submodule update`, il sistema del modulo non riesce a trovare la commit a cui fa riferimento perché esiste solo sul sistema del primo sviluppatore. Quando ciò accade, viene visualizzato un errore come questo: + + $ git submodule update + fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 + Unable to checkout '6c5e70b984a60b3cecd395edd5ba7575bf58e0' in submodule path 'rack' + +Devi quindi vedere chi è stato l’ultimo a cambiare il modulo: + + $ git log -1 rack + commit 85a3eee996800fcfa91e2119372dd4172bf76678 + Author: Scott Chacon + Date: Thu Apr 9 09:19:14 2009 -0700 + + added a submodule reference I will never make public. hahahahaha! + +e mandarmi un’email e cazziarlo. \ No newline at end of file From 67ff32d3c6ec1922767c321f7318856cc4689624 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 17:01:50 +0100 Subject: [PATCH 049/690] Translated "Superprojects" --- it/06-git-tools/01-chapter6.markdown | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 414a65b6c..e49ad1a35 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -418,4 +418,10 @@ Devi quindi vedere chi è stato l’ultimo a cambiare il modulo: added a submodule reference I will never make public. hahahahaha! -e mandarmi un’email e cazziarlo. \ No newline at end of file +e mandarmi un’email e cazziarlo. + +### Super-progetto ### + +A volte gli sviluppatori vogliono scaricare una combinazione di subdirectory di un progetto grande, a seconda del team in cui lavorano. Questo è comune se vieni da CVS o Subversion, dove hai definito un modulo o un insieme di subdirectory e vuoi mantenere questo tipo di flusso di lavoro. + +Un buon modo per farlo in Git è quello di rendere ciascuna sottodirectory un repository Git separato e creare quindi un repository Git con il super-progetto che contenga più moduli. Un vantaggio di questo approccio è che puoi definire meglio i rapporti tra i progetti con tag e branch nei super-progetti. \ No newline at end of file From d1a449d427d6fa96d32c7b32759a869e821759f2 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 17:54:26 +0100 Subject: [PATCH 050/690] Translated "Summary" --- it/06-git-tools/01-chapter6.markdown | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index e49ad1a35..3b1fedea9 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -424,4 +424,8 @@ e mandarmi un’email e cazziarlo. A volte gli sviluppatori vogliono scaricare una combinazione di subdirectory di un progetto grande, a seconda del team in cui lavorano. Questo è comune se vieni da CVS o Subversion, dove hai definito un modulo o un insieme di subdirectory e vuoi mantenere questo tipo di flusso di lavoro. -Un buon modo per farlo in Git è quello di rendere ciascuna sottodirectory un repository Git separato e creare quindi un repository Git con il super-progetto che contenga più moduli. Un vantaggio di questo approccio è che puoi definire meglio i rapporti tra i progetti con tag e branch nei super-progetti. \ No newline at end of file +Un buon modo per farlo in Git è quello di rendere ciascuna sottodirectory un repository Git separato e creare quindi un repository Git con il super-progetto che contenga più moduli. Un vantaggio di questo approccio è che puoi definire meglio i rapporti tra i progetti con tag e branch nei super-progetti. + +## Sommario ## + +Hai visto numerosi strumenti avanzati che ti permettono di manipolare le tue commit e la tua area di staging in modo più preciso. Quando incontrassi dei problemi dovresti essere facilmente in grado di capire quale commit li ha generati, quando e chi ne è l’autore. Se desideri usare dei sotto-progetti nel tuo progetto e hai appreso alcuni modi per soddisfare tali esigenze. A questo punto dovresti essere in grado di fare in Git la maggior parte delle cose sulla riga di comando di uso quotidiano, e sentirti a tuo agio facendole. \ No newline at end of file From d12b40c2e3865c49fb9e4804a4d8cda923e013d3 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 19:20:15 +0100 Subject: [PATCH 051/690] Translating "Issues with Submodules" --- it/06-git-tools/01-chapter6.markdown | 31 ++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 3b1fedea9..149fd4bb6 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -426,6 +426,37 @@ A volte gli sviluppatori vogliono scaricare una combinazione di subdirectory di Un buon modo per farlo in Git è quello di rendere ciascuna sottodirectory un repository Git separato e creare quindi un repository Git con il super-progetto che contenga più moduli. Un vantaggio di questo approccio è che puoi definire meglio i rapporti tra i progetti con tag e branch nei super-progetti. +### Issues with Submodules ### + +Usare i moduli può comunque presentare qualche intoppo. Prima di tutto devi fare molta attenzione quando lavori nella directory del modulo. Quando esegui `git submodule update`, viene fatto il checkout della versione specifica del progetto, ma non del branch. Questo viene detto “avere l’HEAD separato: significa che il file HEAD punta direttamente alla commit, e non un riferimento simbolico. Il problema è che generalmente non vuoi lavorare in un ambiente separato perché è facile perdere commit, e non un riferimento simbolico. Il problema è che generalmente non vuoi lavorare in un ambiente separato perché è facile perdere le tue modifiche. Se inizi col comando `submodule update` e poi fai una commit nella directory del modulo senza aver creato prima un branch per lavorarci e quindi esegui una `git submodule update` dal super-progetto senz’aver committato nel frattempo, Git sovrascriverà le tue modifiche senza dirti nulla. Tecnicamente non hai perso il tuo lavoro, ma non avendo nessun branch che vi punti sarà difficile da recuperare. + +Per evitare questo problema ti basta creare un branch quando lavori nella directory del modulo con `git checkout -b work` o qualcosa di equivalente. Quando successivamente aggiorni il modulo il tuo lavoro sarà di nuovo sovrascritto, ma avrai un puntatore per poterlo recuperare. + +Cambiare branch in progetti con dei moduli può essere difficile. Se crei un nuovo branch, vi aggiungi un modulo e torni a un branch che non abbia il modulo, ti ritroverai la directory del modulo non ancora tracciata: + + $ git checkout -b rack + Switched to a new branch "rack" + $ git submodule add git@github.com:schacon/rack.git rack + Initialized empty Git repository in /opt/myproj/rack/.git/ + ... + Receiving objects: 100% (3184/3184), 677.42 KiB | 34 KiB/s, done. + Resolving deltas: 100% (1952/1952), done. + $ git commit -am 'added rack submodule' + [rack cc49a69] added rack submodule + 2 files changed, 4 insertions(+), 0 deletions(-) + create mode 100644 .gitmodules + create mode 160000 rack + $ git checkout master + Switched to branch "master" + $ git status + # On branch master + # Untracked files: + # (use "git add ..." to include in what will be committed) + # + # rack/ + +Devi rimuoverla o spostarla e in entrambi i casi dovrai riclonarla quando torni al branch precedente e puoi quindi perdere le modifiche locali o i branch di cui non hai ancora fatto una push. + ## Sommario ## Hai visto numerosi strumenti avanzati che ti permettono di manipolare le tue commit e la tua area di staging in modo più preciso. Quando incontrassi dei problemi dovresti essere facilmente in grado di capire quale commit li ha generati, quando e chi ne è l’autore. Se desideri usare dei sotto-progetti nel tuo progetto e hai appreso alcuni modi per soddisfare tali esigenze. A questo punto dovresti essere in grado di fare in Git la maggior parte delle cose sulla riga di comando di uso quotidiano, e sentirti a tuo agio facendole. \ No newline at end of file From f0603201f284f2ccd7d3cf26c9e67798a62e903b Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 19:36:06 +0100 Subject: [PATCH 052/690] Translated "Issues with Submodules" --- it/06-git-tools/01-chapter6.markdown | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 149fd4bb6..57c1f2fd7 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -457,6 +457,39 @@ Cambiare branch in progetti con dei moduli può essere difficile. Se crei un nuo Devi rimuoverla o spostarla e in entrambi i casi dovrai riclonarla quando torni al branch precedente e puoi quindi perdere le modifiche locali o i branch di cui non hai ancora fatto una push. +L'ultima avvertimento riguarda il passaggio da subdirectory a moduli. Se stai versionando dei file tuo nel progetto e vuoi spostarli in un modulo, è necessario devi fare attenzione, altrimenti Git si arrabbierà. Supponi di avere i file di rack in una directory del tuo progetto e decidi di trasformarla in un modulo. Se elimini la directory ed esegui il comando `submodule add`, Git ti strillerà: + + $ rm -Rf rack/ + $ git submodule add git@github.com:schacon/rack.git rack + 'rack' already exists in the index + +Devi prima rimuovere la directory `rack` dalla tua area di staging per poter quindi aggiungerla come modulo: + + $ git rm -r rack + $ git submodule add git@github.com:schacon/rack.git rack + Initialized empty Git repository in /opt/testsub/rack/.git/ + remote: Counting objects: 3184, done. + remote: Compressing objects: 100% (1465/1465), done. + remote: Total 3184 (delta 1952), reused 2770 (delta 1675) + Receiving objects: 100% (3184/3184), 677.42 KiB | 88 KiB/s, done. + Resolving deltas: 100% (1952/1952), done. + +Immagina ora di averlo fatto in un branch. Se ora torni a un branch dove quei file sono ancora nell’albero corrente piuttosto che nel modulo vedrai questo errore: + + $ git checkout master + error: Untracked working tree file 'rack/AUTHORS' would be overwritten by merge. + (errore: il file 'rack/AUTHORS' non è versionato e sarà sovrascritto) + +Devi quindi spostare la directory del modulo `rack` prima di poter tornare al branch che non ce l’aveva: + + $ mv rack /tmp/ + $ git checkout master + Switched to branch "master" + $ ls + README rack + +Ora, quando tornerai indietro, troverai la directory `rack` vuota. Ora puoi eseguire `git submodule update` per ripopolarla o rispostare la directory `/tmp/rack` nella directory vuota. + ## Sommario ## Hai visto numerosi strumenti avanzati che ti permettono di manipolare le tue commit e la tua area di staging in modo più preciso. Quando incontrassi dei problemi dovresti essere facilmente in grado di capire quale commit li ha generati, quando e chi ne è l’autore. Se desideri usare dei sotto-progetti nel tuo progetto e hai appreso alcuni modi per soddisfare tali esigenze. A questo punto dovresti essere in grado di fare in Git la maggior parte delle cose sulla riga di comando di uso quotidiano, e sentirti a tuo agio facendole. \ No newline at end of file From 33b648fd1a1c1883a5b02e5856e8e34acf4776ac Mon Sep 17 00:00:00 2001 From: Petr Prikryl Date: Sun, 5 Jan 2014 19:42:17 +0100 Subject: [PATCH 053/690] [cs] Typos and formulation changes in Ch. 1 up to 1.3 included. --- cs/01-introduction/01-chapter1.markdown | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/cs/01-introduction/01-chapter1.markdown b/cs/01-introduction/01-chapter1.markdown index 44fdd2521..b1b60c735 100644 --- a/cs/01-introduction/01-chapter1.markdown +++ b/cs/01-introduction/01-chapter1.markdown @@ -3,7 +3,7 @@ Tato kapitola vám ve stručnosti představí systém Git. Začneme od samého začátku. Nahlédneme do historie nástrojů ke správě verzí, poté se budeme věnovat tomu, jak spustit systém Git ve vašem počítači, a nakonec se podíváme na možnosti úvodního nastavení. V této kapitole se dozvíte, k čemu Git slouží a proč byste ho měli používat. Kromě toho se také naučíte, jak Git nastavit podle svých potřeb. ## Správa verzí ## - +hi Co je to správa verzí a proč by vás měla zajímat? Správa verzí je systém, který zaznamenává změny souboru nebo sady souborů v průběhu času, a uživatel tak může kdykoli obnovit jeho/jejich konkrétní verzi (tzv. verzování). Příklady verzovaných souborů jsou v této knize ilustrovány na zdrojovém kódu softwaru, avšak ve skutečnosti lze verzování provádět téměř se všemi typy souborů v počítači. Pokud jste grafik nebo webdesigner a chcete uchovávat všechny verze obrázku nebo všechna rozložení stránky (což jistě není k zahození), je pro vás systém správy verzí (zkráceně VCS z angl. Version Control System) ideálním nástrojem. VCS umožňuje vrátit jednotlivé soubory nebo celý projekt do předchozího stavu, porovnávat změny provedené v průběhu času, zjistit, kdo naposledy upravil něco, co nyní možná způsobuje problémy, kdo vložil jakou verzi a kdy a mnoho dalšího. Používáte-li verzovací systém, většinou to také znamená, že snadno obnovíte soubory, které jste ztratili nebo v nichž byly provedeny nežádoucí změny. Všechny funkcionality verzovacího systému můžete navíc používat velice jednoduchým způsobem. @@ -37,11 +37,11 @@ V tomto místě přicházejí ke slovu tzv. distribuované systémy správy verz Insert 18333fig0103.png Obrázek 1-3. Diagram distribuované správy verzí -Mnoho z těchto systémů navíc bez větších obtíží pracuje i s několika vzdálenými repozitáři, a vy tak můžete v rámci jednoho projektu spolupracovat na různých úrovních s rozdílnými skupinami lidí. Díky tomu si můžete vytvořit několik typů pracovních postupů, což není v centralizovaných systémech (např. v hierarchických modelech) možné. +Mnoho z těchto systémů navíc bez větších obtíží pracuje i s několika vzdálenými repozitáři, takže můžete v rámci jednoho projektu různým způsobem spolupracovat s různými skupinami lidí najednou. Můžete zavést několik typů pracovních postupů, které nejsou v centralizovaných systémech možné — jako jsou například hierarchické modely. ## Stručná historie systému Git ## -Tak jako mnoho velkých věcí v lidské historii se i systém Git zrodil z kreativní destrukce a vášnivého sporu. Jádro Linuxu je software s otevřeným kódem a širokou škálou využití. V letech 1991 — 2002 bylo jádro Linuxu spravováno formou záplat a archivních souborů. V roce 2002 začal projekt vývoje linuxového jádra využívat komerční systém DVCS s názvem Bit-Keeper. +Tak jako mnoho velkých věcí v lidské historii se i systém Git zrodil z kreativní destrukce a vášnivého sporu. Jádro Linuxu je software celkém velkého rozsahu, s otevřeným kódem. V letech 1991 — 2002 bylo jádro Linuxu spravováno formou záplat a archivních souborů. V roce 2002 začal projekt vývoje linuxového jádra využívat komerční systém DVCS s názvem BitKeeper. V roce 2005 se zhoršily vztahy mezi komunitou, která vyvíjela jádro Linuxu, a komerční společností, která vyvinula BitKeeper, a společnost přestala tento systém poskytovat zdarma. To přimělo komunitu vývojářů Linuxu (a zejména Linuse Torvaldse, tvůrce Linuxu), aby vyvinula vlastní nástroj, založený na poznatcích, které nasbírala při užívání systému BitKeeper. Mezi požadované vlastnosti systému patřily zejména: @@ -55,7 +55,7 @@ Od svého vzniku v roce 2005 se Git vyvinul a vyzrál v snadno použitelný syst ## Základy systému Git ## -Jak bychom tedy mohli Git charakterizovat? Odpověď na tuto otázku je velmi důležitá, protože pokud pochopíte, co je Git a na jakém principu pracuje, budete ho bezpochyby moci používat mnohem efektivněji. Při seznámení se systémem Git se pokuste zapomenout na vše, co už možná víte o jiných systémech VCS, např. Subversion nebo Perforce. Vyhnete se tak nežádoucím vlivům, které by vás mohly při používání systému Git mást. Ačkoli je uživatelské rozhraní velmi podobné, Git ukládá a zpracovává informace poněkud odlišně od ostatních systémů. Pochopení těchto rozdílů vám pomůže předejít nejasnostem, které mohou vzniknout při používání systému Git. +Jak bychom tedy mohli Git charakterizovat? Odpověď na tuto otázku je velmi důležitá, protože pokud pochopíte, co je Git a na jakém principu pracuje, budete ho bezpochyby moci používat mnohem efektivněji. Při seznámení se systémem Git se pokuste zapomenout na vše, co už možná víte o jiných systémech VCS, např. Subversion nebo Perforce. Vyhnete se tak nežádoucím vlivům, které by vás mohly při používání systému Git mást. Ačkoli je uživatelské rozhraní velmi podobné, Git ukládá a zpracovává informace poněkud odlišně od ostatních systémů. Pochopení těchto rozdílů vám pomůže předejít nejasnostem, které mohou při používání systému Git vzniknout. ### Snímky, nikoli rozdíly ### @@ -69,31 +69,31 @@ Git zpracovává data jinak. Chápe je spíše jako sadu snímků (snapshots) vl Insert 18333fig0105.png Obrázek 1-5. Git ukládá data jako snímky projektu proměnlivé v čase. -Toto je důležitý rozdíl mezi systémem Git a téměř všemi ostatními systémy VCS. Git díky tomu znovu zkoumá skoro každý aspekt správy verzí, které ostatní systémy kopírovaly z předchozí generace. Git je tak z obyčejného VCS spíše povýšen na vlastní systém správy souborů s řadou skutečně výkonných nástrojů, jež stojí na jeho vrcholu. Některé přednosti, které tato metoda správy dat nabízí, si podrobně ukážeme na systému větvení v kapitole 3. +Toto je důležitý rozdíl mezi systémem Git a téměř všemi ostatními systémy VCS. Git díky tomu znovu zkoumá skoro každý aspekt správy verzí, které ostatní systémy kopírovaly z předchozí generace. Git se podobá malému systému souborů (spíše než obyčejnému VCS) s řadou skutečně výkonných nástrojů, jež stojí na jeho vrcholu. Některé přednosti, které tato metoda správy dat nabízí, si podrobně ukážeme na systému větvení v kapitole 3. ### Téměř každá operace je lokální ### Většina operací v systému Git vyžaduje ke své činnosti pouze lokální soubory a zdroje a nejsou potřeba informace z jiných počítačů v síti. Pokud jste zvyklí pracovat se systémy CVCS, kde je většina operací poznamenána latencí sítě, patrně vás při práci v systému Git napadne, že mu bohové rychlosti dali do vínku nadpřirozené schopnosti. Protože máte celou historii projektu uloženou přímo na svém lokálním disku, probíhá většina operací takřka okamžitě. -Pokud chcete například procházet historii projektu, Git kvůli tomu nemusí vyhledávat informace na serveru — načte ji jednoduše přímo z vaší lokální databáze. Znamená to, že se historie projektu zobrazí téměř neprodleně. Pokud si chcete prohlédnout změny provedené mezi aktuální verzí souboru a týmž souborem před měsícem, Git vyhledá měsíc starý soubor a provede lokální výpočet rozdílů, aniž by o to musel žádat vzdálený server nebo stahovat starší verzi souboru ze vzdáleného serveru a poté provádět lokální výpočet. +Pokud chcete například procházet historii projektu, Git kvůli tomu nemusí vyhledávat informace na serveru — načte je jednoduše přímo z vaší lokální databáze. Znamená to, že se historie projektu zobrazí téměř hned. Pokud si chcete prohlédnout změny provedené mezi aktuální verzí souboru a týmž souborem před měsícem, Git vyhledá měsíc starý soubor a provede lokální výpočet rozdílů, aniž by o to musel žádat vzdálený server nebo stahovat starší verzi souboru ze vzdáleného serveru a poté provádět lokální výpočet. -To také znamená, že je jen velmi málo operací, které nemůžete provádět offline nebo bez připojení k VPN. Jste-li v letadle nebo ve vlaku a chcete pokračovat v práci, můžete beze všeho zapisovat nové revize. Ty se odešlou ve chvíli, kdy se opět připojíte k síti. Jestliže přijedete domů a zjistíte, že VPN klient nefunguje, stále můžete pracovat. V mnoha jiných systémech je takový postup nemožný nebo přinejmenším obtížný. Například v systému Perforce toho lze bez připojení k serveru dělat jen velmi málo, v systémech Subversion a CVS můžete sice upravovat soubory, ale nemůžete zapisovat změny do databáze, neboť ta je offline. Možná to vypadá jako maličkost, ale divili byste se, jaký je to velký rozdíl. +To také znamená, že je jen velmi málo operací, které nemůžete provádět offline nebo bez připojení k VPN. Jste-li v letadle nebo ve vlaku a chcete pokračovat v práci, můžete beze všeho zapisovat nové revize. Ty odešlete až po opětovném připojení k síti. Jestliže přijedete domů a zjistíte, že VPN klient nefunguje, stále můžete pracovat. V mnoha jiných systémech je takový postup nemožný nebo přinejmenším obtížný. Například v systému Perforce toho lze bez připojení k serveru dělat jen velmi málo, v systémech Subversion a CVS můžete sice upravovat soubory, ale nemůžete zapisovat změny do databáze, neboť ta je offline. Možná to vypadá jako maličkost, ale divili byste se, jak velký je v tom rozdíl. ### Git pracuje důsledně ### -Než je v systému Git cokoli uloženo, je nejprve proveden kontrolní součet, který je potom používán k identifikaci uloženého souboru. Znamená to, že není možné změnit obsah jakéhokoli souboru nebo adresáře, aniž by o tom Git nevěděl. Tato funkce je integrována do systému Git na nejnižších úrovních a je v souladu s jeho filozofií. Nemůže tak dojít ke ztrátě informací při přenosu dat nebo k poškození souboru, aniž by to byl Git schopen zjistit. +Než je v systému Git cokoli uloženo, je nejprve proveden kontrolní součet, který je potom používán k identifikaci uloženého souboru. Znamená to, že není možné změnit obsah jakéhokoli souboru nebo adresáře, aniž by o tom Git nevěděl. Tato funkce je integrována do systému Git na nejnižších úrovních a je nedílnou součástí jeho filozofie. Nemůže tak dojít ke ztrátě informací při přenosu dat nebo k poškození souboru, aniž by to byl Git schopen zjistit. Mechanismus, který Git k tomuto kontrolnímu součtu používá, se nazývá otisk SHA-1 (SHA-1 hash). Jedná se o řetězec o 40 hexadecimálních znacích (0–9; a–f) vypočítaný na základě obsahu souboru nebo adresářové struktury systému Git. Otisk SHA-1 může vypadat například takto: 24b9da6552252987aa493b52f8696cd6d3b00373 -S těmito otisky se budete setkávat ve všech úložištích systému Git, protože je používá opravdu často. Neukládá totiž soubory podle jejich názvu, ale ve své databázi podle otisku (hashe) jeho obsahu. +S těmito otisky se budete setkávat ve všech úložištích systému Git, protože je používá opravdu často. Git nic neukládá podle názvu souboru. Místo toho používá databázi adresovatelnou hodnotou otisku, který odpovídá obsahu souboru. ### Git většinou jen přidává data ### Jednotlivé operace ve většině případů jednoduše přidávají data do Git databáze. Přimět systém, aby udělal něco, co nelze vzít zpět, nebo aby smazal jakákoli data, je velice obtížné. Stejně jako ve všech systémech VCS můžete ztratit nebo nevratně zničit změny, které ještě nebyly zapsány. Jakmile však jednou zapíšete snímek do systému Git, je téměř nemožné ho ztratit, zvlášť pokud pravidelně zálohujete databázi do jiného repozitáře. -Díky tomu vás bude práce se systémem Git bavit. Budete pracovat s vědomím, že můžete experimentovat, a neriskujete přitom nevratné zničení své práce. Podrobnější informace o tom, jak Git ukládá data a jak lze obnovit zdánlivě ztracenou práci, najdete v kapitole 9 „Git pod pokličkou“. +Díky tomu vás bude práce se systémem Git bavit. Budete pracovat s vědomím, že můžete experimentovat, a neriskujete přitom nevratné zničení své práce. Podrobnější informace o tom, jak Git ukládá data a jak lze obnovit zdánlivě ztracenou práci, najdete v kapitole 9. ### Tři stavy ### @@ -104,9 +104,9 @@ Z toho vyplývá, že projekt je v systému Git rozdělen do tří hlavních č Insert 18333fig0106.png Obrázek 1-6. Pracovní adresář, oblast připravených změn a adresář Git -V adresáři Git ukládá systém databázi metadat a objektů k projektu. Je to nejdůležitější část systému Git a zároveň adresář, který se zkopíruje, když klonujete repozitář z jiného počítače. +Adresář Git (repozitář) je místo, kde Git uchovává metadata a databázi objektů vašeho projektu. Je to nejdůležitější část systému Git a zároveň adresář, který se zkopíruje, když klonujete repozitář z jiného počítače. -Pracovní adresář obsahuje lokální kopii jedné verze projektu. Tyto soubory jsou staženy ze zkomprimované databáze v adresáři Git a umístěny na disk, abyste je mohli upravovat. +Pracovní adresář obsahuje lokální kopii jedné verze projektu. Tyto soubory jsou staženy ze zkomprimované databáze v adresáři Git a umístěny na disk, kde je můžete používat nebo upravovat. Oblast připravených změn je jednoduchý soubor, většinou uložený v adresáři Git, který obsahuje informace o tom, co bude obsahovat příští revize. Soubor se někdy označuje také anglickým výrazem „index“, ale oblast připravených změn (staging area) je už dnes termín běžnější. From d42c90ea3dd5059a11aa5dddb510edbc9a7b4a89 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 22:03:32 +0100 Subject: [PATCH 054/690] Translating "Subtree Merging" --- it/06-git-tools/01-chapter6.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 57c1f2fd7..b7ee69f7f 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -490,6 +490,10 @@ Devi quindi spostare la directory del modulo `rack` prima di poter tornare al br Ora, quando tornerai indietro, troverai la directory `rack` vuota. Ora puoi eseguire `git submodule update` per ripopolarla o rispostare la directory `/tmp/rack` nella directory vuota. +## Subtree Merging ## + +Ora che hai visto quali sono le difficoltà del sistema dei moduli vediamo un’alternativa per risolvere lo stesso problema. Quando Git fa dei merge vede prima quello di cui deve fare il merge e poi decide quale sia la strategia migliore da usare. Se stai facendo il merge due branch Git userà la strategia _ricorsiva_ (*recursive* in inglese). Se stai facendo il merge di più di due branch Git userà la strategia del polpo (*octopus* in inglese). Queste strategie sono scelte automaticamente, perché la strategia ricorsiva può gestire situazioni complesse di merge a tre vie (quando ci sono per esempio più antenati), ma può gestire solamente due branch alla volta. La strategia del polpo può gestire branch multipli ma agisce con più cautela per evitare conflitti difficili da risolvere, ed è quindi scelta come strategia predefinita se stai facendo il merge di più di due branch. + ## Sommario ## Hai visto numerosi strumenti avanzati che ti permettono di manipolare le tue commit e la tua area di staging in modo più preciso. Quando incontrassi dei problemi dovresti essere facilmente in grado di capire quale commit li ha generati, quando e chi ne è l’autore. Se desideri usare dei sotto-progetti nel tuo progetto e hai appreso alcuni modi per soddisfare tali esigenze. A questo punto dovresti essere in grado di fare in Git la maggior parte delle cose sulla riga di comando di uso quotidiano, e sentirti a tuo agio facendole. \ No newline at end of file From 1cd71971f139349a74a901bf69225344d85b4156 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 22:11:07 +0100 Subject: [PATCH 055/690] Translating "Subtree Merging" --- it/06-git-tools/01-chapter6.markdown | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index b7ee69f7f..68318e173 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -494,6 +494,39 @@ Ora, quando tornerai indietro, troverai la directory `rack` vuota. Ora puoi eseg Ora che hai visto quali sono le difficoltà del sistema dei moduli vediamo un’alternativa per risolvere lo stesso problema. Quando Git fa dei merge vede prima quello di cui deve fare il merge e poi decide quale sia la strategia migliore da usare. Se stai facendo il merge due branch Git userà la strategia _ricorsiva_ (*recursive* in inglese). Se stai facendo il merge di più di due branch Git userà la strategia del polpo (*octopus* in inglese). Queste strategie sono scelte automaticamente, perché la strategia ricorsiva può gestire situazioni complesse di merge a tre vie (quando ci sono per esempio più antenati), ma può gestire solamente due branch alla volta. La strategia del polpo può gestire branch multipli ma agisce con più cautela per evitare conflitti difficili da risolvere, ed è quindi scelta come strategia predefinita se stai facendo il merge di più di due branch. +Ci sono comunque altre strategie tra cui scegliere. Una di questa è il merge *subtree* e la puoi usare per risolvere i problemi dei subprogetti. Vedremo ora come includere lo stesso rack come abbiamo fatto nella sezione precedente, usando però il merge subtree. + +L’idea del merge subtree è che tu hai due progetti e uno di questi è mappato su una subdirectory dell’altro e viceversa. Quando specifichi il merge subtree Git è abbastanza intelligente da capire che uno è un albero dell’altro e farne il merge nel migliore dei modi: è piuttosto incredibile. + +Aggiungi prima l’applicazione Rack al tuo progetto e aggiungi il progetto Rack come un riferimento remoto al tuo progetto, quindi fanne il checkout in un suo branch: + + $ git remote add rack_remote git@github.com:schacon/rack.git + $ git fetch rack_remote + warning: no common commits + remote: Counting objects: 3184, done. + remote: Compressing objects: 100% (1465/1465), done. + remote: Total 3184 (delta 1952), reused 2770 (delta 1675) + Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done. + Resolving deltas: 100% (1952/1952), done. + From git@github.com:schacon/rack + * [new branch] build -> rack_remote/build + * [new branch] master -> rack_remote/master + * [new branch] rack-0.4 -> rack_remote/rack-0.4 + * [new branch] rack-0.9 -> rack_remote/rack-0.9 + $ git checkout -b rack_branch rack_remote/master + Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master. + Switched to a new branch "rack_branch" + +Ora hai la root del progetto Rack nel tuo branch `rack_branch` e il tuo progetto nel branch `master`. Se scarichi prima uno e poi l’altro vedrai che avranno due progetti sorgenti: + + $ ls + AUTHORS KNOWN-ISSUES Rakefile contrib lib + COPYING README bin example test + $ git checkout master + Switched to branch "master" + $ ls + README + ## Sommario ## Hai visto numerosi strumenti avanzati che ti permettono di manipolare le tue commit e la tua area di staging in modo più preciso. Quando incontrassi dei problemi dovresti essere facilmente in grado di capire quale commit li ha generati, quando e chi ne è l’autore. Se desideri usare dei sotto-progetti nel tuo progetto e hai appreso alcuni modi per soddisfare tali esigenze. A questo punto dovresti essere in grado di fare in Git la maggior parte delle cose sulla riga di comando di uso quotidiano, e sentirti a tuo agio facendole. \ No newline at end of file From 5fe0860443c025802fffbc150764aa5225b32787 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 22:28:20 +0100 Subject: [PATCH 056/690] Translating "Subtree Merging" --- it/06-git-tools/01-chapter6.markdown | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 68318e173..9accc6b42 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -527,6 +527,10 @@ Ora hai la root del progetto Rack nel tuo branch `rack_branch` e il tuo progetto $ ls README +Ora vuoi inviare il progetto Rack nel tuo progetto `master` come una sottodirectory e in Git puoi farlo con `git read-tree`. Conoscerai meglio `read-tree` e i suoi amici nel Capitolo 9, ma per ora sappi che legge la radice di un branch nella tua area di staging della tua directory di lavoro. Sei appena ritornato nel tuo branch `master` e hai scaricato il branch `rack` nella directory `rack` del branch `master` del tuo progetto principale: + + $ git read-tree --prefix=rack/ -u rack_branch + ## Sommario ## Hai visto numerosi strumenti avanzati che ti permettono di manipolare le tue commit e la tua area di staging in modo più preciso. Quando incontrassi dei problemi dovresti essere facilmente in grado di capire quale commit li ha generati, quando e chi ne è l’autore. Se desideri usare dei sotto-progetti nel tuo progetto e hai appreso alcuni modi per soddisfare tali esigenze. A questo punto dovresti essere in grado di fare in Git la maggior parte delle cose sulla riga di comando di uso quotidiano, e sentirti a tuo agio facendole. \ No newline at end of file From 6c06140c4990176214962c2546f81ffe680d4272 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 22:35:45 +0100 Subject: [PATCH 057/690] Translating "Subtree Merging" --- it/06-git-tools/01-chapter6.markdown | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 9accc6b42..c813e76e8 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -531,6 +531,11 @@ Ora vuoi inviare il progetto Rack nel tuo progetto `master` come una sottodirect $ git read-tree --prefix=rack/ -u rack_branch +Quando fai la commit sembra che tutti i file di Rack siano nella directory, come se li avessi copiati da un archivio. La cosa interessante è che può fare facilmente il merge da un branch all’altro, così che puoi importare gli aggiornamenti del progetto Rack passando a quel branch e facendo la pull: + + $ git checkout rack_branch + $ git pull + ## Sommario ## Hai visto numerosi strumenti avanzati che ti permettono di manipolare le tue commit e la tua area di staging in modo più preciso. Quando incontrassi dei problemi dovresti essere facilmente in grado di capire quale commit li ha generati, quando e chi ne è l’autore. Se desideri usare dei sotto-progetti nel tuo progetto e hai appreso alcuni modi per soddisfare tali esigenze. A questo punto dovresti essere in grado di fare in Git la maggior parte delle cose sulla riga di comando di uso quotidiano, e sentirti a tuo agio facendole. \ No newline at end of file From b894f16e45cdd77f84b2abe728003a8d343e21ee Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 5 Jan 2014 22:59:44 +0100 Subject: [PATCH 058/690] Translation completed --- it/06-git-tools/01-chapter6.markdown | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index c813e76e8..d27267b96 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -536,6 +536,16 @@ Quando fai la commit sembra che tutti i file di Rack siano nella directory, come $ git checkout rack_branch $ git pull +Tutte le modifiche del progetto Rack project vengono incorporate e sono pronte per essere committate in locale. Puoi fare anche l’opposto: modificare la directory `rack` e poi fare il merge nel branch `rack_branch` per inviarlo al mantenitore o farne la push al server remoto. + +Per fare un confronto tra quello che hai nella directory `rack` e il codice nel branch `rack_branch` (e vedere se devi fare un merge o meno) non puoi usare il normale comando `diff`: devi usare invece `git diff-tree` con il branch con cui vuoi fare il confronto: + + $ git diff-tree -p rack_branch + +O confrontare quello che c’è nella directory `rack` con quello che c’era nel branch `master` l’ultima volta che l’hai scaricato, col comando + + $ git diff-tree -p rack_remote/master + ## Sommario ## Hai visto numerosi strumenti avanzati che ti permettono di manipolare le tue commit e la tua area di staging in modo più preciso. Quando incontrassi dei problemi dovresti essere facilmente in grado di capire quale commit li ha generati, quando e chi ne è l’autore. Se desideri usare dei sotto-progetti nel tuo progetto e hai appreso alcuni modi per soddisfare tali esigenze. A questo punto dovresti essere in grado di fare in Git la maggior parte delle cose sulla riga di comando di uso quotidiano, e sentirti a tuo agio facendole. \ No newline at end of file From 20c7daef2b0858f029eac29cc4a6665e987a6e9e Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 6 Jan 2014 10:21:21 +0100 Subject: [PATCH 059/690] Fixing Travis highlights because the conversion failed. see https://travis-ci.org/progit/progit/builds/16434388 --- it/06-git-tools/01-chapter6.markdown | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index d27267b96..516bf8580 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -300,11 +300,20 @@ Prima di tutto nota il file `.gitmodules`: è un file di configurazione che memo Se hai più di un modulo, avrei più voci in questo file. È importante notare che anche questo file è versionato con tutti gli altri file, come il tuo `.gitignore` e viene trasferito con tutto il resto del tuo progetto. Questo è il modo in cui gli altri che clonano questo progetto sanno dove trovare i progetti dei moduli. -L'altro elenco in stato git uscita `` è la voce rack. Se si esegue `git diff` su questo, si vede qualcosa di interessante: +L'altro elenco in stato git uscita `git status` è la voce rack. Se si esegue `git diff` su questo, si vede qualcosa di interessante: -Sebbene `rack` sia una directory della tua directory di lavoro, Git lo vede come un modulo e non tiene traccia del suo contenuto quando non sei in quella directory. Git invece lo memorizza come una commit particolare da quel repository. Quando committi delle modifiche in quella directory, il super-project nota che l’HEAD è cambiato e registra la commit esatta dove sei; In questo modo, quando altri clonano questo progetto, possono ricreare esattamente l'ambiente. + $ git diff --cached rack + diff --git a/rack b/rack + new file mode 160000 + index 0000000..08d709f + --- /dev/null + +++ b/rack + @@ -0,0 +1 @@ + +Subproject commit 08d709f78b8c5b0fbeb7821e37fa53e69afcf433 + +Sebbene `rack` sia una subdirectory della tua directory di lavoro, Git lo vede come un modulo e non tiene traccia del suo contenuto quando non sei in quella directory. Git invece lo memorizza come una commit particolare da quel repository. Quando committi delle modifiche in quella directory, il super-project nota che l’HEAD è cambiato e registra la commit esatta dove sei; In questo modo, quando altri clonano questo progetto, possono ricreare esattamente l'ambiente. -Questo è un punto importante con i moduli: li memorizzi come la ‘commit esatta dove sono. Non puoi memorizzare un modulo su `master` o qualche altro riferimento simbolico. +Questo è un punto importante con i moduli: li memorizzi come la commit esatta dove sono. Non puoi memorizzare un modulo su `master` o qualche altro riferimento simbolico. Quando committi vedi una cosa simile: From 1d6bb5406ea684b7f7ae1b9439254bbd07aa6dec Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 6 Jan 2014 10:35:39 +0100 Subject: [PATCH 060/690] Translated line 339 --- it/08-git-and-other-scms/01-chapter8.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/08-git-and-other-scms/01-chapter8.markdown b/it/08-git-and-other-scms/01-chapter8.markdown index 3c2023ca7..7eb703c2c 100644 --- a/it/08-git-and-other-scms/01-chapter8.markdown +++ b/it/08-git-and-other-scms/01-chapter8.markdown @@ -336,7 +336,7 @@ Il secondo, `git svn show-ignore`, mostra nella console le righe che devi includ $ git svn show-ignore > .git/info/exclude -That way, you don’t litter the project with `.gitignore` files. This is a good option if you’re the only Git user on a Subversion team, and your teammates don’t want `.gitignore` files in the project. +In questo modo non riempirai il progetto con i file `.gitignore`. Questa è una buona opzione se sei l'unico utente Git in un gruppo Subversion e i tuoi compagni non vogliono i file `.gitignore` nel progetto. ### Sommario Git-Svn ### From 866091ca72d10714c43bb2de7c12741e421174cb Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 6 Jan 2014 16:52:02 +0100 Subject: [PATCH 061/690] Translating "Applying a Patch with am" --- it/05-distributed-git/01-chapter5.markdown | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 7e2b6a983..e1a94d448 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -603,11 +603,11 @@ Puoi usare `git apply` anche per vedere se una patch può essere applicata in ma Se non viene visualizzato alcun output, allora la patch può essere applicata in maniera pulita. Questo comando termina con un valore diverso da zero se il controllo fallisce, quindi puoi usarlo anche all'interno di uno script. -#### Applying a Patch with am #### +#### Applicare una patch con 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. +Se il contributore è un utente Git ed è stato abbastanza bravo a usare il comando `format-patch` per generare la sua patch, allora il tuo lavoro è più facile perché la patch contiene le informazioni sull'autore e un messaggio di commit per te. Se ti è possibile incoraggia i tuoi collaboratori ad utilizzare `format-patch` invece di `diff` per generare le patch per te. Dovresti dover usare solo `git apply` per le patch precedenti e altre cose del genere. -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: +Per applicare una patch generata con `format-patch` si usa `git am`. Tecnicamente `git am` è fatto per leggere un file mbox, che ha un formato semplice di solo testo per memorizzare uno o più messaggi email in un solo file che assomiglia a questo: From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith @@ -616,14 +616,14 @@ 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. +Questo è l'inizio dell'output del comando 'format-patch' che hai visto nella sezione precedente, ed è anche un formato valido per mbox. Se qualcuno ti ha inviato la patch usando 'git send-email' e l'hai scaricata nel formato mbox, allora puoi puntare al file mbox da 'git am' e lui inizierà ad applicare tutte le patch che troa. Se hai un client di posta elettronica che ti permette di salvare più messaggi in un file mbox allora puoi salvare tutta una serie di patch in un singolo file e usare `git am` per applicarle tutte assieme. -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: +Se però qualcuno ha caricato su un sistema di ticket (o qualcosa di simile) una patch generata con `format-patch`, tu puoi salvare il file localmente e passarlo a `git am` perché lo applichi: $ 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: +Puoi vedere che ha applicato automaticamente e senza errori le modifiche e creato una commit per te. Le informazioni sull'autore e la data della commit vengono prese delle intestazioni dell'email (rispettivamente da `From` e `Date`), mentre il messaggio della commit è preso dal `Subject` e dal corpo dell'email, prima della patch. Se, per esempio questa patch fosse stata applicata dall'esempio dell'mbox appena mostrato, la commit generata apparirebbe così: $ git log --pretty=fuller -1 commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 From 350a63f90a5ceccb69510c0296347089df67f40a Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 6 Jan 2014 22:17:47 +0100 Subject: [PATCH 062/690] Reviewed "Distributed Git" --- it/05-distributed-git/01-chapter5.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index e1a94d448..b45ec93f4 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -1,8 +1,8 @@ # Git distribuito # -Ora che avete un repository Git remoto messo a punto per tutti gli sviluppatore per condividere il proprio codice, e siete familiari con i comandi di base di Git nel lavoro in locale, andremo a vedere come utilizzare alcuni dei workflows distribuiti che Git offre. +Ora che avete un repository Git remoto configurato per tutti gli sviluppatore per condividere il proprio codice, e usate comunemente i comandi di base di Git per il tuo lavoro in locale, vedremo come utilizzare alcuni dei flussi di lavoro offerti da Git. -In questo capitolo, vedrete come lavorare con Git in un ambiente distribuito come contributore ed integratore. Imparerai come contribuire in maniera efficiente ad un progetto e rendere semplice la vita al gestore del progetto, oltre a come mantenere un progetto in maniera corretta con un certo numero di sviluppatori che contribuiscono ad esso. +In questo capitolo, vedremo come lavorare con Git in un ambiente distribuito come contributore e integratore. Imparerai come contribuire in maniera efficiente ad un progetto e rendere la vita al gestore del progetto il più semplice possibile, ma anche come mantenere correttamente un progetto con un certo numero di sviluppatori che vi contribuiscono. ## Workflows distribuiti ## From a4933d7770d4605f9f7ce0e83fcbebd3801709ff Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Tue, 7 Jan 2014 11:00:54 +0100 Subject: [PATCH 063/690] Reviewed "Distributed Git" --- it/05-distributed-git/01-chapter5.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index b45ec93f4..ccb4ab1c8 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -6,7 +6,7 @@ In questo capitolo, vedremo come lavorare con Git in un ambiente distribuito com ## Workflows distribuiti ## -A differenza dei gestori di versione centralizzati (CVCSs), la natura distribuita di Git renderà possibile una maggiore flessibilità nel modo in cui gli sviluppatori collaborano nei progetti. Nel sistemi centralizzati, ogni sviluppatore è un nodo che lavora appoggiandosi più o meno ad un fulcro centrale. Con Git invece, ogni sviluppatore è potenzialmente sia un nodo che il fulcro stesso - infatti ogni sviluppatore può fornire del codice agli altri repository e mantenere un pubblico repository sul quale gli altri basano il proprio lavoro e verso il quale contribuiscono. Questo apre ad una vasta gamma di possibilità di workflow per il vostro progetto e/o il vostro team, quindi coprirò alcuni paradigmi che si avvantaggiano di questa flessibilità. Discuterò dei punti di forza e quelli deboli di ogni possibilità; potete usarne una sola, oppure prendere pezzi da diverse ed adattarle alle vostre necessità. +A differenza dei gestori di versione centralizzati (CVCS), la natura distribuita di Git ti permette di essere più flessibile nel gestire il modo in cui gli sviluppatori collaborano ai progetti. Nel sistemi centralizzati, ogni sviluppatore è un nodo che lavora appoggiandosi ad un nucleo centrale più o meno ugualmente agli altri. Con Git invece, ogni sviluppatore è potenzialmente sia un nodo che un nucleo - infatti ogni sviluppatore può fornire del codice agli altri repository e mantenere un repository pubblico sul quale gli altri basino il proprio lavoro e verso il quale contribuiscano. Questo apre ad una vasta gamma di possibilità di workflow per il vostro progetto e/o il vostro team. Tratterò quindi alcuni paradigmi che sfruttano questa flessibilità. Discuterò i punti di forza e quelli deboli di ogni design. Potrai usarne uno o combinarli per adattarli alle tue necessità. ### Workflow centralizzato ### From 15f2bf1b9902cd166d7c016a65e1f9242e17b4f2 Mon Sep 17 00:00:00 2001 From: "Helmut K. C. Tessarek" Date: Wed, 8 Jan 2014 02:21:17 -0500 Subject: [PATCH 064/690] fixed error in the imap section git send-email does not put the patches into an IMAP folder, but the command git imap-send. I've changed the command, added the output that occurs when using the command and wrote a short sentence to make use of the previous output used in the document. I've also added an example for SMTP config. --- en/05-distributed-git/01-chapter5.markdown | 23 +++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/en/05-distributed-git/01-chapter5.markdown b/en/05-distributed-git/01-chapter5.markdown index 6bf3e1d49..36fccb013 100644 --- a/en/05-distributed-git/01-chapter5.markdown +++ b/en/05-distributed-git/01-chapter5.markdown @@ -532,7 +532,26 @@ First, you need to set up the imap section in your `~/.gitconfig` file. You can 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: +When that is set up, you can use `git imap-send` to place the patch series in the Drafts folder of the specified IMAP server: + + $ cat *.patch |git imap-send + Resolving imap.gmail.com... ok + Connecting to [74.125.142.109]:993... ok + Logging in... + sending 2 messages + 100% (2/2) done + +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. + +You can also send the patches through an SMTP server. As before, you can set each value separately with a series of `git config` commands, or you can add them manually in the sendemail section in your `~/.gitconfig` file: + + [sendemail] + smtpencryption = tls + smtpserver = smtp.gmail.com + smtpuser = user@gmail.com + smtpserverport = 587 + +After this is done, you can use `git send-email` to send your patches: $ git send-email *.patch 0001-added-limit-to-log-function.patch @@ -559,8 +578,6 @@ Then, Git spits out a bunch of log information looking something like this for e 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. From d4919746c7480b74f9e1fa0349dbf01b2293f03c Mon Sep 17 00:00:00 2001 From: rns Date: Thu, 9 Jan 2014 08:53:44 +0200 Subject: [PATCH 065/690] Update 01-chapter4.markdown --- ru/04-git-server/01-chapter4.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ru/04-git-server/01-chapter4.markdown b/ru/04-git-server/01-chapter4.markdown index f578e94e3..825587c58 100644 --- a/ru/04-git-server/01-chapter4.markdown +++ b/ru/04-git-server/01-chapter4.markdown @@ -1,6 +1,6 @@ # Git на сервере # -К этому моменту вы уже должны уметь делать большую часть повседневных задач, для которых вы будете использовать Git. Однако, для совместной работы в Git'е, вам необходим удалённый репозиторий. Несмотря на то, что технически вы можете отправлять и забирать изменения непосредственно из личных репозиториев, делать это не рекомендуется. Вы легко можете испортить то, над чем работают другие, если не будете аккуратны. К тому же, вам бы наверняка хотелось, чтобы остальные имели доступ к репозиторию даже если ваш компьютер выключен, поэтому наличие более надежного репозитория обычно весьма полезно. Поэтому предпочтительный метод взаимодействия с кем-либо — это создание промежуточного репозитория, к которому вы оба будете иметь доступ, и отправка и получение изменений через него. Мы будем называть этот репозиторий "Git-сервер", но обычно размещение Git-репозитория требует очень небольшого количества ресурсов, поэтому вряд ли вам для этого будет нужен весь сервер. +К этому моменту вы уже должны уметь решать большинство повседневных задач, для которых будете использовать Git. Однако, для совместной работы в Git'е, вам необходим удалённый репозиторий. Несмотря на то, что технически вы можете отправлять и забирать изменения непосредственно из личных репозиториев, делать это не рекомендуется. Вы легко можете испортить то, над чем работают другие, если не будете аккуратны. К тому же, вам бы наверняка хотелось, чтобы остальные имели доступ к репозиторию даже если ваш компьютер выключен, поэтому наличие более надежного репозитория обычно весьма полезно. Поэтому предпочтительный метод взаимодействия с кем-либо — это создание промежуточного репозитория, к которому вы оба будете иметь доступ, и отправка и получение изменений через него. Мы будем называть этот репозиторий "Git-сервер", но обычно размещение Git-репозитория требует очень небольшого количества ресурсов, поэтому вряд ли вам для этого будет нужен весь сервер. Запустить Git-сервер просто. Для начала вам следует выбрать протокол, который вы будете использовать для связи с сервером. Первая часть этой главы описывает доступные протоколы и их достоинства и недостатки. Следующие части освещают базовые конфигурации с использованием этих протоколов, а также настройку вашего сервера для работы с ними. Наконец, мы рассмотрим несколько вариантов готового хостинга, если вы не против разместить ваш код на чьём-то сервере и вы не хотите мучиться с настройками и поддержкой вашего собственного сервера. From 7b2abbf43f94853069c5be0d01dda22ef0203eca Mon Sep 17 00:00:00 2001 From: Jean-Noel Avila Date: Fri, 10 Jan 2014 09:59:48 +0100 Subject: [PATCH 066/690] fix typo for git daemon export flag file Spotted by Joseph P. SKUDLAREK. The file name is git-daemon-export-ok instead of git-export-daemon-ok. --- az/04-git-server/01-chapter4.markdown | 2 +- cs/04-git-server/01-chapter4.markdown | 2 +- de/04-git-server/01-chapter4.markdown | 2 +- en/04-git-server/01-chapter4.markdown | 2 +- es/04-git-server/01-chapter4.markdown | 2 +- fr/04-git-server/01-chapter4.markdown | 2 +- it/04-git-server/01-chapter4.markdown | 2 +- ja/04-git-server/01-chapter4.markdown | 2 +- ko/04-git-server/01-chapter4.markdown | 2 +- nl/04-git-server/01-chapter4.markdown | 2 +- no-nb/04-git-server/01-chapter4.markdown | 2 +- pl/04-git-server/01-chapter4.markdown | 2 +- pt-br/04-git-server/01-chapter4.markdown | 2 +- ru/04-git-server/01-chapter4.markdown | 2 +- zh/04-git-server/01-chapter4.markdown | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/az/04-git-server/01-chapter4.markdown b/az/04-git-server/01-chapter4.markdown index 8733fe40a..db9098f73 100644 --- a/az/04-git-server/01-chapter4.markdown +++ b/az/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ The negative aspect of SSH is that you can’t serve anonymous access of your re ### 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. +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-deamon-export-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 #### diff --git a/cs/04-git-server/01-chapter4.markdown b/cs/04-git-server/01-chapter4.markdown index 746caa912..a6100408a 100644 --- a/cs/04-git-server/01-chapter4.markdown +++ b/cs/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ Nevýhodou protokolu SSH je, že neumožňuje anonymní přístup do repozitář ### Protokol Git ### -Dalším protokolem v pořadí je protokol Git. Je to speciální démon, který je distribuován spolu se systémem Git. Naslouchá na vyhrazeném portu (9418) a poskytuje podobnou službu jako protokol SSH, avšak bez jakéhokoli ověřování. Chcete-li, aby byl repozitář obsluhován protokolem Git, musíte vytvořit soubor `git-export-daemon-ok` – démon nebude repozitář obsluhovat, dokud v něm tento soubor nebude. Žádné jiné zabezpečení k dispozici není. Repozitář Git je buď dostupný pro všechny a všichni z něj mohou klonovat, nebo dostupný není. To znamená, že se přes tento protokol nedají odesílat žádné revize. Možnost odesílání lze aktivovat, ale vzhledem k tomu, že protokol neumožňuje ověřování, aktivované odesílání znamená, že kdokoli na internetu, kdo najde URL vašeho projektu, do něj bude moci odesílat data. Tato možnost se však téměř nepoužívá. +Dalším protokolem v pořadí je protokol Git. Je to speciální démon, který je distribuován spolu se systémem Git. Naslouchá na vyhrazeném portu (9418) a poskytuje podobnou službu jako protokol SSH, avšak bez jakéhokoli ověřování. Chcete-li, aby byl repozitář obsluhován protokolem Git, musíte vytvořit soubor `git-deamon-export-ok` – démon nebude repozitář obsluhovat, dokud v něm tento soubor nebude. Žádné jiné zabezpečení k dispozici není. Repozitář Git je buď dostupný pro všechny a všichni z něj mohou klonovat, nebo dostupný není. To znamená, že se přes tento protokol nedají odesílat žádné revize. Možnost odesílání lze aktivovat, ale vzhledem k tomu, že protokol neumožňuje ověřování, aktivované odesílání znamená, že kdokoli na internetu, kdo najde URL vašeho projektu, do něj bude moci odesílat data. Tato možnost se však téměř nepoužívá. #### Výhody #### diff --git a/de/04-git-server/01-chapter4.markdown b/de/04-git-server/01-chapter4.markdown index d78f410e4..2af95673d 100644 --- a/de/04-git-server/01-chapter4.markdown +++ b/de/04-git-server/01-chapter4.markdown @@ -123,7 +123,7 @@ Die negative Seite von SSH ist, dass Du Deine Repositories nicht anonym darüber ### Das Git Protokoll ### - + Als nächstes kommt das Git Protokoll. Das ist ein spezieller Dämon, der zusammen mit Git kommt. Er horcht auf einem bestimmten Port (9418), dieser Service ist vergleichbar mit dem SSH-Protokoll, aber ohne jegliche Authentifizierung. Um ein Repository über das Git Protokoll, musst Du die `gitk-export-daemon-ok` Datei erstellen – der Dämon bietet kein Repository ohne die Datei darin an – außer dieser Datei gibt es keine Sicherheit. Entweder das Git Repository ist für jeden zum Clonen verfügbar oder halt nicht. Das bedeutet, dass dieses Protokoll generell kein push anbietet. Du kannst push-Zugriff aktivieren; aber ohne Authentifizierung, wenn Du den push-Zugriff aktivierst, kann jeder im Internet, der Deine Projekt-URL findet, zu Deinem Projekt pushen. Ausreichend zu sagen, dass das selten ist. diff --git a/en/04-git-server/01-chapter4.markdown b/en/04-git-server/01-chapter4.markdown index ec3f415a4..fda0fb87f 100644 --- a/en/04-git-server/01-chapter4.markdown +++ b/en/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ The negative aspect of SSH is that you can’t serve anonymous access of your re ### 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. +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-deamon-export-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 #### diff --git a/es/04-git-server/01-chapter4.markdown b/es/04-git-server/01-chapter4.markdown index 4cc8612a3..7efaf3963 100755 --- a/es/04-git-server/01-chapter4.markdown +++ b/es/04-git-server/01-chapter4.markdown @@ -68,7 +68,7 @@ El aspecto negativo de SSH es su imposibilidad para dar acceso anónimo al repos ### El Protocolo Git ### -El protocolo Git es un demonio (daemon) especial, que viene incorporado con Git. Escucha por un puerto dedicado (9418), y nos da un servicio similar al del protocolo SSH; pero sin ningún tipo de autentificación. Para que un repositorio pueda exponerse a través del protocolo Git, tienes que crear en él un archivo 'git-export-daemon-ok'; sin este archivo, el demonio no hará disponible el repositorio. Pero, aparte de esto, no hay ninguna otra medida de seguridad. O el repositorio está disponible para que cualquiera lo pueda clonar, o no lo está. Lo cual significa que, normalmente, no se podrá enviar (push) a través de este protocolo. Aunque realmente si que puedes habilitar el envio, si lo haces, dada la total falta de ningún mecanismo de autentificación, cualquiera que encuentre la URL a tu proyecto en Internet, podrá enviar (push) contenidos a él. Ni que decir tiene que esto solo lo necesitarás en contadas ocasiones. +El protocolo Git es un demonio (daemon) especial, que viene incorporado con Git. Escucha por un puerto dedicado (9418), y nos da un servicio similar al del protocolo SSH; pero sin ningún tipo de autentificación. Para que un repositorio pueda exponerse a través del protocolo Git, tienes que crear en él un archivo 'git-deamon-export-ok'; sin este archivo, el demonio no hará disponible el repositorio. Pero, aparte de esto, no hay ninguna otra medida de seguridad. O el repositorio está disponible para que cualquiera lo pueda clonar, o no lo está. Lo cual significa que, normalmente, no se podrá enviar (push) a través de este protocolo. Aunque realmente si que puedes habilitar el envio, si lo haces, dada la total falta de ningún mecanismo de autentificación, cualquiera que encuentre la URL a tu proyecto en Internet, podrá enviar (push) contenidos a él. Ni que decir tiene que esto solo lo necesitarás en contadas ocasiones. ### Ventajas ### diff --git a/fr/04-git-server/01-chapter4.markdown b/fr/04-git-server/01-chapter4.markdown index 0ecbaf05f..723879107 100644 --- a/fr/04-git-server/01-chapter4.markdown +++ b/fr/04-git-server/01-chapter4.markdown @@ -109,7 +109,7 @@ Si vous souhaitez proposer de l'accès anonyme en lecture seule à vos projets, ### Protocole Git ### Vient ensuite le protocole Git. Celui-ci est géré par un *daemon* spécial livré avec Git. Ce *daemon* (démon, processus en arrière plan) écoute sur un port dédié (9418) et propose un service similaire au protocole SSH, mais sans aucune sécurisation. -Pour qu'un dépôt soit publié via le protocole Git, le fichier `git-export-daemon-ok` doit exister mais mise à part cette condition sans laquelle le *daemon* refuse de publier un projet, il n'y a aucune sécurité. +Pour qu'un dépôt soit publié via le protocole Git, le fichier `git-deamon-export-ok` doit exister mais mise à part cette condition sans laquelle le *daemon* refuse de publier un projet, il n'y a aucune sécurité. Soit le dépôt Git est disponible sans restriction en lecture, soit il n'est pas publié. Cela signifie qu'il ne permet pas de pousser des modifications. Vous pouvez activer la capacité à pousser mais étant donné l'absence d'authentification, n'importe qui sur Internet ayant trouvé l'URL du projet peut pousser sur le dépôt. diff --git a/it/04-git-server/01-chapter4.markdown b/it/04-git-server/01-chapter4.markdown index af62c8b8a..40e2c112a 100644 --- a/it/04-git-server/01-chapter4.markdown +++ b/it/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ L'aspetto negativo di SSH è che non puoi dare accesso anonimo al tuo repository ### Il Protocollo Git ### -Poi c'è il protocollo Git. Questo è un demone speciale che è incluso nel pacchetto Git; è in ascolto su una porta dedicata (9418) e fornisce un servizio simile al protocollo SSH, ma assolutamente senza autenticazione. Per permettere ad un repository di essere servito tramite il protocollo Git, devi creare un file `git-export-daemon-ok` — il demone non serve il repository senza l'inserimento di questo file — altrimenti non ci sarebbe sicurezza. O il repository Git è disponibile per chiunque voglia copiarlo o altrimenti niente. Questo significa che generalmente non si invia tramite questo protocollo. Puoi abilitare l'accesso all'invio; ma data la mancanza di autenticazione, se abiliti l'accesso di scrittura, chiunque trovi su internet l'URL al progetto può inviare dati. Basti dire che questo è raro. +Poi c'è il protocollo Git. Questo è un demone speciale che è incluso nel pacchetto Git; è in ascolto su una porta dedicata (9418) e fornisce un servizio simile al protocollo SSH, ma assolutamente senza autenticazione. Per permettere ad un repository di essere servito tramite il protocollo Git, devi creare un file `git-deamon-export-ok` — il demone non serve il repository senza l'inserimento di questo file — altrimenti non ci sarebbe sicurezza. O il repository Git è disponibile per chiunque voglia copiarlo o altrimenti niente. Questo significa che generalmente non si invia tramite questo protocollo. Puoi abilitare l'accesso all'invio; ma data la mancanza di autenticazione, se abiliti l'accesso di scrittura, chiunque trovi su internet l'URL al progetto può inviare dati. Basti dire che questo è raro. #### I Pro #### diff --git a/ja/04-git-server/01-chapter4.markdown b/ja/04-git-server/01-chapter4.markdown index 07ac3a33b..33b34b8f2 100644 --- a/ja/04-git-server/01-chapter4.markdown +++ b/ja/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ SSH の欠点は、リポジトリへの匿名アクセスを許可できない ### Git プロトコル ### -次は Git プロトコルです。これは Git に標準で付属する特別なデーモンです。専用のポート (9418) をリスンし、SSH プロトコルと同様のサービスを提供しますが、認証は行いません。Git プロトコルを提供するリポジトリを準備するには、`git-export-daemon-ok` というファイルを作らなければなりません (このファイルがなければデーモンはサービスを提供しません)。ただ、このままでは一切セキュリティはありません。Git リポジトリをすべての人に開放し、クローンさせることができます。しかし、一般に、このプロトコルでプッシュさせることはありません。プッシュアクセスを認めることは可能です。しかし認証がないということは、その URL を知ってさえいればインターネット上の誰もがプロジェクトにプッシュできるということになります。これはありえない話だと言っても差し支えないでしょう。 +次は Git プロトコルです。これは Git に標準で付属する特別なデーモンです。専用のポート (9418) をリスンし、SSH プロトコルと同様のサービスを提供しますが、認証は行いません。Git プロトコルを提供するリポジトリを準備するには、`git-deamon-export-ok` というファイルを作らなければなりません (このファイルがなければデーモンはサービスを提供しません)。ただ、このままでは一切セキュリティはありません。Git リポジトリをすべての人に開放し、クローンさせることができます。しかし、一般に、このプロトコルでプッシュさせることはありません。プッシュアクセスを認めることは可能です。しかし認証がないということは、その URL を知ってさえいればインターネット上の誰もがプロジェクトにプッシュできるということになります。これはありえない話だと言っても差し支えないでしょう。 #### 利点 #### diff --git a/ko/04-git-server/01-chapter4.markdown b/ko/04-git-server/01-chapter4.markdown index 043d5be67..0083ec87c 100644 --- a/ko/04-git-server/01-chapter4.markdown +++ b/ko/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ SSH의 단점은 익명으로 접근할 수 없다는 것이다. 심지어 읽 ### Git 프로토콜 ### -Git 프로토콜은 Git에 포함된 데몬을 사용하는 방법이다. 포트는 9418이며 SSH 프로토콜과 비슷한 서비스를 제공하지만, 인증 메커니즘이 없다. 저장소에 git-export-daemon-ok 파일을 만들면 Git 프로토콜로 서비스할 수 있지만, 보안은 없다. 이 파일이 없는 저장소는 Git 프로토콜로 서비스할 수 없다. 이 저장소는 누구나 Clone할 수 있거나 아무도 Clone할 수 없거나 둘 중의 하나만 선택할 수 있다. 그래서 이 프로토콜로는 Push 가능하게 설정할 수 없다. 엄밀히 말해서 Push할 수 있도록 설정할 수 있지만, 인증하도록 할 수 없다. 그러니까 당신이 Push할 수 있으면 이 프로젝트의 URL을 아는 사람은 누구나 Push할 수 있다. 그냥 이런 것도 있지만 잘 안 쓴다고 알고 있으면 된다. +Git 프로토콜은 Git에 포함된 데몬을 사용하는 방법이다. 포트는 9418이며 SSH 프로토콜과 비슷한 서비스를 제공하지만, 인증 메커니즘이 없다. 저장소에 git-deamon-export-ok 파일을 만들면 Git 프로토콜로 서비스할 수 있지만, 보안은 없다. 이 파일이 없는 저장소는 Git 프로토콜로 서비스할 수 없다. 이 저장소는 누구나 Clone할 수 있거나 아무도 Clone할 수 없거나 둘 중의 하나만 선택할 수 있다. 그래서 이 프로토콜로는 Push 가능하게 설정할 수 없다. 엄밀히 말해서 Push할 수 있도록 설정할 수 있지만, 인증하도록 할 수 없다. 그러니까 당신이 Push할 수 있으면 이 프로젝트의 URL을 아는 사람은 누구나 Push할 수 있다. 그냥 이런 것도 있지만 잘 안 쓴다고 알고 있으면 된다. #### 장점 #### diff --git a/nl/04-git-server/01-chapter4.markdown b/nl/04-git-server/01-chapter4.markdown index 9d4ff89c3..47c01c78e 100644 --- a/nl/04-git-server/01-chapter4.markdown +++ b/nl/04-git-server/01-chapter4.markdown @@ -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 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. +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-deamon-export-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 #### diff --git a/no-nb/04-git-server/01-chapter4.markdown b/no-nb/04-git-server/01-chapter4.markdown index f3172e638..29d33bd57 100644 --- a/no-nb/04-git-server/01-chapter4.markdown +++ b/no-nb/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ The negative aspect of SSH is that you can’t serve anonymous access of your re ### 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. +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-deamon-export-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 #### diff --git a/pl/04-git-server/01-chapter4.markdown b/pl/04-git-server/01-chapter4.markdown index 0c2d4227c..08e95b3d7 100644 --- a/pl/04-git-server/01-chapter4.markdown +++ b/pl/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ Wadą dostępu po SSH jest to, że nie istnieje dostęp anonimowy do repozytoriu ### Protokół Git ### -Następnie mamy protokół Git. To specjalny rodzaj procesu demona, który dostępny jest w pakiecie z Gitem; słucha na dedykowanym porcie (9418) i udostępnia usługi podobne do protokołu SSH, ale całkowicie bez obsługi uwierzytelnienia. Aby repozytorium mogło być udostępnione po protokole Git konieczne jest utworzenie pliku `git-export-daemon-ok` - bez niego demon nie udostępni repozytorium - ale to jedyne zabezpieczenie. Albo wszyscy mogą klonować dane repozytorium, albo nikt. Generalnie oznacza to że nie można pchać zmian po tym protokole. Można włączyć taką możliwość; ale biorąc pod uwagę brak mechanizmów uwierzytelniania, jeśli włączysz możliwość zapisu, każdy w Internecie, kto odkryje adres Twojego projektu może pchać do niego zmiany. Wystarczy powiedzieć, że nie spotyka się często takich sytuacji. +Następnie mamy protokół Git. To specjalny rodzaj procesu demona, który dostępny jest w pakiecie z Gitem; słucha na dedykowanym porcie (9418) i udostępnia usługi podobne do protokołu SSH, ale całkowicie bez obsługi uwierzytelnienia. Aby repozytorium mogło być udostępnione po protokole Git konieczne jest utworzenie pliku `git-deamon-export-ok` - bez niego demon nie udostępni repozytorium - ale to jedyne zabezpieczenie. Albo wszyscy mogą klonować dane repozytorium, albo nikt. Generalnie oznacza to że nie można pchać zmian po tym protokole. Można włączyć taką możliwość; ale biorąc pod uwagę brak mechanizmów uwierzytelniania, jeśli włączysz możliwość zapisu, każdy w Internecie, kto odkryje adres Twojego projektu może pchać do niego zmiany. Wystarczy powiedzieć, że nie spotyka się często takich sytuacji. #### Zalety #### diff --git a/pt-br/04-git-server/01-chapter4.markdown b/pt-br/04-git-server/01-chapter4.markdown index 505ed24ff..9411c3f06 100644 --- a/pt-br/04-git-server/01-chapter4.markdown +++ b/pt-br/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ O aspecto negativo do SSH é que você não pode permitir acesso anônimo do seu ### O Protocolo Git ### -O próximo é o protocolo Git. Este é um daemon especial que vem no mesmo pacote que o Git; ele escuta em uma porta dedicada (9418) que provê um serviço similar ao do protocolo SSH, mas absolutamente sem nenhuma autenticação. Para que um repositório seja disponibilizado via protocolo Git, você tem que criar o arquivo `git-export-daemon-ok` — o daemon não disponibilizará um repositório sem este arquivo dentro — mas além disso não há nenhuma segurança. Ou o repositório Git está disponível para todos clonarem ou não. Isto significa que geralmente não existe envio (push) sobre este protocolo. Você pode habilitar o acesso a envio; mas dada a falta de autenticação, se você ativar o acesso de envio, qualquer um na internet que encontre a URL do seu projeto poderia enviar (push) para o seu projeto. É suficiente dizer que isto é raro. +O próximo é o protocolo Git. Este é um daemon especial que vem no mesmo pacote que o Git; ele escuta em uma porta dedicada (9418) que provê um serviço similar ao do protocolo SSH, mas absolutamente sem nenhuma autenticação. Para que um repositório seja disponibilizado via protocolo Git, você tem que criar o arquivo `git-deamon-export-ok` — o daemon não disponibilizará um repositório sem este arquivo dentro — mas além disso não há nenhuma segurança. Ou o repositório Git está disponível para todos clonarem ou não. Isto significa que geralmente não existe envio (push) sobre este protocolo. Você pode habilitar o acesso a envio; mas dada a falta de autenticação, se você ativar o acesso de envio, qualquer um na internet que encontre a URL do seu projeto poderia enviar (push) para o seu projeto. É suficiente dizer que isto é raro. #### Os Prós #### diff --git a/ru/04-git-server/01-chapter4.markdown b/ru/04-git-server/01-chapter4.markdown index f578e94e3..cfb52a42e 100644 --- a/ru/04-git-server/01-chapter4.markdown +++ b/ru/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ SSH имеет множество достоинств. Во-первых, вы, ### Git-протокол ### -Следующий протокол — Git-протокол. Вместе с Git'ом поставляется специальный демон, который слушает порт 9418 и предоставляет сервис, схожий с протоколом ssh, но абсолютно без аутентификации. Чтобы использовать Git-протокол для репозитория, вы должны создать файл `git-export-daemon-ok`, иначе демон не будет работать с этим репозиторием, но следует помнить, что в протоколе отсутствуют средства безопасности. Соответственно, любой репозиторий в Git'е может быть либо доступен для клонирования всем, либо не доступен никому. Как следствие, обычно вы не можете отправлять изменения по этому протоколу. Вы можете открыть доступ на запись, но из-за отсутствия авторизации в этом случае кто угодно, зная URL вашего проекта, сможет его изменить. В общем, это редко используемая возможность. +Следующий протокол — Git-протокол. Вместе с Git'ом поставляется специальный демон, который слушает порт 9418 и предоставляет сервис, схожий с протоколом ssh, но абсолютно без аутентификации. Чтобы использовать Git-протокол для репозитория, вы должны создать файл `git-deamon-export-ok`, иначе демон не будет работать с этим репозиторием, но следует помнить, что в протоколе отсутствуют средства безопасности. Соответственно, любой репозиторий в Git'е может быть либо доступен для клонирования всем, либо не доступен никому. Как следствие, обычно вы не можете отправлять изменения по этому протоколу. Вы можете открыть доступ на запись, но из-за отсутствия авторизации в этом случае кто угодно, зная URL вашего проекта, сможет его изменить. В общем, это редко используемая возможность. #### Достоинства #### diff --git a/zh/04-git-server/01-chapter4.markdown b/zh/04-git-server/01-chapter4.markdown index d938f2631..514b1a3f6 100644 --- a/zh/04-git-server/01-chapter4.markdown +++ b/zh/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ SSH 的限制在于你不能通过它实现仓库的匿名访问。即使仅为 ### Git 协议 ### -接下来是 Git 协议。这是一个包含在 Git 软件包中的特殊守护进程; 它会监听一个提供类似于 SSH 服务的特定端口(9418),而无需任何授权。打算支持 Git 协议的仓库,需要先创建 `git-export-daemon-ok` 文件 — 它是协议进程提供仓库服务的必要条件 — 但除此之外该服务没有什么安全措施。要么所有人都能克隆 Git 仓库,要么谁也不能。这也意味着该协议通常不能用来进行推送。你可以允许推送操作;然而由于没有授权机制,一旦允许该操作,网络上任何一个知道项目 URL 的人将都有推送权限。不用说,这是十分罕见的情况。 +接下来是 Git 协议。这是一个包含在 Git 软件包中的特殊守护进程; 它会监听一个提供类似于 SSH 服务的特定端口(9418),而无需任何授权。打算支持 Git 协议的仓库,需要先创建 `git-deamon-export-ok` 文件 — 它是协议进程提供仓库服务的必要条件 — 但除此之外该服务没有什么安全措施。要么所有人都能克隆 Git 仓库,要么谁也不能。这也意味着该协议通常不能用来进行推送。你可以允许推送操作;然而由于没有授权机制,一旦允许该操作,网络上任何一个知道项目 URL 的人将都有推送权限。不用说,这是十分罕见的情况。 #### 优点 #### From 491d4de84074db63233caabcd0e672bec14f7d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20F=C3=BCrbach?= Date: Fri, 10 Jan 2014 12:09:48 +0100 Subject: [PATCH 067/690] Update 01-chapter1.markdown forget an letter --- de/01-introduction/01-chapter1.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/de/01-introduction/01-chapter1.markdown b/de/01-introduction/01-chapter1.markdown index 3c95fcbb9..a86cec03a 100644 --- a/de/01-introduction/01-chapter1.markdown +++ b/de/01-introduction/01-chapter1.markdown @@ -54,7 +54,7 @@ Dieser Aufbau hat viele Vorteile gegenüber Lokalen Versionskontrollsystemen. Zu -Allerdings hat dieser Aufbau auch einige erhebliche Nachteile. Der offensichtlichste Nachteil ist der „Single Point of Failure“, den der zentralisierte Server darstellt. Wenn dieser Server für nur eine Stunde nicht verfügbar ist, dann kann in dieser Stunde niemand in irgendeiner Form mit anderen arbeiten oder versionierte Änderungen an den Dateien speichern, an denen sie momentan arbeiten. Wenn die auf dem zentralen Server verwendete Festplatte beschädigt wird und keine Sicherheitskopien erstellt wurden, dann sind all diese Daten unwiederbringlich verloren – die komplette Historie des Projektes, abgesehen natürlich von dem jeweiligen Zustand, den Mitarbeiter gerade zufällig auf ihrem Rechner haben. Lokale Versionskontrollsysteme haben natürlich dasselbe Problem: wenn man die Historie eines Projektes an einer einzigen, zentralen Stelle verwaltet, riskiert man, sie vollständig zu verlieren, wenn irgendetwas an dieser zentralen Stelle ersthaft schief läuft. +Allerdings hat dieser Aufbau auch einige erhebliche Nachteile. Der offensichtlichste Nachteil ist der „Single Point of Failure“, den der zentralisierte Server darstellt. Wenn dieser Server für nur eine Stunde nicht verfügbar ist, dann kann in dieser Stunde niemand in irgendeiner Form mit anderen arbeiten oder versionierte Änderungen an den Dateien speichern, an denen sie momentan arbeiten. Wenn die auf dem zentralen Server verwendete Festplatte beschädigt wird und keine Sicherheitskopien erstellt wurden, dann sind all diese Daten unwiederbringlich verloren – die komplette Historie des Projektes, abgesehen natürlich von dem jeweiligen Zustand, den Mitarbeiter gerade zufällig auf ihrem Rechner haben. Lokale Versionskontrollsysteme haben natürlich dasselbe Problem: wenn man die Historie eines Projektes an einer einzigen, zentralen Stelle verwaltet, riskiert man, sie vollständig zu verlieren, wenn irgendetwas an dieser zentralen Stelle ernsthaft schief läuft. ### Verteilte Versionskontrollsysteme ### From b0eb6d98b92e68f122770db97176fca76c3a0179 Mon Sep 17 00:00:00 2001 From: Jean-Noel Avila Date: Fri, 10 Jan 2014 12:16:51 +0100 Subject: [PATCH 068/690] Fix typo on git-daemon-export-ok It's daemon, not deamon, dammit! --- az/04-git-server/01-chapter4.markdown | 2 +- cs/04-git-server/01-chapter4.markdown | 2 +- de/04-git-server/01-chapter4.markdown | 4 ++-- en/04-git-server/01-chapter4.markdown | 2 +- es/04-git-server/01-chapter4.markdown | 2 +- fr/04-git-server/01-chapter4.markdown | 2 +- it/04-git-server/01-chapter4.markdown | 2 +- ja/04-git-server/01-chapter4.markdown | 2 +- ko/04-git-server/01-chapter4.markdown | 2 +- nl/04-git-server/01-chapter4.markdown | 2 +- no-nb/04-git-server/01-chapter4.markdown | 2 +- pl/04-git-server/01-chapter4.markdown | 2 +- pt-br/04-git-server/01-chapter4.markdown | 2 +- ru/04-git-server/01-chapter4.markdown | 2 +- zh/04-git-server/01-chapter4.markdown | 2 +- 15 files changed, 16 insertions(+), 16 deletions(-) diff --git a/az/04-git-server/01-chapter4.markdown b/az/04-git-server/01-chapter4.markdown index db9098f73..c631fb0f6 100644 --- a/az/04-git-server/01-chapter4.markdown +++ b/az/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ The negative aspect of SSH is that you can’t serve anonymous access of your re ### 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-deamon-export-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. +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-daemon-export-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 #### diff --git a/cs/04-git-server/01-chapter4.markdown b/cs/04-git-server/01-chapter4.markdown index a6100408a..4f06a9e58 100644 --- a/cs/04-git-server/01-chapter4.markdown +++ b/cs/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ Nevýhodou protokolu SSH je, že neumožňuje anonymní přístup do repozitář ### Protokol Git ### -Dalším protokolem v pořadí je protokol Git. Je to speciální démon, který je distribuován spolu se systémem Git. Naslouchá na vyhrazeném portu (9418) a poskytuje podobnou službu jako protokol SSH, avšak bez jakéhokoli ověřování. Chcete-li, aby byl repozitář obsluhován protokolem Git, musíte vytvořit soubor `git-deamon-export-ok` – démon nebude repozitář obsluhovat, dokud v něm tento soubor nebude. Žádné jiné zabezpečení k dispozici není. Repozitář Git je buď dostupný pro všechny a všichni z něj mohou klonovat, nebo dostupný není. To znamená, že se přes tento protokol nedají odesílat žádné revize. Možnost odesílání lze aktivovat, ale vzhledem k tomu, že protokol neumožňuje ověřování, aktivované odesílání znamená, že kdokoli na internetu, kdo najde URL vašeho projektu, do něj bude moci odesílat data. Tato možnost se však téměř nepoužívá. +Dalším protokolem v pořadí je protokol Git. Je to speciální démon, který je distribuován spolu se systémem Git. Naslouchá na vyhrazeném portu (9418) a poskytuje podobnou službu jako protokol SSH, avšak bez jakéhokoli ověřování. Chcete-li, aby byl repozitář obsluhován protokolem Git, musíte vytvořit soubor `git-daemon-export-ok` – démon nebude repozitář obsluhovat, dokud v něm tento soubor nebude. Žádné jiné zabezpečení k dispozici není. Repozitář Git je buď dostupný pro všechny a všichni z něj mohou klonovat, nebo dostupný není. To znamená, že se přes tento protokol nedají odesílat žádné revize. Možnost odesílání lze aktivovat, ale vzhledem k tomu, že protokol neumožňuje ověřování, aktivované odesílání znamená, že kdokoli na internetu, kdo najde URL vašeho projektu, do něj bude moci odesílat data. Tato možnost se však téměř nepoužívá. #### Výhody #### diff --git a/de/04-git-server/01-chapter4.markdown b/de/04-git-server/01-chapter4.markdown index 2af95673d..cb95e87bb 100644 --- a/de/04-git-server/01-chapter4.markdown +++ b/de/04-git-server/01-chapter4.markdown @@ -123,9 +123,9 @@ Die negative Seite von SSH ist, dass Du Deine Repositories nicht anonym darüber ### Das Git Protokoll ### - + -Als nächstes kommt das Git Protokoll. Das ist ein spezieller Dämon, der zusammen mit Git kommt. Er horcht auf einem bestimmten Port (9418), dieser Service ist vergleichbar mit dem SSH-Protokoll, aber ohne jegliche Authentifizierung. Um ein Repository über das Git Protokoll, musst Du die `gitk-export-daemon-ok` Datei erstellen – der Dämon bietet kein Repository ohne die Datei darin an – außer dieser Datei gibt es keine Sicherheit. Entweder das Git Repository ist für jeden zum Clonen verfügbar oder halt nicht. Das bedeutet, dass dieses Protokoll generell kein push anbietet. Du kannst push-Zugriff aktivieren; aber ohne Authentifizierung, wenn Du den push-Zugriff aktivierst, kann jeder im Internet, der Deine Projekt-URL findet, zu Deinem Projekt pushen. Ausreichend zu sagen, dass das selten ist. +Als nächstes kommt das Git Protokoll. Das ist ein spezieller Dämon, der zusammen mit Git kommt. Er horcht auf einem bestimmten Port (9418), dieser Service ist vergleichbar mit dem SSH-Protokoll, aber ohne jegliche Authentifizierung. Um ein Repository über das Git Protokoll, musst Du die `git-daemon-export-ok` Datei erstellen – der Dämon bietet kein Repository ohne die Datei darin an – außer dieser Datei gibt es keine Sicherheit. Entweder das Git Repository ist für jeden zum Clonen verfügbar oder halt nicht. Das bedeutet, dass dieses Protokoll generell kein push anbietet. Du kannst push-Zugriff aktivieren; aber ohne Authentifizierung, wenn Du den push-Zugriff aktivierst, kann jeder im Internet, der Deine Projekt-URL findet, zu Deinem Projekt pushen. Ausreichend zu sagen, dass das selten ist. #### Die Vorteile #### diff --git a/en/04-git-server/01-chapter4.markdown b/en/04-git-server/01-chapter4.markdown index fda0fb87f..c0e35ec3f 100644 --- a/en/04-git-server/01-chapter4.markdown +++ b/en/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ The negative aspect of SSH is that you can’t serve anonymous access of your re ### 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-deamon-export-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. +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-daemon-export-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 #### diff --git a/es/04-git-server/01-chapter4.markdown b/es/04-git-server/01-chapter4.markdown index 7efaf3963..ef8af9cf8 100755 --- a/es/04-git-server/01-chapter4.markdown +++ b/es/04-git-server/01-chapter4.markdown @@ -68,7 +68,7 @@ El aspecto negativo de SSH es su imposibilidad para dar acceso anónimo al repos ### El Protocolo Git ### -El protocolo Git es un demonio (daemon) especial, que viene incorporado con Git. Escucha por un puerto dedicado (9418), y nos da un servicio similar al del protocolo SSH; pero sin ningún tipo de autentificación. Para que un repositorio pueda exponerse a través del protocolo Git, tienes que crear en él un archivo 'git-deamon-export-ok'; sin este archivo, el demonio no hará disponible el repositorio. Pero, aparte de esto, no hay ninguna otra medida de seguridad. O el repositorio está disponible para que cualquiera lo pueda clonar, o no lo está. Lo cual significa que, normalmente, no se podrá enviar (push) a través de este protocolo. Aunque realmente si que puedes habilitar el envio, si lo haces, dada la total falta de ningún mecanismo de autentificación, cualquiera que encuentre la URL a tu proyecto en Internet, podrá enviar (push) contenidos a él. Ni que decir tiene que esto solo lo necesitarás en contadas ocasiones. +El protocolo Git es un demonio (daemon) especial, que viene incorporado con Git. Escucha por un puerto dedicado (9418), y nos da un servicio similar al del protocolo SSH; pero sin ningún tipo de autentificación. Para que un repositorio pueda exponerse a través del protocolo Git, tienes que crear en él un archivo 'git-daemon-export-ok'; sin este archivo, el demonio no hará disponible el repositorio. Pero, aparte de esto, no hay ninguna otra medida de seguridad. O el repositorio está disponible para que cualquiera lo pueda clonar, o no lo está. Lo cual significa que, normalmente, no se podrá enviar (push) a través de este protocolo. Aunque realmente si que puedes habilitar el envio, si lo haces, dada la total falta de ningún mecanismo de autentificación, cualquiera que encuentre la URL a tu proyecto en Internet, podrá enviar (push) contenidos a él. Ni que decir tiene que esto solo lo necesitarás en contadas ocasiones. ### Ventajas ### diff --git a/fr/04-git-server/01-chapter4.markdown b/fr/04-git-server/01-chapter4.markdown index 723879107..3633206d2 100644 --- a/fr/04-git-server/01-chapter4.markdown +++ b/fr/04-git-server/01-chapter4.markdown @@ -109,7 +109,7 @@ Si vous souhaitez proposer de l'accès anonyme en lecture seule à vos projets, ### Protocole Git ### Vient ensuite le protocole Git. Celui-ci est géré par un *daemon* spécial livré avec Git. Ce *daemon* (démon, processus en arrière plan) écoute sur un port dédié (9418) et propose un service similaire au protocole SSH, mais sans aucune sécurisation. -Pour qu'un dépôt soit publié via le protocole Git, le fichier `git-deamon-export-ok` doit exister mais mise à part cette condition sans laquelle le *daemon* refuse de publier un projet, il n'y a aucune sécurité. +Pour qu'un dépôt soit publié via le protocole Git, le fichier `git-daemon-export-ok` doit exister mais mise à part cette condition sans laquelle le *daemon* refuse de publier un projet, il n'y a aucune sécurité. Soit le dépôt Git est disponible sans restriction en lecture, soit il n'est pas publié. Cela signifie qu'il ne permet pas de pousser des modifications. Vous pouvez activer la capacité à pousser mais étant donné l'absence d'authentification, n'importe qui sur Internet ayant trouvé l'URL du projet peut pousser sur le dépôt. diff --git a/it/04-git-server/01-chapter4.markdown b/it/04-git-server/01-chapter4.markdown index 40e2c112a..ddadb66bf 100644 --- a/it/04-git-server/01-chapter4.markdown +++ b/it/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ L'aspetto negativo di SSH è che non puoi dare accesso anonimo al tuo repository ### Il Protocollo Git ### -Poi c'è il protocollo Git. Questo è un demone speciale che è incluso nel pacchetto Git; è in ascolto su una porta dedicata (9418) e fornisce un servizio simile al protocollo SSH, ma assolutamente senza autenticazione. Per permettere ad un repository di essere servito tramite il protocollo Git, devi creare un file `git-deamon-export-ok` — il demone non serve il repository senza l'inserimento di questo file — altrimenti non ci sarebbe sicurezza. O il repository Git è disponibile per chiunque voglia copiarlo o altrimenti niente. Questo significa che generalmente non si invia tramite questo protocollo. Puoi abilitare l'accesso all'invio; ma data la mancanza di autenticazione, se abiliti l'accesso di scrittura, chiunque trovi su internet l'URL al progetto può inviare dati. Basti dire che questo è raro. +Poi c'è il protocollo Git. Questo è un demone speciale che è incluso nel pacchetto Git; è in ascolto su una porta dedicata (9418) e fornisce un servizio simile al protocollo SSH, ma assolutamente senza autenticazione. Per permettere ad un repository di essere servito tramite il protocollo Git, devi creare un file `git-daemon-export-ok` — il demone non serve il repository senza l'inserimento di questo file — altrimenti non ci sarebbe sicurezza. O il repository Git è disponibile per chiunque voglia copiarlo o altrimenti niente. Questo significa che generalmente non si invia tramite questo protocollo. Puoi abilitare l'accesso all'invio; ma data la mancanza di autenticazione, se abiliti l'accesso di scrittura, chiunque trovi su internet l'URL al progetto può inviare dati. Basti dire che questo è raro. #### I Pro #### diff --git a/ja/04-git-server/01-chapter4.markdown b/ja/04-git-server/01-chapter4.markdown index 33b34b8f2..43155723e 100644 --- a/ja/04-git-server/01-chapter4.markdown +++ b/ja/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ SSH の欠点は、リポジトリへの匿名アクセスを許可できない ### Git プロトコル ### -次は Git プロトコルです。これは Git に標準で付属する特別なデーモンです。専用のポート (9418) をリスンし、SSH プロトコルと同様のサービスを提供しますが、認証は行いません。Git プロトコルを提供するリポジトリを準備するには、`git-deamon-export-ok` というファイルを作らなければなりません (このファイルがなければデーモンはサービスを提供しません)。ただ、このままでは一切セキュリティはありません。Git リポジトリをすべての人に開放し、クローンさせることができます。しかし、一般に、このプロトコルでプッシュさせることはありません。プッシュアクセスを認めることは可能です。しかし認証がないということは、その URL を知ってさえいればインターネット上の誰もがプロジェクトにプッシュできるということになります。これはありえない話だと言っても差し支えないでしょう。 +次は Git プロトコルです。これは Git に標準で付属する特別なデーモンです。専用のポート (9418) をリスンし、SSH プロトコルと同様のサービスを提供しますが、認証は行いません。Git プロトコルを提供するリポジトリを準備するには、`git-daemon-export-ok` というファイルを作らなければなりません (このファイルがなければデーモンはサービスを提供しません)。ただ、このままでは一切セキュリティはありません。Git リポジトリをすべての人に開放し、クローンさせることができます。しかし、一般に、このプロトコルでプッシュさせることはありません。プッシュアクセスを認めることは可能です。しかし認証がないということは、その URL を知ってさえいればインターネット上の誰もがプロジェクトにプッシュできるということになります。これはありえない話だと言っても差し支えないでしょう。 #### 利点 #### diff --git a/ko/04-git-server/01-chapter4.markdown b/ko/04-git-server/01-chapter4.markdown index 0083ec87c..8ad6b1c68 100644 --- a/ko/04-git-server/01-chapter4.markdown +++ b/ko/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ SSH의 단점은 익명으로 접근할 수 없다는 것이다. 심지어 읽 ### Git 프로토콜 ### -Git 프로토콜은 Git에 포함된 데몬을 사용하는 방법이다. 포트는 9418이며 SSH 프로토콜과 비슷한 서비스를 제공하지만, 인증 메커니즘이 없다. 저장소에 git-deamon-export-ok 파일을 만들면 Git 프로토콜로 서비스할 수 있지만, 보안은 없다. 이 파일이 없는 저장소는 Git 프로토콜로 서비스할 수 없다. 이 저장소는 누구나 Clone할 수 있거나 아무도 Clone할 수 없거나 둘 중의 하나만 선택할 수 있다. 그래서 이 프로토콜로는 Push 가능하게 설정할 수 없다. 엄밀히 말해서 Push할 수 있도록 설정할 수 있지만, 인증하도록 할 수 없다. 그러니까 당신이 Push할 수 있으면 이 프로젝트의 URL을 아는 사람은 누구나 Push할 수 있다. 그냥 이런 것도 있지만 잘 안 쓴다고 알고 있으면 된다. +Git 프로토콜은 Git에 포함된 데몬을 사용하는 방법이다. 포트는 9418이며 SSH 프로토콜과 비슷한 서비스를 제공하지만, 인증 메커니즘이 없다. 저장소에 git-daemon-export-ok 파일을 만들면 Git 프로토콜로 서비스할 수 있지만, 보안은 없다. 이 파일이 없는 저장소는 Git 프로토콜로 서비스할 수 없다. 이 저장소는 누구나 Clone할 수 있거나 아무도 Clone할 수 없거나 둘 중의 하나만 선택할 수 있다. 그래서 이 프로토콜로는 Push 가능하게 설정할 수 없다. 엄밀히 말해서 Push할 수 있도록 설정할 수 있지만, 인증하도록 할 수 없다. 그러니까 당신이 Push할 수 있으면 이 프로젝트의 URL을 아는 사람은 누구나 Push할 수 있다. 그냥 이런 것도 있지만 잘 안 쓴다고 알고 있으면 된다. #### 장점 #### diff --git a/nl/04-git-server/01-chapter4.markdown b/nl/04-git-server/01-chapter4.markdown index 47c01c78e..153825c95 100644 --- a/nl/04-git-server/01-chapter4.markdown +++ b/nl/04-git-server/01-chapter4.markdown @@ -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-deamon-export-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. +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-daemon-export-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 #### diff --git a/no-nb/04-git-server/01-chapter4.markdown b/no-nb/04-git-server/01-chapter4.markdown index 29d33bd57..244463a46 100644 --- a/no-nb/04-git-server/01-chapter4.markdown +++ b/no-nb/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ The negative aspect of SSH is that you can’t serve anonymous access of your re ### 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-deamon-export-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. +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-daemon-export-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 #### diff --git a/pl/04-git-server/01-chapter4.markdown b/pl/04-git-server/01-chapter4.markdown index 08e95b3d7..50550ae02 100644 --- a/pl/04-git-server/01-chapter4.markdown +++ b/pl/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ Wadą dostępu po SSH jest to, że nie istnieje dostęp anonimowy do repozytoriu ### Protokół Git ### -Następnie mamy protokół Git. To specjalny rodzaj procesu demona, który dostępny jest w pakiecie z Gitem; słucha na dedykowanym porcie (9418) i udostępnia usługi podobne do protokołu SSH, ale całkowicie bez obsługi uwierzytelnienia. Aby repozytorium mogło być udostępnione po protokole Git konieczne jest utworzenie pliku `git-deamon-export-ok` - bez niego demon nie udostępni repozytorium - ale to jedyne zabezpieczenie. Albo wszyscy mogą klonować dane repozytorium, albo nikt. Generalnie oznacza to że nie można pchać zmian po tym protokole. Można włączyć taką możliwość; ale biorąc pod uwagę brak mechanizmów uwierzytelniania, jeśli włączysz możliwość zapisu, każdy w Internecie, kto odkryje adres Twojego projektu może pchać do niego zmiany. Wystarczy powiedzieć, że nie spotyka się często takich sytuacji. +Następnie mamy protokół Git. To specjalny rodzaj procesu demona, który dostępny jest w pakiecie z Gitem; słucha na dedykowanym porcie (9418) i udostępnia usługi podobne do protokołu SSH, ale całkowicie bez obsługi uwierzytelnienia. Aby repozytorium mogło być udostępnione po protokole Git konieczne jest utworzenie pliku `git-daemon-export-ok` - bez niego demon nie udostępni repozytorium - ale to jedyne zabezpieczenie. Albo wszyscy mogą klonować dane repozytorium, albo nikt. Generalnie oznacza to że nie można pchać zmian po tym protokole. Można włączyć taką możliwość; ale biorąc pod uwagę brak mechanizmów uwierzytelniania, jeśli włączysz możliwość zapisu, każdy w Internecie, kto odkryje adres Twojego projektu może pchać do niego zmiany. Wystarczy powiedzieć, że nie spotyka się często takich sytuacji. #### Zalety #### diff --git a/pt-br/04-git-server/01-chapter4.markdown b/pt-br/04-git-server/01-chapter4.markdown index 9411c3f06..abdc94532 100644 --- a/pt-br/04-git-server/01-chapter4.markdown +++ b/pt-br/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ O aspecto negativo do SSH é que você não pode permitir acesso anônimo do seu ### O Protocolo Git ### -O próximo é o protocolo Git. Este é um daemon especial que vem no mesmo pacote que o Git; ele escuta em uma porta dedicada (9418) que provê um serviço similar ao do protocolo SSH, mas absolutamente sem nenhuma autenticação. Para que um repositório seja disponibilizado via protocolo Git, você tem que criar o arquivo `git-deamon-export-ok` — o daemon não disponibilizará um repositório sem este arquivo dentro — mas além disso não há nenhuma segurança. Ou o repositório Git está disponível para todos clonarem ou não. Isto significa que geralmente não existe envio (push) sobre este protocolo. Você pode habilitar o acesso a envio; mas dada a falta de autenticação, se você ativar o acesso de envio, qualquer um na internet que encontre a URL do seu projeto poderia enviar (push) para o seu projeto. É suficiente dizer que isto é raro. +O próximo é o protocolo Git. Este é um daemon especial que vem no mesmo pacote que o Git; ele escuta em uma porta dedicada (9418) que provê um serviço similar ao do protocolo SSH, mas absolutamente sem nenhuma autenticação. Para que um repositório seja disponibilizado via protocolo Git, você tem que criar o arquivo `git-daemon-export-ok` — o daemon não disponibilizará um repositório sem este arquivo dentro — mas além disso não há nenhuma segurança. Ou o repositório Git está disponível para todos clonarem ou não. Isto significa que geralmente não existe envio (push) sobre este protocolo. Você pode habilitar o acesso a envio; mas dada a falta de autenticação, se você ativar o acesso de envio, qualquer um na internet que encontre a URL do seu projeto poderia enviar (push) para o seu projeto. É suficiente dizer que isto é raro. #### Os Prós #### diff --git a/ru/04-git-server/01-chapter4.markdown b/ru/04-git-server/01-chapter4.markdown index cfb52a42e..0c9e085f4 100644 --- a/ru/04-git-server/01-chapter4.markdown +++ b/ru/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ SSH имеет множество достоинств. Во-первых, вы, ### Git-протокол ### -Следующий протокол — Git-протокол. Вместе с Git'ом поставляется специальный демон, который слушает порт 9418 и предоставляет сервис, схожий с протоколом ssh, но абсолютно без аутентификации. Чтобы использовать Git-протокол для репозитория, вы должны создать файл `git-deamon-export-ok`, иначе демон не будет работать с этим репозиторием, но следует помнить, что в протоколе отсутствуют средства безопасности. Соответственно, любой репозиторий в Git'е может быть либо доступен для клонирования всем, либо не доступен никому. Как следствие, обычно вы не можете отправлять изменения по этому протоколу. Вы можете открыть доступ на запись, но из-за отсутствия авторизации в этом случае кто угодно, зная URL вашего проекта, сможет его изменить. В общем, это редко используемая возможность. +Следующий протокол — Git-протокол. Вместе с Git'ом поставляется специальный демон, который слушает порт 9418 и предоставляет сервис, схожий с протоколом ssh, но абсолютно без аутентификации. Чтобы использовать Git-протокол для репозитория, вы должны создать файл `git-daemon-export-ok`, иначе демон не будет работать с этим репозиторием, но следует помнить, что в протоколе отсутствуют средства безопасности. Соответственно, любой репозиторий в Git'е может быть либо доступен для клонирования всем, либо не доступен никому. Как следствие, обычно вы не можете отправлять изменения по этому протоколу. Вы можете открыть доступ на запись, но из-за отсутствия авторизации в этом случае кто угодно, зная URL вашего проекта, сможет его изменить. В общем, это редко используемая возможность. #### Достоинства #### diff --git a/zh/04-git-server/01-chapter4.markdown b/zh/04-git-server/01-chapter4.markdown index 514b1a3f6..c04b5933b 100644 --- a/zh/04-git-server/01-chapter4.markdown +++ b/zh/04-git-server/01-chapter4.markdown @@ -70,7 +70,7 @@ SSH 的限制在于你不能通过它实现仓库的匿名访问。即使仅为 ### Git 协议 ### -接下来是 Git 协议。这是一个包含在 Git 软件包中的特殊守护进程; 它会监听一个提供类似于 SSH 服务的特定端口(9418),而无需任何授权。打算支持 Git 协议的仓库,需要先创建 `git-deamon-export-ok` 文件 — 它是协议进程提供仓库服务的必要条件 — 但除此之外该服务没有什么安全措施。要么所有人都能克隆 Git 仓库,要么谁也不能。这也意味着该协议通常不能用来进行推送。你可以允许推送操作;然而由于没有授权机制,一旦允许该操作,网络上任何一个知道项目 URL 的人将都有推送权限。不用说,这是十分罕见的情况。 +接下来是 Git 协议。这是一个包含在 Git 软件包中的特殊守护进程; 它会监听一个提供类似于 SSH 服务的特定端口(9418),而无需任何授权。打算支持 Git 协议的仓库,需要先创建 `git-daemon-export-ok` 文件 — 它是协议进程提供仓库服务的必要条件 — 但除此之外该服务没有什么安全措施。要么所有人都能克隆 Git 仓库,要么谁也不能。这也意味着该协议通常不能用来进行推送。你可以允许推送操作;然而由于没有授权机制,一旦允许该操作,网络上任何一个知道项目 URL 的人将都有推送权限。不用说,这是十分罕见的情况。 #### 优点 #### From 28f93d9cf20983fc2ce005816a60ecd49090a3ab Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Jan 2014 15:21:16 -0300 Subject: [PATCH 069/690] Fix issue #612: Bad spanish translation --- es/03-git-branching/01-chapter3.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es/03-git-branching/01-chapter3.markdown b/es/03-git-branching/01-chapter3.markdown index 8d885fb89..f745f493b 100644 --- a/es/03-git-branching/01-chapter3.markdown +++ b/es/03-git-branching/01-chapter3.markdown @@ -257,7 +257,7 @@ Donde nos dice que la versión en HEAD (la rama 'master', la que habias activado Esta corrección contiene un poco de ambas partes. Y se han eliminado completamente las líneas `<<<<<<<` , `=======` y `>>>>>>>` Tras resolver todos los bloques conflictivos, has de lanzar comandos 'git add' para marcar cada archivo modificado. Marcar archivos como preparados (staging), indica a Git que sus conflictos han sido resueltos. -Si, en lugar de resolver directamente, prefieres utilizar una herramienta gráfica. Puedes usar el comando 'git mergetool'. Esto arrancará la correspondiente herramienta de visualización y te permirá ir resolviendo conflictos con ella. +Si en lugar de resolver directamente, prefieres utilizar una herramienta gráfica, puedes usar el comando 'git mergetool'. Esto arrancará la correspondiente herramienta de visualización y te permirá ir resolviendo conflictos con ella. $ git mergetool merge tool candidates: kdiff3 tkdiff xxdiff meld gvimdiff opendiff emerge vimdiff From 0d7b37596f82e229ac7fda21a09078669856a1f4 Mon Sep 17 00:00:00 2001 From: Broda Noel Date: Fri, 10 Jan 2014 15:49:23 -0300 Subject: [PATCH 070/690] Fix issue #611. Bad Spanish translation --- es/03-git-branching/01-chapter3.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es/03-git-branching/01-chapter3.markdown b/es/03-git-branching/01-chapter3.markdown index 8d885fb89..a4dab04b6 100644 --- a/es/03-git-branching/01-chapter3.markdown +++ b/es/03-git-branching/01-chapter3.markdown @@ -388,7 +388,7 @@ Esto puede ser un tanto confuso, pero intentemos aclararlo con un ejemplo. Supo Insert 18333fig0322.png Figura 3-22. Un clón Git te proporciona tu propia rama 'master' y otra rama 'origin/master' apuntando a la rama 'master' original. -Si haces algún trabajo en tu rama 'master' local. Y, al mismo tiempo, alguna otra persona lleva (push) su trabajo al servidor 'git.ourcompany.com', actualizando la rama 'master' de allí. Te encontrarás con que ambos registros avanzan de forma diferente. Además, mientras no tengas contacto con el servidor, tu apuntador a tu rama 'origin/master' no se moverá (ver Figura 3/23). +Si haces algún trabajo en tu rama 'master' local, y al mismo tiempo, alguna otra persona lleva (push) su trabajo al servidor 'git.ourcompany.com', actualizando la rama 'master' de allí, te encontrarás con que ambos registros avanzan de forma diferente. Además, mientras no tengas contacto con el servidor, tu apuntador a tu rama 'origin/master' no se moverá (ver Figura 3/23). Insert 18333fig0323.png Figura 3-23. Trabajando localmente y que otra persona esté llevando (push) algo al servidor remoto, hace que cada registro avance de forma distinta. From a21668220e7948e86d301ab455232d9748668be7 Mon Sep 17 00:00:00 2001 From: Krzysztof Gibas Date: Sat, 11 Jan 2014 23:35:44 +0100 Subject: [PATCH 071/690] [pl] chapter 7 improvements --- pl/07-customizing-git/01-chapter7.markdown | 27 ++++++++++++++-------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/pl/07-customizing-git/01-chapter7.markdown b/pl/07-customizing-git/01-chapter7.markdown index 5b9e6bfa2..2476a295c 100644 --- a/pl/07-customizing-git/01-chapter7.markdown +++ b/pl/07-customizing-git/01-chapter7.markdown @@ -132,7 +132,7 @@ Teraz, możesz podpisywać tagi bez konieczności wskazywania za każdym razem k #### core.excludesfile #### -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`. +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 lokalizację 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`. @@ -317,27 +317,36 @@ Jeżeli uruchomić tą komendę, zamiast ustawienia plików `extMerge` i `extDif -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 - -Git posiada kilka opcji konfiguracyjnych, które pomagają rozwiązać te problemy. +Problemy związane z formatowaniem i białymi znakami są jednymi z bardziej uciążliwych i wyrafinowanych, które wielu deweloperów mogą spotkać podczas pracy, szczególnie jeżeli korzystają z różnych systemów operacyjnych. Bardzo łatwo można je wprowadzić w łatach lub modyfikacjach, poprzez samoistne dodanie ich przez edytor tekstowy, lub dodanie znaku powrotu karetki na końcach linii przez programistów korzystających z systemu Windows. Git posiada kilka opcji konfiguracyjnych, które pomagają rozwiązać te problemy. #### core.autocrlf #### -If you’re programming on Windows or using another system but working with people who are programming on Windows, you’ll probably run into line-ending issues at some point. This is because Windows uses both a carriage-return character and a linefeed character for newlines in its files, whereas Mac and Linux systems use only the linefeed character. This is a subtle but incredibly annoying fact of cross-platform work. -Git can handle this by auto-converting CRLF line endings into LF when you commit, and vice versa when it checks out code onto your filesystem. You can turn on this functionality with the `core.autocrlf` setting. If you’re on a Windows machine, set it to `true` — this converts LF endings into CRLF when you check out code: +Jeżeli programujesz na systemie Windows, lub używasz innego systemu, ale współpracujesz z osobami które programują na tym systemie, prawdopodobnie będziesz miał w pewnym momencie problemy związane ze znakami końca linii. Dzieje się tak dlatego, ponieważ system Windows używa obu znaków powrotu karetki i nowej linii w celu oznaczenia końca wiersza w swoich plikach, a tymczasem w systemach Mac i Linux użwany jest jedynie znak nowej linii. To jest subtelny, ale bardzo irytujący fakt przy współpracy na wielu platformach. + + + +Git może to obsłużyć poprzez automatyczną konwersję linii CRLF na LF, gdy wykonujesz commit, i odwrotnie podczas pobierania kodu na dysk. Możesz włączyć tą funkcjonalność za pomocą ustawienia `core.autocrlf`. Jeżeli pracujesz na systemie Windows, ustaw jej wartość na `true` - zamieni to znaki LF na CRLS podczas pobierania kodu. + + $ git config --global core.autocrlf true -If you’re on a Linux or Mac system that uses LF line endings, then you don’t want Git to automatically convert them when you check out files; however, if a file with CRLF endings accidentally gets introduced, then you may want Git to fix it. You can tell Git to convert CRLF to LF on commit but not the other way around by setting `core.autocrlf` to input: +Jeżeli pracujesz na systemie Linux lub Mac, który używa znaków LF oznaczających koniec wiersza, nie będziesz chciał, aby Git automatycznie konwertował je podczas pobierania kodu; jednakże, jeżeli zostanie przez pomyłkę wgrany plik z zakończeniami CRLF, możesz chcieć aby Git je poprawił. Możesz wskazać Git, aby konwertował znaki CRLF na LF podczas commita, ale nie w odwrotną stronę ustawiając `core.autocrlf` na input: + + $ git config --global core.autocrlf input -This setup should leave you with CRLF endings in Windows checkouts but LF endings on Mac and Linux systems and in the repository. +Takie ustawienia powinny zachować znaki CRLF na systemach Windows, oraz LF na systemach Mac i Linux, oraz w repozytorium. + + + +Jeżeli jesteś programistą tworzącym aplikację przeznaczoną wyłącznie na systemy Windows, możesz zupełnie wyłączyć tą funkcjonalność przez ustawienie wartości false, przez co znaki powrotu karetki również będą zapisywanie w repozytorium. -If you’re a Windows programmer doing a Windows-only project, then you can turn off this functionality, recording the carriage returns in the repository by setting the config value to `false`: + $ git config --global core.autocrlf false From 9cc46bbf390c6c762f9fe5902395510289a4349b Mon Sep 17 00:00:00 2001 From: Krzysztof Gibas Date: Sat, 11 Jan 2014 23:42:15 +0100 Subject: [PATCH 072/690] =?UTF-8?q?[pl]=20s/t=C4=85=20komend=C4=99/t=C4=99?= =?UTF-8?q?=20komend=C4=99/?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pl/05-distributed-git/01-chapter5.markdown | 2 +- pl/06-git-tools/01-chapter6.markdown | 2 +- pl/07-customizing-git/01-chapter7.markdown | 2 +- pl/08-git-and-other-scms/01-chapter8.markdown | 4 ++-- pl/09-git-internals/01-chapter9.markdown | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pl/05-distributed-git/01-chapter5.markdown b/pl/05-distributed-git/01-chapter5.markdown index 257072367..61032e009 100644 --- a/pl/05-distributed-git/01-chapter5.markdown +++ b/pl/05-distributed-git/01-chapter5.markdown @@ -133,7 +133,7 @@ Po pierwsze, nie chcesz wgrywać żadnych błędów związanych z poprawkami pus + def command(git_cmd)XXXX -Jeżeli uruchomisz tą komendę przed commit-em, dowiesz się czy zamierzasz wgrać zmiany które mogą zdenerwować innych programistów. +Jeżeli uruchomisz tę komendę przed commit-em, dowiesz się czy zamierzasz wgrać zmiany które mogą zdenerwować innych programistów. diff --git a/pl/06-git-tools/01-chapter6.markdown b/pl/06-git-tools/01-chapter6.markdown index 0aff34822..228326762 100644 --- a/pl/06-git-tools/01-chapter6.markdown +++ b/pl/06-git-tools/01-chapter6.markdown @@ -1330,7 +1330,7 @@ Dzieje się tak dlatego, ponieważ wskaźnik który masz dla modułu zależnego, 08d709f..6c5e70b master -> origin/master Submodule path 'rack': checked out '6c5e70b984a60b3cecd395edd5b48a7575bf58e0' -Musisz wykonywać tą komendę, za każdym razem gdy ściągniesz zmiany z modułu do swojego projektu. Trochę to dziwne, ale działa. +Musisz wykonywać tę komendę, za każdym razem gdy ściągniesz zmiany z modułu do swojego projektu. Trochę to dziwne, ale działa. diff --git a/pl/07-customizing-git/01-chapter7.markdown b/pl/07-customizing-git/01-chapter7.markdown index 5b9e6bfa2..7bf7b7b31 100644 --- a/pl/07-customizing-git/01-chapter7.markdown +++ b/pl/07-customizing-git/01-chapter7.markdown @@ -309,7 +309,7 @@ Git jest wstępnie skonfigurowany do używania wielu innych narzędzi do łącze $ git config --global merge.tool kdiff3 -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. +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. diff --git a/pl/08-git-and-other-scms/01-chapter8.markdown b/pl/08-git-and-other-scms/01-chapter8.markdown index 19155bca8..b855eba7a 100644 --- a/pl/08-git-and-other-scms/01-chapter8.markdown +++ b/pl/08-git-and-other-scms/01-chapter8.markdown @@ -264,7 +264,7 @@ Warto to zapamiętać, że wynikiem będzie projekt w stanie, w którym nie istn -Powinieneś również uruchamiać tą komendę, aby pobierać zmiany z serwera Subversion, nawet jeżeli nie jesteś jeszcze gotowy do zapisania swoich. Możesz uruchomić `git svn fetch`, aby pobrać nowe dane, `git svn rebase` zrobi to samo, jednak również nałoży Twoje lokalne modyfikacje. +Powinieneś również uruchamiać tę komendę, aby pobierać zmiany z serwera Subversion, nawet jeżeli nie jesteś jeszcze gotowy do zapisania swoich. Możesz uruchomić `git svn fetch`, aby pobrać nowe dane, `git svn rebase` zrobi to samo, jednak również nałoży Twoje lokalne modyfikacje. @@ -477,7 +477,7 @@ W ten sposób, nie zaśmiecasz swojego projektu plikami `.gitignore`. Jest to do -Narzędzia dostarczane przez `git svn` są przydatne, jeżeli musisz używać serwera Subversion, lub jeżeli są inne przesłanki, które zmuszają Cię do tego. Powinieneś patrzeć na tą komendę jak na ograniczonego Gita, lub inaczej będziesz natrafiał na kłopotliwe dla innych programistów problemy. Aby napotykać ich jak najmniej, trzymaj się tych zasad: +Narzędzia dostarczane przez `git svn` są przydatne, jeżeli musisz używać serwera Subversion, lub jeżeli są inne przesłanki, które zmuszają Cię do tego. Powinieneś patrzeć na tę komendę jak na ograniczonego Gita, lub inaczej będziesz natrafiał na kłopotliwe dla innych programistów problemy. Aby napotykać ich jak najmniej, trzymaj się tych zasad: diff --git a/pl/09-git-internals/01-chapter9.markdown b/pl/09-git-internals/01-chapter9.markdown index 5caebd6d1..3bdd05268 100644 --- a/pl/09-git-internals/01-chapter9.markdown +++ b/pl/09-git-internals/01-chapter9.markdown @@ -416,7 +416,7 @@ W Gitcie nazywane są one "referencjami" lub krócej "refs"; możesz znaleźć p $ find .git/refs -type f $ -Aby stworzyć nową referencję, która pomocna będzie przy zapamiętywaniu który commit jest ostatni, możesz wykonać tą prostą komendę: +Aby stworzyć nową referencję, która pomocna będzie przy zapamiętywaniu który commit jest ostatni, możesz wykonać tę prostą komendę: From ca6c022c8974b1f089f3162df9272fb69e35aa4f Mon Sep 17 00:00:00 2001 From: Broda Noel Date: Sat, 11 Jan 2014 20:59:05 -0300 Subject: [PATCH 073/690] Fix issue #620 --- es/04-git-server/01-chapter4.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/es/04-git-server/01-chapter4.markdown b/es/04-git-server/01-chapter4.markdown index ef8af9cf8..14bc87477 100755 --- a/es/04-git-server/01-chapter4.markdown +++ b/es/04-git-server/01-chapter4.markdown @@ -361,9 +361,9 @@ En este punto, es posible que desees cambiar a un popular programa llamado Gitos Instalar Gitosis no es precisamente sencillo. Pero tampoco demasiado complicado. Es más sencillo hacerlo si utilizas un servidor Linux --estos ejemplos se han hecho sobre un servidor Ubuntu 8.10--. -Gitosis necesita de ciertas herramientas Python, por lo que la primera tarea será instalar el paquete de herramientas Pyton. En Ubuntu viene como el paquete python-stuptools: +Gitosis necesita de ciertas herramientas Python, por lo que la primera tarea será instalar el paquete de herramientas Pyton. En Ubuntu viene como el paquete python-setuptools: - $ apt-get install python-setuptools + $ sudo apt-get install python-setuptools A continuación, has de clonar e instalar Gitosis desde el repositorio principal de su proyecto: From 168dfddc091aae4f1191ff996513f36659e5a41e Mon Sep 17 00:00:00 2001 From: Changwoo Park Date: Sun, 10 Nov 2013 08:18:41 +0900 Subject: [PATCH 074/690] [ko] update fonts and thanks for pdf --- latex/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/latex/config.yml b/latex/config.yml index 4271597c8..2ed0f7939 100644 --- a/latex/config.yml +++ b/latex/config.yml @@ -116,9 +116,9 @@ de: 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 + font: NanumBarunGothic bold: "{* Bold}" - mono: NanumGothicCoding + mono: NanumGothicCoding prechap: "" postchap: "장" presect: "" @@ -127,7 +127,7 @@ ko: con: "목차" fig: "그림" tab: "표" - thanks: "지금 보시는 문서는 Pro Git 책에 대한 PDF 파일입니다. 본 문서는 Creative Commons 저작자표시-비영리조건-동일조건변경허락 3.0(Creative Commons Attribution-Non Commercial-Share Alike 3.0) 라이센스를 따릅니다. 여러분이 Git을 이해하는데 도움이 되기를 희망합니다. 종이로 출판된 책을 Amazon 웹사이트 \\url{http://tinyurl.com/amazonprogit} 에서 구입하여 저를 비롯한 Apress에도 도움을 주시기를 기대하겠습니다.\\newline한국어 번역은 박창우(pismute@gmail.com), 이성환(lethee@gmail.com)이 하였습니다. 오역 등의 개선 사항은 역자의 메일로 보내주시거나 한국어 번역 게시판에 \\url{https://github.com/dogfeet/progit/issues} 남겨주시기 바랍니다. 직접 개선해서 패치나 Pull Request를 보내주셔도 됩니다." + thanks: "지금 보시는 문서는 Pro Git 책에 대한 PDF 파일입니다. 본 문서는 Creative Commons 저작자표시-비영리조건-동일조건변경허락 3.0(Creative Commons Attribution-Non Commercial-Share Alike 3.0) 라이센스를 따릅니다. 여러분이 Git을 이해하는데 도움이 되기를 희망합니다. 종이로 출판된 책을 Amazon 웹사이트 \\url{http://tinyurl.com/amazonprogit} 에서 구입하여 저를 비롯한 Apress에도 도움을 주시기를 기대하겠습니다.\\newline한국어 번역판도 인사이트를 통해 종이로 출판됐습니다. 한국어 번역에 대한 자세한 정보는 \\url{https://github.com/progit/progit/tree/master/ko}에서 확인 바람니다." be: prechap: "Глава " presect: "Раздзел " From e8d8978818ee81a3a25a88b5762d5f2576f63afe Mon Sep 17 00:00:00 2001 From: Changwoo Park Date: Sun, 10 Nov 2013 08:32:31 +0900 Subject: [PATCH 075/690] [ko] update ko/README --- ko/README | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ko/README b/ko/README index f44feb7e2..d625b729e 100644 --- a/ko/README +++ b/ko/README @@ -48,3 +48,9 @@ Mac에서는 먼저 Pandoc과 MacTex 패키지를 설치합니다. pdf를 빌드 번역, 박창우(Changwoo Park), pismute at gmail dot com, https://github.com/pismute 번역, 이성환(Sean Lee), lethee at gmail dot comt, https://github.com/lethee +번역, 최용재(Yongjae choi), lnyarl at gmail dot comt, https://github.com/lnyarl + +종이책 +===================== + +[인사이트](http://www.insightbook.co.kr/)를 통해서 Pro Git 한글 번역판이 종이로도 출간됐습니다. 인사이트와 역자에게 도움을 주시기 바람니다. From 22e4411f9ea251febf9ec1b685b38c235cde08da Mon Sep 17 00:00:00 2001 From: Changwoo Park Date: Wed, 18 Dec 2013 20:56:10 +0900 Subject: [PATCH 076/690] [ko] update translation --- ko/02-git-basics/01-chapter2.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ko/02-git-basics/01-chapter2.markdown b/ko/02-git-basics/01-chapter2.markdown index 123b17df7..88b86ca02 100644 --- a/ko/02-git-basics/01-chapter2.markdown +++ b/ko/02-git-basics/01-chapter2.markdown @@ -1107,9 +1107,9 @@ Git의 기초를 마치기 전에 Git을 좀 더 쉽고 편안하게 쓸 수 있 ### 자동완성 ### -Bash 쉘을 쓰고 있다면 멋진 자동완성(Auto-completion) 기능을 사용할 수 있다. Git의 소스코드를 다운받아 `contrib/completion` 디렉토리를 살펴보면 `git-completion.bash`라는 파일이 있다. 그 파일을 홈 디렉토리에 카피하고 `.bashrc` 파일에 아래와 같은 내용을 추가하자: +Bash 쉘을 쓰고 있다면 멋진 자동완성(Auto-completion) 기능을 사용할 수 있다. https://github.com/git/git/blob/master/contrib/completion/git-completion.bash 에서 바로 다운받는다. 그 파일을 홈 디렉토리에 카피하고 `.bashrc` 파일에 아래와 같은 내용을 추가하자: - source ~/.git-completion.bash + source ~/git-completion.bash 또 모든 사용자가 사용할 수 있게 설정할 수 있다. Mac 시스템이라면 이 스크립트를 `/opt/local/etc/bash_completion.d` 디렉토리에 복사하고 리눅스라면 `/etc/bash_completion.d/`에 복사한다. 이 디렉토리는 Bash가 자동완성을 지원하기 위해 사용하는 디렉토리다. From 7a425995f66f9b2d9de5ae54a8c5e86c1db6457a Mon Sep 17 00:00:00 2001 From: Changwoo Park Date: Wed, 18 Dec 2013 21:00:54 +0900 Subject: [PATCH 077/690] [ko] fix typo. --- ko/07-customizing-git/01-chapter7.markdown | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ko/07-customizing-git/01-chapter7.markdown b/ko/07-customizing-git/01-chapter7.markdown index 3c4f1fe1a..e93c49a46 100644 --- a/ko/07-customizing-git/01-chapter7.markdown +++ b/ko/07-customizing-git/01-chapter7.markdown @@ -333,11 +333,9 @@ Git은 바이너리 파일도 diff할 수 있다. Git Attribute를 통해 Git이 위의 명령은 아래와 같은 내용을 `.git/config` 파일에 추가한다: [diff "word"] - textconv = strings + textconv = catdoc -댓글: `.doc` 파일의 종류는 여러가지이다. UTF-16 인코딩을 쓰거나 "codepages" 기반(역주: 한글은 Codepage 949) 인코딩을 사용 할 수도 있다. `catdoc`으로는 유용한 정보를 아무것도 찾지 못할 수 있다. - -이제 Git은 확장자가 `.doc`인 파일의 스냅샷을 diff할 때 "word" 필터로 정의한 `strings` 프로그램을 사용한다. 이 프로그램은 Word 파일을 텍스트 파일로 변환해 주기 때문에 diff할 수 있다. +이제 Git은 확장자가 `.doc`인 파일의 스냅샷을 diff할 때 "word" 필터로 정의한 `catdoc` 프로그램을 사용한다. 이 프로그램은 Word 파일을 텍스트 파일로 변환해 주기 때문에 diff할 수 있다. 이 책의 *1장*을 Word 파일로 만들어서 Git에 넣고 나서 단락 하나를 수정하고 저장하는 예를 살펴보자. `git diff`를 실행하면 어디가 달려졌는지 확인할 수 있다: From 93acb40f9d23330d2df89e3259b01ae4a3ec0772 Mon Sep 17 00:00:00 2001 From: Changwoo Park Date: Sat, 21 Dec 2013 07:15:27 +0900 Subject: [PATCH 078/690] [ko] fix punctuations for figure --- ko/01-introduction/01-chapter1.markdown | 14 ++-- ko/02-git-basics/01-chapter2.markdown | 4 +- ko/03-git-branching/01-chapter3.markdown | 78 +++++++++++----------- ko/04-git-server/01-chapter4.markdown | 30 ++++----- ko/05-distributed-git/01-chapter5.markdown | 54 +++++++-------- ko/06-git-tools/01-chapter6.markdown | 2 +- ko/07-customizing-git/01-chapter7.markdown | 6 +- ko/09-git-internals/01-chapter9.markdown | 8 +-- 8 files changed, 98 insertions(+), 98 deletions(-) diff --git a/ko/01-introduction/01-chapter1.markdown b/ko/01-introduction/01-chapter1.markdown index 0cbacd34b..a7a24715b 100644 --- a/ko/01-introduction/01-chapter1.markdown +++ b/ko/01-introduction/01-chapter1.markdown @@ -15,7 +15,7 @@ 이런 이유로 프로그래머들은 오래전에 로컬 VCS라는 걸 만들었다. 이 VCS는 아주 간단한 데이터베이스를 사용해서 파일의 변경 정보를 관리했다. Insert 18333fig0101.png -그림 1-1 로컬 버전 관리 다이어그램 +그림 1-1. 로컬 버전 관리 다이어그램 많이 쓰는 VCS 도구 중에 rcs라고 부르는 것이 있는데 오늘날까지도 아직 많은 회사가 사용하고 있다. Mac OS X 운영체제에서도 개발 도구를 설치하면 RCS가 함께 설치된다. RCS는 기본적으로 Patch Set(파일에서 변경되는 부분)을 관리한다. 이 Patch Set은 특별한 형식의 파일로 저장한다. 그리고 일련의 Patch Set을 적용해서 모든 파일을 특정 시점으로 되돌릴 수 있다. @@ -24,7 +24,7 @@ Insert 18333fig0101.png 프로젝트를 진행하다 보면 다른 개발자와 함께 작업해야 하는 경우가 많다. 이럴 때 생기는 문제를 해결하기 위해 CVCS(중앙집중식 VCS)가 개발됐다. CVS, Subversion, Perforce 같은 시스템은 파일을 관리하는 서버가 별도로 있고 클라이언트가 중앙 서버에서 파일을 받아서 사용(Checkout)한다. 수년 동안 이러한 시스템들이 많은 사랑을 받았다. Insert 18333fig0102.png -그림 1-2 중앙집중식 버전 관리(CVCS) 다이어그램 +그림 1-2. 중앙집중식 버전 관리(CVCS) 다이어그램 CVCS 환경은 로컬 VCS에 비해 장점이 많다. 프로젝트에 참여한 사람이면 누가 무엇을 하고 있는지 알 수 있다. 관리자는 누가 무엇을 할 수 있는지 꼼꼼하게 관리할 수 있다. 모든 클라이언트의 로컬 데이터베이스를 관리하는 것보다 VCS 하나를 관리하기가 훨씬 쉽다. @@ -35,7 +35,7 @@ CVCS 환경은 로컬 VCS에 비해 장점이 많다. 프로젝트에 참여한 DVCS(분산 버전 관리 시스템)을 설명할 차례다. Git, Mecurial, Bazaar, Darcs 같은 DVCS에서는 클라이언트가 파일의 마지막 스냅샷을 Checkout하지 않는다. 그냥 저장소를 전부 복제한다. 서버에 문제가 생기면 이 복제물로 다시 작업을 시작할 수 있다. 클라이언트 중에서 아무거나 골라도 서버를 복원할 수 있다. 모든 Checkout은 모든 데이터를 가진 진정한 백업이다. Insert 18333fig0103.png -그림 1-3 분산 버전 관리 시스템(DVCS) 다이어그램 +그림 1-3. 분산 버전 관리 시스템(DVCS) 다이어그램 게다가 대부분의 DVCS 환경에서는 리모트 저장소가 존재한다. 리모트 저장소가 많을 수도 있다. 그래서 사람들은 동시에 다양한 그룹과 다양한 방법으로 협업할 수 있다. 계층 모델 같은 중앙집중식 시스템으로는 할 수 없는 몇 가지 워크플로우를 사용할 수 있다. @@ -62,12 +62,12 @@ Git의 핵심은 뭘까? 이 질문은 Git을 이해하는데 굉장히 중요 Subversion과 Subversion 비슷한 놈들과 Git의 가장 큰 차이점은 데이터를 다루는 방법에 있다. 큰 틀에서 봤을 때 대부분의 VCS 시스템이 관리하는 정보는 파일들의 목록이다. CVS, Subversion, Perforce, Bazaar 등의 시스템은 파일의 집합으로 정보를 관리한다. 각 파일의 변화를 그림 1-4처럼 시간순으로 관리한다. Insert 18333fig0104.png -그림 1-4 각 파일에 대한 변화(델타)를 저장하는 시스템들 +그림 1-4. 각 파일에 대한 변화(델타)를 저장하는 시스템들 Git은 이런 식으로 데이터를 저장하지도 취급하지도 않는다. 대신 Git의 데이터는 파일 시스템의 스냅샷이라 할 수 있으며 크기가 아주 작다. Git은 커밋하거나 프로젝트의 상태를 저장할 때마다 파일이 존재하는 그 순간을 중요하게 여긴다. 파일이 달라지지 않았으면 Git은 성능을 위해서 파일을 저장하지 않는다. 단지 이전 상태의 파일에 대한 링크만 저장한다. Git은 그림 1-5처럼 동작한다. Insert 18333fig0105.png -그림 1-5 Git은 시간순으로 프로젝트의 스냅샷을 저장한다 +그림 1-5. Git은 시간순으로 프로젝트의 스냅샷을 저장한다 이것이 Git이 다른 VCS와 구분되는 점이다. 이점 때문에 Git는 다른 시스템들이 과거로부터 답습해왔던 버전 컨트롤의 개념과 다르다는 것이고 많은 부분을 새로운 관점에서 바라본다. Git은 강력한 도구를 지원하는 작은 파일시스템이다. Git은 단순한 VCS가 아니다. 이제 3장에서 설명할 Git 브랜치를 사용하면 얻게 되는 이득이 무엇인지 설명한다. @@ -102,7 +102,7 @@ Git을 사용하면 프로젝트가 심각하게 망가질 걱정 없이 매우 이 세 가지 상태는 Git 프로젝트의 세 가지 단계와 연결돼 있다. Git 디렉토리, 워킹 디렉토리, Staging Area 이렇게 세 가지 단계를 이해하고 넘어가자. Insert 18333fig0106.png -그림 1-6 워킹 디렉토리, Staging Area, Git 디렉토리 +그림 1-6. 워킹 디렉토리, Staging Area, Git 디렉토리 Git 디렉토리는 Git이 프로젝트의 메타데이터와 객체 데이터베이스를 저장하는 곳을 말한다. Git 디렉토리가 Git의 핵심이다. 다른 컴퓨터에 있는 저장소를 Clone 할 때 Git 디렉토리가 만들어진다. @@ -166,7 +166,7 @@ Mac에 Git을 쉽게 설치하는 방법은 두 가지가 있다. GUI 인스톨 http://code.google.com/p/git-osx-installer Insert 18333fig0107.png -그림 1-7 OS X Git 인스톨러 +그림 1-7. OS X Git 인스톨러 MacPorts(`http://www.macports.org`)를 사용하는 방법도 있다. MacPorts가 설치돼 있으면 아래와 같이 Git을 설치한다: diff --git a/ko/02-git-basics/01-chapter2.markdown b/ko/02-git-basics/01-chapter2.markdown index 88b86ca02..9353c88e3 100644 --- a/ko/02-git-basics/01-chapter2.markdown +++ b/ko/02-git-basics/01-chapter2.markdown @@ -47,7 +47,7 @@ Git은 다양한 프로토콜을 지원한다. 이제까지는 `git://` 프로 마지막 커밋 이후 아직 아무것도 수정하지 않은 상태에서 어떤 파일이 수정되면 Git은 그 즉시 파일을 *Modified* 상태로 인식한다. 그리고 이 수정한 파일을 Stage하고 *Staged* 상태인 파일을 커밋한다. 이 라이프사이클을 그림 2-1처럼 계속 반복한다. Insert 18333fig0201.png -그림 2-1 파일의 라이프사이클 +그림 2-1. 파일의 라이프사이클 ### 파일의 상태 확인하기 ### @@ -669,7 +669,7 @@ The lines must be formatted as follows GUI 도구로 커밋 히스토리를 시각화하고 싶다면 gitk를 사용할 수 있다. gitk는 Tcl/Tk 프로그램이고 `git log` 명령을 시각화해주는 도구다. gitk는 `git log` 명령이 지원하는 필터링 옵션을 거의 모두 지원한다. 프로젝트 디렉토리에서 gitk를 실행하면 그림 2-2처럼 보일 것이다. Insert 18333fig0202.png -그림 2-2 gitk의 히스토리 +그림 2-2. gitk의 히스토리 위쪽 반을 차지하는 윈도에서는 히스토리를 그래프로 예쁘게 보여준다. 아래쪽 반을 차지하는 윈도는 diff 결과를 보여주는데 위쪽 윈도에서 선택한 커밋에 대한 diff 결과를 보여준다. diff --git a/ko/03-git-branching/01-chapter3.markdown b/ko/03-git-branching/01-chapter3.markdown index a9cc52748..9a66a6841 100644 --- a/ko/03-git-branching/01-chapter3.markdown +++ b/ko/03-git-branching/01-chapter3.markdown @@ -22,17 +22,17 @@ Git이 브랜치하는 과정을 이해하려면 우선 Git이 데이터를 어 이 작업을 마치고 나면 Git 저장소에는 다섯 개의 데이터 개체가 생긴다. 각 파일에 대한 Blob 세 개, 파일과 디렉토리 구조가 들어 있는 트리 개체 하나, 메타데이터와 루트 트리를 가리키는 포인터가 담긴 커밋 개체 하나이다. 이것을 그림으로 그리면 그림 3-1과 같다. Insert 18333fig0301.png -그림 3-1 저장소의 커밋 데이터 +그림 3-1. 저장소의 커밋 데이터 다시 파일을 수정하고 커밋하면 이전 커밋이 무엇인지도 저장한다. 커밋을 두 번 더 하면 그림 3-2과 같이 저장된다. Insert 18333fig0302.png -그림 3-2 Git 커밋의 개체 데이터 +그림 3-2. Git 커밋의 개체 데이터 Git의 브랜치는 커밋 사이를 가볍게 이동할 수 있는 어떤 포인터 같은 것이다. 기본적으로 Git은 `master` 브랜치를 만든다. 최초로 커밋하면 Git은 master라는 이름의 브랜치를 만들어서 자동으로 가장 마지막 커밋을 가리키게 한다. Insert 18333fig0303.png -그림 3-3 가장 최근 커밋 정보를 가리키는 브랜치 +그림 3-3. 가장 최근 커밋 정보를 가리키는 브랜치 브랜치를 하나 새로 만들면 어떨까? 브랜치를 하나 만들어서 놀자. 다음과 같이 `git branch` 명령으로 testing 브랜치를 만든다. @@ -41,12 +41,12 @@ Insert 18333fig0303.png 새로 만든 브랜치도 지금 작업하고 있던 마지막 커밋을 가리킨다(그림 3-4). Insert 18333fig0304.png -그림 3-4 커밋 개체를 가리키는 두 브랜치 +그림 3-4. 커밋 개체를 가리키는 두 브랜치 지금 작업 중인 브랜치가 무엇인지 Git은 어떻게 파악할까? 다른 버전 관리 시스템과는 달리 Git은 'HEAD'라는 특수한 포인터가 있다. 이 포인터는 지금 작업하는 로컬 브랜치를 가리킨다. 브랜치를 새로 만들었지만, Git은 아직 master 브랜치를 가리키고 있다. `git branch` 명령은 브랜치를 만들기만 하고 브랜치를 옮기지 않는다. Insert 18333fig0305.png -그림 3-5 HEAD는 현재 작업 중인 브랜치를 가리킴 +그림 3-5. HEAD는 현재 작업 중인 브랜치를 가리킴 `git checkout` 명령으로 새로 만든 브랜치로 이동할 수 있다. testing 브랜치로 이동하려면 다음과 같이 한다: @@ -55,7 +55,7 @@ Insert 18333fig0305.png 이렇게 하면 HEAD는 testing 브랜치를 가리킨다. Insert 18333fig0306.png -그림 3-6 HEAD는 옮겨간 다른 브랜치를 가리킨다 +그림 3-6. HEAD는 옮겨간 다른 브랜치를 가리킨다 자, 이제 핵심이 보일 거다! 커밋을 새로 한 번 해보면: @@ -65,7 +65,7 @@ Insert 18333fig0306.png 결과는 그림 3-7과 같다. Insert 18333fig0307.png -그림 3-7 HEAD가 가리키는 testing 브랜치가 새 커밋을 가리킨다 +그림 3-7. HEAD가 가리키는 testing 브랜치가 새 커밋을 가리킨다 이 부분이 흥미롭다. 새로 커밋해서 testing 브랜치는 앞으로 이동했다. 하지만, `master` 브랜치는 여전히 이전 커밋을 가리킨다. `master` 브랜치로 되돌아가면: @@ -74,7 +74,7 @@ Insert 18333fig0307.png 결과는 그림 3-8과 같다. Insert 18333fig0308.png -그림 3-8 HEAD가 Checkout한 브랜치로 이동함 +그림 3-8. HEAD가 Checkout한 브랜치로 이동함 방금 실행한 명령이 한 일은 두 가지다. master 브랜치가 가리키는 커밋을 HEAD가 가리키게 하고 워킹 디렉토리의 파일도 그 시점으로 되돌려 놓았다. 앞으로 커밋을 하면 다른 브랜치의 작업들과 별개로 진행되기 때문에 testing 브랜치에서 임시로 작업하고 원래 master 브랜치로 돌아와서 하던 일을 계속할 수 있다. @@ -86,7 +86,7 @@ Insert 18333fig0308.png 프로젝트 히스토리는 분리돼 진행한다(그림 3-9). 우리는 브랜치를 하나 만들어 그 브랜치에서 일을 좀 하고, 다시 원래 브랜치로 되돌아와서 다른 일을 했다. 두 작업 내용은 서로 독립적으로 각 브랜치에 존재한다. 커밋 사이를 자유롭게 이동하다가 때가 되면 두 브랜치를 Merge한다. 간단히 `branch`와 `checkout` 명령을 써서 말이다. Insert 18333fig0309.png -그림 3-9 브랜치 히스토리가 서로 독립적임 +그림 3-9. 브랜치 히스토리가 서로 독립적임 실제로 Git의 브랜치는 어떤 한 커밋을 가리키는 40글자의 SHA-1 체크섬 파일에 불과하기 때문에 만들기도 쉽고 지우기도 쉽다. 새로 브랜치를 하나 만드는 것은 41바이트 크기의 파일을(40자와 줄 바꿈 문자) 하나 만드는 것에 불과하다. @@ -114,7 +114,7 @@ Insert 18333fig0309.png 먼저 커밋을 몇 번 했다고 가정하자. Insert 18333fig0310.png -그림 3-10 현재 커밋 히스토리 +그림 3-10. 현재 커밋 히스토리 이슈 관리 시스템에 등록된 53번 이슈를 처리한다고 하면 이 이슈에 집중할 수 있는 브랜치를 새로 하나 만든다. Git은 어떤 이슈 관리 시스템에도 종속돼 있지 않다. 브랜치를 만들면서 Checkout까지 한 번에 하려면 `git checkout` 명령에 `-b`라는 옵션을 준다. @@ -129,7 +129,7 @@ Insert 18333fig0310.png 그림 3-11은 위 명령의 결과를 나타낸다. Insert 18333fig0311.png -그림 3-11 브랜치 포인터를 새로 만듦 +그림 3-11. 브랜치 포인터를 새로 만듦 iss53 브랜치를 Checkout했기 때문에(즉, HEAD는 iss53 브랜치를 가리킨다) 뭔가 일을 하고 커밋하면 iss53 브랜치가 앞으로 진행한다: @@ -137,7 +137,7 @@ iss53 브랜치를 Checkout했기 때문에(즉, HEAD는 iss53 브랜치를 가 $ git commit -a -m 'added a new footer [issue 53]' Insert 18333fig0312.png -그림 3-12 진행 중인 iss53 브랜치 +그림 3-12. 진행 중인 iss53 브랜치 다른 상황을 가정해보자. 만드는 사이트에 문제가 생겨서 즉시 고쳐야 한다. 버그를 해결한 Hotfix에 'iss53'이 섞이는 것을 방지하기 위해 'iss53'와 관련된 코드를 어딘가에 저장해두고 원래 운영 환경의 소스로 복구해야 한다. Git을 사용하면 이런 노력을 들일 필요 없이 그냥 master 브랜치로 옮기면 된다. @@ -158,7 +158,7 @@ hotfix라는 브랜치를 만들고 새로운 이슈를 해결할 때까지 사 1 files changed, 0 insertions(+), 1 deletions(-) Insert 18333fig0313.png -그림 3-13 master 브랜치에서 갈라져 나온 hotfix 브랜치 +그림 3-13. master 브랜치에서 갈라져 나온 hotfix 브랜치 운영 환경에 적용하려면 문제를 제대로 고쳤는지 테스트하고 master 브랜치에 합쳐야 한다. `git merge` 명령으로 다음과 같이 한다: @@ -174,7 +174,7 @@ Merge 메시지에서 'Fast forward'가 보이는가? Merge할 브랜치가 가 이제 hotfix는 master 브랜치에 포함됐고 운영환경에 적용할 수 있다(그림 3-14). Insert 18333fig0314.png -그림 3-14 Merge 후 hotfix 브랜치와 같은 것을 가리키는 master 브랜치 +그림 3-14. Merge 후 hotfix 브랜치와 같은 것을 가리키는 master 브랜치 문제를 급히 해결하고 master 브랜치에 적용하고 나면 다시 일하던 브랜치로 돌아가야 한다. 하지만, 그전에 필요없는 hotfix 브랜치를 삭제한다. `git branch` 명령에 `-d` 옵션을 주고 브랜치를 삭제한다. @@ -191,7 +191,7 @@ Insert 18333fig0314.png 1 files changed, 1 insertions(+), 0 deletions(-) Insert 18333fig0315.png -그림 3-15 master와 별개로 진행하는 iss53 브랜치 +그림 3-15. master와 별개로 진행하는 iss53 브랜치 위에서 작업한 hotfix가 iss53 브랜치에 영향을 끼치지 않는다는 점을 이해하는 것이 중요하다. `git merge master` 명령으로 master 브랜치를 iss53 브랜치에 Merge하면 iss53 브랜치에 hotfix가 적용된다. 아니면 iss53 브랜치가 master에 Merge할 수 있는 수준이 될 때까지 기다렸다가 Merge하면 hotfix와 iss53가 합쳐진다. @@ -208,14 +208,14 @@ Insert 18333fig0315.png hotfix를 Merge했을 때와 메시지가 다르다. 현 브랜치가 가리키는 커밋이 Merge할 브랜치의 조상이 아니므로 Git은 'Fast-forward'로 Merge하지 않는다. 이러면 Git은 각 브랜치가 가리키는 커밋 두 개와 공통 조상 하나를 사용하여 3-way Merge를 한다. 그림 3-16에 이 Merge에서 사용하는 커밋 세 개가 표시된다. Insert 18333fig0316.png -그림 3-16 Git은 Merge에 필요한 공통 커밋을 자동으로 찾음 +그림 3-16. Git은 Merge에 필요한 공통 커밋을 자동으로 찾음 단순히 브랜치 포인터를 최신 커밋으로 옮기는 게 아니라 3-way Merge의 결과를 별도의 커밋으로 만들고 나서 해당 브랜치가 그 커밋을 가리키도록 이동시킨다(그림 3-17). 그래서 이런 커밋은 부모가 여러 개고 Merge 커밋이라고 부른다. Git은 Merge하는데 필요한 최적의 공통 조상을 자동으로 찾는다. 이런 기능도 Git이 다른 버전 관리 시스템보다 나은 점이다. CVS나 Subversion 같은 버전 관리 시스템은 개발자가 직접 공통 조상을 찾아서 Merge해야 한다. Git은 다른 시스템보다 Merge가 대단히 쉽다. Insert 18333fig0317.png -그림 3-17 Git은 Merge할 때 Merge에 대한 정보가 들어 있는 커밋를 하나 만든다. +그림 3-17. Git은 Merge할 때 Merge에 대한 정보가 들어 있는 커밋를 하나 만든다. iss53 브랜치를 master에 Merge하고 나면 더는 iss53 브랜치가 필요 없다. 다음 명령으로 브랜치를 삭제하고 이슈의 상태를 처리 완료로 표시한다: @@ -350,12 +350,12 @@ Git은 꼼꼼하게 3-way Merge를 사용하기 때문에 장기간에 걸쳐서 사실 우리가 얘기하는 것은 커밋을 가리키는 포인터에 대한 얘기다. 개발 브랜치는 공격적으로 히스토리를 만들어 나아가고 안정 브랜치는 이미 만든 히스토리를 뒤따르며 나아간다. Insert 18333fig0318.png -그림 3-18 안정적인 브랜치일수록 커밋 히스토리가 뒤쳐진다 +그림 3-18. 안정적인 브랜치일수록 커밋 히스토리가 뒤쳐진다 실험실에서 충분히 테스트하고 실전에 배치하는 과정으로 보면 이해하기 쉽다(그림 3-19). Insert 18333fig0319.png -그림 3-19 각 브랜치를 하나의 실험실로 생각하라 +그림 3-19. 각 브랜치를 하나의 실험실로 생각하라 코드를 여러 단계로 나누어 안정성을 높여가며 운영할 수 있다. 큰 규모의 프로젝트라면 proposed 혹은 pu(proposed updates)라는 이름의 브랜치를 두어 next나 master 브랜치에 아직 Merge할 준비가 되지 않은 것을 일단 Merge시킨다. @@ -370,12 +370,12 @@ Insert 18333fig0319.png master 브랜치를 checkout한 상태에서 어떤 작업을 한다고 해보자. 한 이슈를 처리하기 위해서 iss91라는 브랜치를 만들고 해당 작업을 한다. 같은 이슈를 다른 방법으로 해결해보고 싶을 때도 있다. iss91v2라는 브랜치를 만들고 다른 방법을 시도해 본다. 확신할 수 없는 아이디어를 적용해보기 위해 다시 master 브랜치로 되돌아가서 dumbidea 브랜치를 하나 더 만든다. 지금까지 말했던 커밋 히스토리는 그림 3-20과 같다. Insert 18333fig0320.png -그림 3-20 여러 토픽 브랜치에 대한 커밋 히스토리 +그림 3-20. 여러 토픽 브랜치에 대한 커밋 히스토리 이슈를 처리했던 방법 중 두 번째 방법인 iss91v2 브랜치가 괜찮아서 적용하기로 결정을 내렸다. 그리고 아이디어를 확신할 수 없었던 dumbidea 브랜치를 같이 일하는 다른 개발자에게 보여줬더니 썩 괜찮다는 반응을 얻었다. iss91 브랜치는 (C5, C6 커밋도 함께) 버리고 다른 두 브랜치를 Merge하면 그림 3-21과 같이 된다. Insert 18333fig0321.png -그림 3-21 dumbidea와 iss91v2 브랜치를 Merge하고 난 후의 모습 +그림 3-21. dumbidea와 iss91v2 브랜치를 Merge하고 난 후의 모습 지금까지 한 작업은 전부 로컬에서만 처리한다는 것을 꼭 기억하자. 로컬 저장소에서만 브랜치를 만들고 Merge했으며 서버와 통신을 주고받는 일은 없었다. @@ -388,29 +388,29 @@ Insert 18333fig0321.png 다소 헷갈릴 수 있으니 예제를 좀 더 살펴보자. `git.ourcompany.com`이라는 Git 서버가 있고 이 서버의 저장소를 하나 Clone하면 Git은 자동으로 origin이라는 이름을 붙인다. origin으로부터 저장소 데이터를 모두 내려받고 master 브랜치를 가리키는 포인터를 만든다. 이 포인터는 origin/master라고 부르고 멋대로 조종할 수 없다. 그리고 Git은 로컬의 master 브랜치가 origin/master를 가리키게 한다. 이제 이 master 브랜치에서 작업을 시작할 수 있다. Insert 18333fig0322.png -그림 3-22 저장소를 Clone하면 로컬 master 브랜치, 리모트 저장소의 master 브랜치를 가리키는 origin/master 브랜치가 생김 +그림 3-22. 저장소를 Clone하면 로컬 master 브랜치, 리모트 저장소의 master 브랜치를 가리키는 origin/master 브랜치가 생김 로컬 저장소에서 어떤 작업을 하고 있는데 동시에 다른 팀원이 `git.ourcompany.com` 서버에 Push하고 master 브랜치를 업데이트한다. 그러면 이제 팀원 간의 히스토리는 서로 달라진다. 서버 저장소로부터 어떤 데이터도 주고받지 않아서 origin/master 포인터는 그대로다. Insert 18333fig0323.png -그림 3-24 로컬과 서버의 커밋 히스토리는 독립적임 +그림 3-23. 로컬과 서버의 커밋 히스토리는 독립적임 리모트 서버로부터 저장소 정보를 동기화하려면 `git fetch origin` 명령을 사용한다. 명령을 실행하면 우선 origin 서버의 주소 정보(이 예에서는 `git.ourcompany.com`)를 찾아서, 현재 로컬의 저장소가 갖고 있지 않은 새로운 정보가 있으면 모두 내려받고, 받은 데이터를 로컬 저장소에 업데이트하고 나서, origin/master 포인터의 위치를 최신 커밋으로 이동시킨다. Insert 18333fig0324.png -그림 3-24 Git의 Fetch 명령은 리모트 브랜치 정보를 업데이트한다 +그림 3-24. Git의 Fetch 명령은 리모트 브랜치 정보를 업데이트한다 리모트 저장소를 여러 개 운영하는 상황을 이해할 수 있도록 개발용으로 사용할 Git 저장소를 팀 내부에 하나 추가해 보자. 이 저장소의 주소가 `git.team1.ourcompany.com` 이면 *2장*에서 살펴본 `git remote add` 명령으로 현재 작업 중인 프로젝트에 팀의 저장소를 추가한다. 이름을 teamone으로 짓고 긴 서버 주소 대신 사용한다. Insert 18333fig0325.png -그림 3-25 서버를 리모트 저장소로 추가하기 +그림 3-25. 서버를 리모트 저장소로 추가하기 서버를 추가하고 나면 git fetch teamone 명령으로 teamone 서버의 데이터를 내려받는다. 명령을 실행해도 teamone 서버의 데이터는 모두 origin 서버에도 있는 것들이라서 아무것도 내려받지 않는다. 하지만, 이 명령은 teamone/master 브랜치가 teamone 서버의 master 브랜치가 가리키는 커밋을 가리키게 한다. Insert 18333fig0326.png -그림 3-26 로컬 저장소에 만들어진 teamone의 master 브랜치를 가리키는 포인터 +그림 3-26. 로컬 저장소에 만들어진 teamone의 master 브랜치를 가리키는 포인터 ### Push하기 ### @@ -487,12 +487,12 @@ Git에서 한 브랜치에서 다른 브랜치로 합치는 방법은 두 가지 앞의 Merge 절에서 살펴본 예제로 다시 돌아가 보자(그림 3-27). 두 개의 나누어진 브랜치의 모습을 볼 수 있다. Insert 18333fig0327.png -그림 3-27 두 개의 브랜치로 나누어진 커밋 히스토리 +그림 3-27. 두 개의 브랜치로 나누어진 커밋 히스토리 이 두 브랜치를 합치는 가장 쉬운 방법은 앞에서 살펴본 대로 Merge 명령을 사용하는 것이다. 두 브랜치의 마지막 커밋 두 개(C3, C4)와 공통 조상(C2)을 사용하는 3-way Merge로 그림 3-28처럼 새로운 커밋을 만들어 낸다. Insert 18333fig0328.png -그림 3-28 나뉜 브랜치를 Merge하기 +그림 3-28. 나뉜 브랜치를 Merge하기 비슷한 결과를 만드는 다른 방식으로, C3에서 변경된 사항을 패치(Patch)로 만들고 이를 다시 C4에 적용시키는 방법이 있다. Git에서는 이런 방식을 _Rebase_ 라고 한다. Rebase 명령으로 한 브랜치에서 변경된 사항을 다른 브랜치에 적용할 수 있다. @@ -506,12 +506,12 @@ Insert 18333fig0328.png 실제로 일어나는 일을 설명하자면 일단 두 브랜치가 나뉘기 전인 공통 커밋으로 이동하고 나서 그 커밋부터 지금 Checkout한 브랜치가 가리키는 커밋까지 diff를 차례로 만들어 어딘가에 임시로 저장해 놓는다. Rebase할 브랜치(역주 - experiment)가 합칠 브랜치(역주 - master)가 가리키는 커밋을 가리키게 하고 아까 저장해 놓았던 변경사항을 차례대로 적용한다. 그림 3-29는 이러한 과정을 나타내고 있다. Insert 18333fig0329.png -그림 3-29 C3의 변경사항을 C4에 적용하는 Rebase 과정 +그림 3-29. C3의 변경사항을 C4에 적용하는 Rebase 과정 그리고 나서 master 브랜치를 Fast-forward 시킨다. Insert 18333fig0330.png -그림 3-30 master 브랜치를 Fast-forward시키기 +그림 3-30. master 브랜치를 Fast-forward시키기 C3'로 표시된 커밋에서의 내용은 Merge 예제에서 살펴본 C5 커밋에서의 내용과 같을 것이다. Merge이든 Rebase든 둘 다 합치는 관점에서는 서로 다를 게 없다. 하지만, Rebase가 좀 더 깨끗한 히스토리를 만든다. Rebase한 브랜치의 Log를 살펴보면 히스토리가 선형적이다. 일을 병렬로 동시에 진행해도 Rebase하고 나면 모든 작업이 차례대로 수행된 것처럼 보인다. @@ -524,7 +524,7 @@ Rebase를 하든지, Merge를 하든지 최종 결과물은 같고 커밋 히스 Rebase는 단순히 브랜치를 합치는 것만 아니라 다른 용도로도 사용할 수 있다. 그림 3-31과 같은 히스토리가 있다고 하자. server 브랜치를 만들어서 서버 기능을 추가하고 그 브랜치에서 다시 client 브랜치를 만들어 클라이언트 기능을 추가한다. 마지막으로 server 브랜치로 돌아가서 몇 가지 기능을 더 추가한다. Insert 18333fig0331.png -그림 3-31 다른 토픽 브랜치에서 갈라져 나온 토픽 브랜치 +그림 3-31. 다른 토픽 브랜치에서 갈라져 나온 토픽 브랜치 이때 테스트가 덜 된 server 브랜치는 그대로 두고 client 브랜치만 master로 합치려는 상황을 생각해보자. server와는 아무 관련이 없는 client 커밋은 C8, C9이다. 이 두 커밋을 master 브랜치에 적용하기 위해서 `--onto` 옵션을 사용하여 아래와 같은 명령을 실행한다: @@ -533,7 +533,7 @@ Insert 18333fig0331.png 이 명령은 client 브랜치를 Checkout하고 server와 client의 공통조상 이후의 패치를 만들어 master에 적용한다. 조금 복잡하긴 해도 꽤 쓸모 있다. 그림 3-32를 보자. Insert 18333fig0332.png -그림 3-32 다른 토픽 브랜치에서 갈라져 나온 토픽 브랜치를 Rebase하기 +그림 3-32. 다른 토픽 브랜치에서 갈라져 나온 토픽 브랜치를 Rebase하기 이제 master 브랜치로 돌아가서 Fast-forward 시킬 수 있다: @@ -541,7 +541,7 @@ Insert 18333fig0332.png $ git merge client Insert 18333fig0333.png -그림 3-33 master 브랜치를 client 브랜치 위치로 진행 시키기 +그림 3-33. master 브랜치를 client 브랜치 위치로 진행 시키기 server 브랜치의 일이 다 끝나면 `git rebase [basebranch] [topicbranch]`라는 명령으로 Checkout하지 않고 바로 server 브랜치를 master 브랜치로 rebase할 수 있다. 이 명령은 토픽(server) 브랜치를 Checkout하고 베이스(master) 브랜치에 Rebase한다: @@ -550,7 +550,7 @@ server 브랜치의 일이 다 끝나면 `git rebase [basebranch] [topicbranch]` server 브랜치의 수정사항을 master 브랜치에 적용했다. 그 결과는 그림 3-34와 같다. Insert 18333fig0334.png -그림 3-34 master 브랜치에 server 브랜치의 수정 사항을 적용 +그림 3-34. master 브랜치에 server 브랜치의 수정 사항을 적용 그리고 나서 master 브랜치를 Fast-forward 시킨다: @@ -563,7 +563,7 @@ Insert 18333fig0334.png $ git branch -d server Insert 18333fig0335.png -그림 3-35 최종 커밋 히스토리 +그림 3-35. 최종 커밋 히스토리 ### Rebase의 위험성 ### @@ -578,22 +578,22 @@ Rebase는 기존의 커밋을 그대로 사용하는 것이 아니라 내용은 이미 공개 저장소에 Push한 커밋을 Rebase하면 어떤 결과가 초래되는지 예제를 통해 알아보자. 중앙 저장소에서 Clone하고 일부 수정을 하면 커밋 히스토리는 그림 3-36과 같아 진다. Insert 18333fig0336.png -그림 3-36 저장소를 Clone하고 일부 수정함 +그림 3-36. 저장소를 Clone하고 일부 수정함 이제 팀원 중 누군가 커밋, Merge하고 나서 서버에 Push 한다. 이 리모트 브랜치를 Fetch, Merge하면 그림 3-37과 같이 된다. Insert 18333fig0337.png -그림 3-37 Fetch한 후 Merge함 +그림 3-37. Fetch한 후 Merge함 그런데 Push했던 팀원은 Merge한 일을 되돌리고 다시 Rebase한다. 서버의 히스토리를 새로 덮어씌우려면 `git push --force` 명령을 사용해야 한다. 이후에 저장소에서 Fetch하고 나면 아래 그림과 같은 상태가 된다: Insert 18333fig0338.png -그림 3-38 한 팀원이 다른 팀원이 의존하는 커밋을 없애고 Rebase한 커밋을 다시 Push함 +그림 3-38. 한 팀원이 다른 팀원이 의존하는 커밋을 없애고 Rebase한 커밋을 다시 Push함 기존 커밋이 사라졌기 때문에 이미 처리한 일이라고 해도 다시 Merge해야 한다. Rebase는 커밋의 SHA-1 해시를 바꾸기 때문에 Git은 새로운 커밋으로 생각한다. 사실 C4는 이미 히스토리에 적용되어 있지만, Git은 모른다. Insert 18333fig0339.png -그림 3-39 같은 Merge를 다시 한다 +그림 3-39. 같은 Merge를 다시 한다 다른 개발자와 계속 같이 일하려면 이런 Merge도 해야만 한다. Merge하면 C4와 C4' 커밋 둘 다 히스토리에 남게 된다. 실제 내용과 메시지가 같지만 SHA-1 해시 값이 전혀 다르다. `git log`로 히스토리를 확인해보면 저자, 커밋 날짜, 메시지가 같은 커밋이 두 개 있을 것이다. 이렇게 되면 혼란스럽다. 게다가 이 히스토리를 서버에 Push하면 같은 커밋이 두 개 있기 때문에 다른 사람들도 혼란스러워한다. diff --git a/ko/04-git-server/01-chapter4.markdown b/ko/04-git-server/01-chapter4.markdown index 8ad6b1c68..2755518da 100644 --- a/ko/04-git-server/01-chapter4.markdown +++ b/ko/04-git-server/01-chapter4.markdown @@ -312,7 +312,7 @@ Apache를 재시작하면 아래와 같은 URL로 저장소를 Clone할 수 있 프로젝트 저장소를 단순히 읽거나 쓰는 것에 대한 설정은 다뤘다. 이제는 웹 기반 인터페이스를 설정해보자. Git에는 GitWeb이라는 CGI 스크립트를 제공해서 쉽게 웹에서 저장소를 조회하도록 할 수 있다. `http://git.kernel.org`같은 사이트에서 GitWeb을 구경할 수 있다(그림 4-1). Insert 18333fig0401.png -그림 4-1 Git 웹용 UI, GitWeb +그림 4-1. Git 웹용 UI, GitWeb Git은 GitWeb을 쉽게 사용해 볼 수 있도록 서버를 잠시 띄우는 명령을 제공한다. 시스템에 `lighttpd`나 `webrick` 같은 경량 웹서버가 설치돼 있어야 이 명령을 사용할 수 있다. 리눅스에서는 `lighttpd`가 설치돼 있을 확률이 높고 프로젝트 디렉토리에서 그냥 `git instaweb`을 실행하면 바로 실행된다. Mac의 Leopard 버전은 Ruby가 미리 설치돼 있기 때문에 `webrick`이 더 낫다. lighttpd이 아니라면 아래와 같이 `--httpd` 옵션을 사용해야 한다: @@ -734,17 +734,17 @@ GitHub은 이윤을 목적으로 하는 회사이기 때문에 비공개 저장 먼저 무료 계정을 하나 만든다. 가격 정책에 대해 알려주며 가입을 시작할 수 있는 `http://github.com/plans`에 방문하여 "Sign up" 버튼을 클릭한다. 그러면 가입 페이지로 이동한다. Insert 18333fig0402.png -그림 4-2 GitHub 가격 정책 페이지 +그림 4-2. GitHub 가격 정책 페이지 아직 등록되지 않은 사용자 이름을 입력하고 e-mail 주소와 암호를 입력한다(그림 4-3). Insert 18333fig0403.png -그림 4-3 GitHub 가입 폼 +그림 4-3. GitHub 가입 폼 그리고 SSH 공개키가 있으면 바로 등록한다. SSH 키를 만드는 방법은 "바로 설정하기" 절에서 이미 설명했다. 그 공개키 파일의 내용을 복사해서 SSH 공개키 입력 박스에 붙여 넣는다. "explain ssh keys" 링크를 클릭하면 key를 생성하는 방법을 자세히 설명해준다. 주요 운영체제에서 하는 방법이 모두 설명돼 있다. "I agree, sign me up" 버튼을 클릭하면 자신만의 대쉬보드 페이지가 나타난다. Insert 18333fig0404.png -그림 4-4 GitHub 사용자 대쉬보드 +그림 4-4. GitHub 사용자 대쉬보드 그리고 저장소를 만들자. @@ -753,17 +753,17 @@ Insert 18333fig0404.png `Your Repositories`옆에 있는 "create a new one" 링크를 클릭하면 저장소를 만드는 입력 폼을 볼 수 있다(그림 4-5). Insert 18333fig0405.png -그림 4-5 GitHub의 저장소를 생성하는 폼 +그림 4-5. GitHub의 저장소를 생성하는 폼 이 폼에 프로젝트 이름과 프로젝트 설명을 적는다. 다 적은 후에 "Create Repository" 버튼을 클릭하면 GitHub에 저장소가 생긴다. Insert 18333fig0406.png -그림 4-6 GitHub 프로젝트 정보 +그림 4-6. GitHub 프로젝트 정보 이 저장소에는 아직 코드가 없어서 GitHub은 프로젝트를 새로 만드는 방법, 이미 있는 Git 프로젝트를 Push하는 법, 공개된 Subversion 저장소에서 프로젝트를 가져오는(Import) 방법 등을 보여준다. Insert 18333fig0407.png -그림 4-7 새 저장소를 위한 사용설명서 +그림 4-7. 새 저장소를 위한 사용설명서 여기 설명하는 내용은 이미 우리가 배웠다. 프로젝트가 없을 때는 아래와 같이 프로젝트를 초기화한다: @@ -779,7 +779,7 @@ Insert 18333fig0407.png 이제 프로젝트가 GitHub에서 서비스되니 공유하고 싶은 사람에게 URL을 알려 주면 된다. URL은 `http://github.com/testinguser/iphone_project`이다. 그리고 이 저장소의 정보를 잘 살펴보면 Git URL이 두 개라는 것을 발견할 수 있다. Insert 18333fig0408.png -그림 4-8 프로젝트의 공개 URL과 비공개 URL +그림 4-8. 프로젝트의 공개 URL과 비공개 URL `Public Clone URL`은 말 그대로 누구나 프로젝트를 Clone할 수 있도록 모두에게 읽기 전용으로 공개하는 것이다. 이 URL을 다른 사람에 알려주거나 웹사이트 같은데 공개하는 것을 부담스러워 하지 않아도 된다. @@ -790,7 +790,7 @@ Insert 18333fig0408.png GitHub은 공개 중인 Subversion 프로젝트를 Git 프로젝트로 만들어 준다. 사용설명서 하단에 있는 "Subversion에서 Import하기" 링크를 클릭하면 임포트 폼을 볼 수 있고 거기에 Subversion 프로젝트의 URL을 넣는다(그림 4-9). Insert 18333fig0409.png -그림 4-9 Subversion 프로젝트를 Import하는 화면 +그림 4-9. Subversion 프로젝트를 Import하는 화면 프로젝트가 비표준 방식을 사용하거나 규모가 너무 크고 비공개라면 이 기능을 사용할 수 없다. *7장*에서 수동으로 임포트하는 방법에 대해 좀 더 자세히 배운다. @@ -801,17 +801,17 @@ Insert 18333fig0409.png 프로젝트 페이지에 있는 Admin 버튼을 클릭해서 관리 페이지로 이동한다(그림 4-10). Insert 18333fig0410.png -그림 4-10 GitHub의 프로젝트 관리 페이지 +그림 4-10. GitHub의 프로젝트 관리 페이지 다른 사람에게 쓰기 권한을 주려면 “Add another collaborator” 링크를 클릭한다. 그러면 텍스트 박스가 새로 나타나는 데 거기에 사용자 이름을 입력한다. 사용자 이름을 입력하기 시작하면 자동으로 시스템에 존재하는 사용자를 찾아서 보여 준다. 원하는 사용자를 찾으면 Add 버튼을 클릭해서 그 사용자를 동료로 만든다. Insert 18333fig0411.png -그림 4-11 프로젝트에 동료 추가하기 +그림 4-11. 프로젝트에 동료 추가하기 추가한 사람은 동료 목록 박스에서 모두 확인할 수 있다(그림 4-12). Insert 18333fig0412.png -그림 4-12 프로젝트 동료들 +그림 4-12. 프로젝트 동료들 그리고 만약 다시 혼자 작업하고 싶어지면 "revoke" 링크를 클릭하여 쫓아낸다. 쫓겨나면 더는 Push할 수 없다. 또 기존 프로젝트에 등록된 동료를 그룹으로 묶어 추가할 수도 있다. @@ -820,7 +820,7 @@ Insert 18333fig0412.png Subversion에서 Import했거나 로컬의 프로젝트를 Push하고 나면 프로젝트 메인 페이지가 그림 4-13같이 바뀐다. Insert 18333fig0413.png -그림 4-13 GitHub의 프로젝트 메인 페이지 +그림 4-13. GitHub의 프로젝트 메인 페이지 사람들이 이 프로젝트에 방문하면 이 페이지가 제일 처음 보인다. 이 페이지는 몇 가지 탭으로 구성된다. Commits 탭은 지금까지의 커밋을 `git log` 명령을 실행시킨 것처럼 최신 것부터 보여준다. Network 탭은 프로젝트를 복제한 사람들과 기여한 사람들을 모두 보여준다. Downloads 탭에는 바이너리 파일이나 프로젝트의 태그 버전을 압축해서 올릴 수 있다. Wiki 탭은 프로젝트에 대한 정보나 문서를 쓰는 곳이다. Graphs 탭은 사람들의 활동을 그림과 통계로 보여준다. 메인 탭인 Source 탭은 프로젝트의 메인 디렉토리를 보여주고 README 파일이 있으면 자동으로 화면에 출력해 준다. 그리고 마지막 커밋 내용도 함께 보여준다. @@ -833,12 +833,12 @@ Insert 18333fig0413.png 프로젝트 페이지에 들어가서 상단의 "fork" 버튼을 클릭하여 프로젝트를 복제한다(그림 4-14) 그림 4-14의 예는 mojombo/chronic 프로젝트 페이지이다 Insert 18333fig0414.png -그림 4-14 어떤 저장소든지 "fork" 버튼을 클릭하면 Push할 수 있는 저장소를 얻을 수 있다 +그림 4-14. 어떤 저장소든지 "fork" 버튼을 클릭하면 Push할 수 있는 저장소를 얻을 수 있다 클릭하는 순간, 이 프로젝트를 즉시 Fork한다(그림 4-15). Insert 18333fig0415.png -그림 4-15 Fork한 프로젝트 +그림 4-15. Fork한 프로젝트 ### GitHub 요약 ### diff --git a/ko/05-distributed-git/01-chapter5.markdown b/ko/05-distributed-git/01-chapter5.markdown index d8f7dda7c..c1ea7508a 100644 --- a/ko/05-distributed-git/01-chapter5.markdown +++ b/ko/05-distributed-git/01-chapter5.markdown @@ -13,7 +13,7 @@ 중앙집중식 시스템에서는 보통 중앙집중식 협업 모델이라는 한 가지 방식밖에 없다. 중앙 저장소는 딱 하나 있고 변경 사항은 모두 이 중앙 저장소에 집중된다. 개발자는 이 중앙 저장소를 중심으로 작업한다(그림 5-1). Insert 18333fig0501.png -그림 5-1 중앙집중식 Workflow +그림 5-1. 중앙집중식 Workflow 중앙집중식에서 개발자 두 명이 중앙저장소를 Clone하고 각자 수정하는 상황을 생각해보자. 한 개발자가 자신이 한 일을 커밋하고 나서 아무 문제 없이 서버에 Push한다. 그러면 다른 개발자는 자신의 일을 커밋하고 Push하기 전에 첫 번째 개발자가 한 일을 먼저 Merge해야 한다. Merge를 해야 첫 번째 개발자가 작업한 내용을 덮어쓰지 않는다. 이런 개념은 Subversion과 같은 중앙집중식 버전 관리 시스템에서 사용하는 방식이고 Git에서도 당연히 이런 Workflow를 사용할 수 있다. @@ -31,7 +31,7 @@ Git을 사용하면 리모트 저장소를 여러 개 운영할 수 있다. 다 6. Integration-Manager는 Merge한 사항을 메인 저장소에 Push한다. Insert 18333fig0502.png -그림 5-2 Integration-Manager Workflow +그림 5-2. Integration-Manager Workflow 이 방식은 GitHub 같은 사이트에서 주로 사용하는 방식이다. GitHub는 프로젝트를 Fork하고 수정사항을 반영하여 다시 모두에게 공개하기 좋은 구조로 되어 있다. 이 방식의 장점은 기여자와 Integration-Manager가 각자의 사정에 맞춰 프로젝트를 유지할 수 있다는 점이다. 기여자는 자신의 저장소와 브랜치에서 수정 작업을 계속해 나갈 수 있고 수정사항이 프로젝트에 반영되도록 기다릴 필요가 없다. 관리자는 여유를 가지고 기여자가 Push해 놓은 커밋을 적절한 시점에 Merge한다. @@ -45,7 +45,7 @@ Insert 18333fig0502.png 4. Dictator는 Merge한 자신의 master 브랜치를 Push하여 다른 모든 개발자가 Rebase할 수 있는 기준으로 만든다. Insert 18333fig0503.png -그림 5-3 Benevolent dictator Workflow +그림 5-3. Benevolent dictator Workflow 이 방식이 일반적이지 않지만 깊은 계층 구조를 가지는 환경이나 규모가 큰 프로젝트에서는 매우 쓸모 있다. 프로젝트 리더가 모든 코드를 통합하기 전에 코드를 부분부분 통합하도록 여러 명의 Lieutenant에게 위임한다. @@ -157,7 +157,7 @@ Jessica씨의 Push는 성공했지만, John씨의 커밋은 서버에서 거절 Fetch하고 나면 John씨의 로컬 저장소는 그림 5-4와 같이 된다. Insert 18333fig0504.png -그림 5-4 Fetch하고 난 John씨의 저장소 +그림 5-4. Fetch하고 난 John씨의 저장소 John씨는 Jessica씨가 저장소로 Push했던 커밋과 를 로컬 저장소에 가져왔다. 하지만, Push하기 전에 Fetch한 브랜치를 Merge해야 한다: @@ -169,7 +169,7 @@ John씨는 Jessica씨가 저장소로 Push했던 커밋과 를 로컬 저장소 Merge가 잘 이루어지면 John씨의 브랜치는 그림 5-5와 같은 상태가 된다. Insert 18333fig0505.png -그림 5-5 origin/master 브랜치를 Merge하고 난 후, John씨의 저장소 +그림 5-5. origin/master 브랜치를 Merge하고 난 후, John씨의 저장소 John씨는 Merge하고 나서 자신이 작업한 코드가 제대로 동작하는지 확인한다. 그 후에 공유하는 저장소에 Push한다: @@ -181,12 +181,12 @@ John씨는 Merge하고 나서 자신이 작업한 코드가 제대로 동작하 이제 John씨의 저장소는 그림 5-6 처럼 되었다. Insert 18333fig0506.png -그림 5-6 Push하고 난 후, John씨의 저장소 +그림 5-6. Push하고 난 후, John씨의 저장소 동시에 Jessica씨는 토픽 브랜치를 하나 만든다. issue54 브랜치를 만들고 세 번에 걸쳐서 커밋한다. 아직 John씨의 커밋을 Fetch하지 않은 상황이기 때문에 그림 5-7과 같은 상황이 된다. Insert 18333fig0507.png -그림 5-7 Jessica씨의 저장소 +그림 5-7. Jessica씨의 저장소 Jessica씨는 John씨의 작업을 적용하려면 Fetch를 해야 한다: @@ -199,7 +199,7 @@ Jessica씨는 John씨의 작업을 적용하려면 Fetch를 해야 한다: 위 명령으로 John씨가 Push한 커밋을 모두 내려받는다. 그러면 Jessica씨의 저장소는 그림 5-8과 같은 상태가 된다. Insert 18333fig0508.png -그림 5-8 John씨의 커밋을 Fetch한 후 Jessica씨의 저장소 +그림 5-8. John씨의 커밋을 Fetch한 후 Jessica씨의 저장소 이제 orgin/master와 Merge할 차례다. Jessica씨는 토픽 브랜치 작업을 마치고 어떤 내용이 Merge되는지 `git log` 명령으로 확인한다: @@ -236,7 +236,7 @@ origin/master, issue54 모두 master보다 Fast-forward된 브랜치이기 때 위와 같이 Merge가 잘 되면 그림 5-9와 같은 상태가 된다. Insert 18333fig0509.png -그림 5-9 Merge 이후 Jessica씨의 저장소 +그림 5-9. Merge 이후 Jessica씨의 저장소 origin/master 브랜치가 Jessica씨의 master 브랜치로 나아갈(reachable) 수 있기 때문에 Push는 성공한다(물론 John씨가 그 사이에 Push를 하지 않았다면): @@ -248,12 +248,12 @@ origin/master 브랜치가 Jessica씨의 master 브랜치로 나아갈(reachable 두 개발자의 커밋과 Merge가 성공적으로 이루어지고 난 후의 결과는 5-10과 같다. Insert 18333fig0510.png -그림 5-10 Jessica씨가 서버로 Push하고 난 후의 저장소 +그림 5-10. Jessica씨가 서버로 Push하고 난 후의 저장소 여기서 살펴본 예제가 가장 간단한 상황이다. 토픽 브랜치에서 수정하고 로컬의 master 브랜치에 Merge한다. 작업한 내용을 프로젝트의 공유 저장소에 Push하고자 할 때에는 우선 origin/master 브랜치를 Fetch하고 Merge한다. 그리고 나서 Merge한 결과를 다시 서버로 Push한다. 이런 Workflow가 일반적이고 그림 5-11로 나타낼 수 있다. Insert 18333fig0511.png -그림 5-11 여러 개발자가 Git을 사용하는 Workflow +그림 5-11. 여러 개발자가 Git을 사용하는 Workflow ### 비공개 대규모 팀 ### @@ -299,7 +299,7 @@ Jessica씨는 자신이 한 일을 featureA라는 브랜치로 Push했다는 이 그럼 Jessica씨의 저장소는 그림 5-12과 같다. Insert 18333fig0512.png -그림 5-12 Jessica씨의 저장소 +그림 5-12. Jessica씨의 저장소 작업을 마치고 Push하려고 하는데 Jesie씨가 이미 일부 작업을 하고 서버에 featureBee 브랜치로 Push했다는 이메일을 보내왔다. Jessica씨는 Jesie씨의 작업을 먼저 Merge해야만 Push할 수 있다. Merge하기 위해서 우선 `git fetch`로 Fetch한다: @@ -364,17 +364,17 @@ Jessica씨는 일부 수정하고, 수정한 내용을 다시 서버로 Push한 위와 같은 작업을 마치고 나면 Jessica씨의 저장소는 그림 5-13과 같은 모습이 된다. Insert 18333fig0513.png -그림 5-13 마지막 Push하고 난 후의 Jessica씨의 저장소 +그림 5-13. 마지막 Push하고 난 후의 Jessica씨의 저장소 그럼 featureA와 featureBee 브랜치가 프로젝트의 메인 브랜치로 Merge할 준비가 되었다고 Integration-Manager에게 알려준다. Integration-Manager가 두 브랜치를 모두 Merge하고 난 후에 메인 브랜치를 Fetch하면 그림 5-14와 같은 모양이 된다. Insert 18333fig0514.png -그림 5-14 두 브랜치가 메인 브랜치에 Merge된 후의 저장소 +그림 5-14. 두 브랜치가 메인 브랜치에 Merge된 후의 저장소 수많은 팀의 작업을 동시에 진행하고 나중에 Merge하는 기능을 사용하려고 다른 버전 관리 시스템에서 Git으로 바꾸는 조직들이 많아지고 있다. 팀은 자신의 브랜치로 작업하지만, 메인 브랜치에 영향을 끼치지 않는다는 점이 Git의 장점이다. 그림 5-15는 이런 Workflow을 나타내고 있다. Insert 18333fig0515.png -그림 5-15 대규모 팀의 Workflow +그림 5-15. 대규모 팀의 Workflow ### 공개 소규모 팀 ### @@ -434,7 +434,7 @@ request-pull 명령은 아규먼트를 두 개 입력받는다. 첫 번째 아 그림 5-16 처럼 각 토픽은 일종의 실험실이라고 할 수 있다. 각 토픽은 서로 방해하지 않고 독립적으로 수정하고 Rebase할 수 있다: Insert 18333fig0516.png -그림 5-16 featureB 수정작업이 끝난 직후 저장소의 모습 +그림 5-16. featureB 수정작업이 끝난 직후 저장소의 모습 프로젝트 관리자가 사람들의 수정사항을 Merge하고 나서 Jessica씨의 브랜치를 Merge하려고 할 때 충돌이 날 수도 있다. 그러면 Jessica씨가 자신의 브랜치를 origin/master에 Rebase해서 충돌을 해결하고 다시 Pull Request을 보낸다: @@ -445,7 +445,7 @@ Insert 18333fig0516.png 위 명령들을 실행하고 나면 그림 5-17과 같아진다. Insert 18333fig0517.png -그림 5-17 FeatureA에 대한 Rebase가 적용된 후의 모습 +그림 5-17. FeatureA에 대한 Rebase가 적용된 후의 모습 브랜치를 Rebase해 버렸기 때문에 Push할 때 -f 옵션을 주고 강제로 기존에 서버에 있던 브랜치의 내용을 덮어 써야 한다. 아니면 새로운 브랜치를(예를 들어 featureAv2) 서버에 Push해도 된다. @@ -462,7 +462,7 @@ Insert 18333fig0517.png 수정을 마치면 관리자에게 featureBv2 브랜치를 확인해 보라고 메시지를 보낸다 (그림 5-18 참고). Insert 18333fig0518.png -그림 5-18 featureBv2 브랜치를 커밋한 이후 저장소 모습 +그림 5-18. featureBv2 브랜치를 커밋한 이후 저장소 모습 ### 대규모 공개 프로젝트 ### @@ -755,23 +755,23 @@ master 브랜치가 가리키는 커밋이 토픽 브랜치의 조상이라면 바로 master 브랜치에 Merge하는 것이 가장 간단하다. 이 Workflow에서는 master 브랜치가 안전한 코드라고 가정한다. 토픽 브랜치를 검증하고 master 브랜치로 Merge할 때마다 토픽 브랜치를 삭제한다. 그림 5-19처럼 `ruby_client` 브랜치와 `php_client` 브랜치가 있을 때 `ruby_client` 브랜치를 master 브랜치로 Merge한 후 `php_client` 브랜치를 Merge하면 그림 5-20과 같아진다: Insert 18333fig0519.png -그림 5-19 저장소의 두 브랜치 +그림 5-19. 저장소의 두 브랜치 Insert 18333fig0520.png -그림 5-20 Merge한 후의 저장소 +그림 5-20. Merge한 후의 저장소 이 Workflow은 간단하지만, 프로젝트의 규모가 커지면 문제가 생길 수 있다. 개발자가 많고 규모가 큰 프로젝트에서는 두 단계로 Merge하는 것이 좋다. 그래서 Long-Running 브랜치를 두 개로 유지해야 한다. master 브랜치는 아주 안정적인 버전을 릴리즈하기 위해서 사용한다. develop 브랜치는 새로 수정된 코드를 통합할 때 사용한다. 그리고 두 브랜치를 모두 저장소에 Push한다. 우선 develop 브랜치에 토픽 브랜치(그림 5-21)를 그림 5-22과 같이 Merge한다. 그 후에 릴리즈해도 될만한 수준이 되면 master 브랜치를 develop 브랜치까지 Fast-forward시킨다(그림 5-23). Insert 18333fig0521.png -그림 5-21 토픽 브랜치를 Merge하기 전 +그림 5-21. 토픽 브랜치를 Merge하기 전 Insert 18333fig0522.png -그림 5-22 토픽 브랜치를 Merge한 후 +그림 5-22. 토픽 브랜치를 Merge한 후 Insert 18333fig0523.png -그림 5-23 토픽 브랜치를 릴리즈한 후 +그림 5-23. 토픽 브랜치를 릴리즈한 후 이 Workflow을 사용하면 프로젝트 저장소를 Clone하고 나서 개발자가 안정 버전이 필요하면 master 브랜치를 빌드하고 안정적이지 않더라도 좀 더 최신 버전이 필요하면 develop 브랜치를 Checkout하여 빌드한다. 이 개념을 좀 더 확장해서 사용할 수 있다. 토픽 브랜치를 검증하기 위한 integrate 브랜치를 만들어 Merge하고 토픽 브랜치가 검증되면 develop 브랜치에 머지한다. 그리고 develop 브랜치에서 충분히 안정하다는 것이 증명되면 그때 master 브랜치에 Merge한다. @@ -780,12 +780,12 @@ Insert 18333fig0523.png Git을 개발하는 프로젝트는 Long-Running의 브랜치를 4개 운영한다. 각 브랜치 이름은 master, next, pu (Proposed Updates), maint 이다. maint는 마지막으로 릴리즈한 버전을 지원하는 브랜치다. 기여자가 새로운 기능을 제안하면 관리자는 그림 5-24처럼 자신의 저장소에 토픽 브랜치를 만들어 관리한다. 그리고 토픽에 부족한 점은 없는지, 안정적인지 계속 테스트한다. 안정화되면 next로 Merge하고 저장소에 Push한다. 그러면 모두가 잘 통합됐는지 확인할 수 있다. Insert 18333fig0524.png -그림 5-24 토픽 브랜치를 동시에 여러 개 관리하는 것은 복잡하다 +그림 5-24. 토픽 브랜치를 동시에 여러 개 관리하는 것은 복잡하다 토픽 브랜치가 좀 더 개선돼야 하면 next가 아니라 pu에 Merge한다. 그 후에 충분히 검증을 마치면 pu에서 next로 옮기고 next를 기반으로 pu를 다시 만든다. next에는 아직 master에 넣기에 모자라 보이는 것들이 들어 있다. 즉 next 브랜치는 정말 가끔 Rebase하고 pu는 자주 Rebase하지만 master는 항상 Fast-forward한다(그림 5-25). Insert 18333fig0525.png -그림 5-25 토픽 브랜치를 Long-Running 브랜치로 Merge하기 +그림 5-25. 토픽 브랜치를 Long-Running 브랜치로 Merge하기 토픽 브랜치가 결국 master 브랜치로 Merge되면 저장소에서 삭제한다. 그리고 이전 릴리즈 버전에 Patch가 필요하면 maint 브랜치를 이용해 대응한다. Git을 개발하는 프로젝트를 Clone하면 브랜치가 4개 있고 각 브랜치를 이용하여 진행사항을 확인해볼 수 있다. 그래서 새로운 기능을 추가하려면 적당한 브랜치를 보고 고른다. 이 Workflow는 잘 구조화돼 있어서 코드가 새로 추가돼도 테스트하기 쉽다. @@ -796,7 +796,7 @@ Insert 18333fig0525.png 한 브랜치에서 다른 브랜치로 작업한 내용을 옮기는 또 다른 방식으로 Cherry-pick이란 것도 있다. Git의 Cherry-pick은 커밋 하나만 Rebase하는 것이다. 커밋 하나로 Patch 내용을 만들어 현재 브랜치에 적용을 하는 것이다. 토픽 브랜치에 있는 커밋중에서 하나만 고르거나 토픽 브랜치에 커밋이 하나밖에 없을 때 Rebase보다 유용하다. 그림 5-26의 예를 들어보자. Insert 18333fig0526.png -그림 5-26 Cherry-pick을 실행하기 전의 저장소 +그림 5-26. Cherry-pick을 실행하기 전의 저장소 e43a6 커밋 하나만 현재 브랜치에 적용하려면 아래와 같은 명령을 실행한다: @@ -808,7 +808,7 @@ e43a6 커밋 하나만 현재 브랜치에 적용하려면 아래와 같은 명 위 명령을 실행하면 e43a6 커밋에서 변경된 내용을 현재 브랜치에 똑같이 적용을 한다. 하지만, 변경을 적용한 시점이 다르므로 새 커밋의 SHA-1 해시 값은 달라진다. 명령을 실행하고 나면 그림 5-27과 같이 될 것이다. Insert 18333fig0527.png -그림 5-27 Cherry-pick 방식으로 커밋 하나를 적용한 후의 저장소 +그림 5-27. Cherry-pick 방식으로 커밋 하나를 적용한 후의 저장소 Rebase나 Cherry-pick 방식으로 토픽 브랜치를 합치고 나면 필요없는 토픽 브랜치나 커밋은 삭제한다. diff --git a/ko/06-git-tools/01-chapter6.markdown b/ko/06-git-tools/01-chapter6.markdown index d10b446d7..1af11f6b2 100644 --- a/ko/06-git-tools/01-chapter6.markdown +++ b/ko/06-git-tools/01-chapter6.markdown @@ -190,7 +190,7 @@ reflog의 일은 모두 로컬의 일이기 때문에 내 reflog가 동료의 범위를 표현하는 문법으로 Double Dot(..)을 많이 쓴다. Double Dot은 한쪽에는 있고 다른 쪽에는 없는 커밋이 무엇인지 Git에게 물어보는 것이다. 예들 들어 그림 6-1과 같은 커밋 히스토리가 있다고 가정하자. Insert 18333fig0601.png -그림 6-1 범위를 설명하는 데 사용할 예제 +그림 6-1. 범위를 설명하는 데 사용할 예제 experiment 브랜치의 커밋들 중에서 아직 master 브랜치에 Merge하지 않은 것만 보고 싶으면 `master..experiment`라고 사용한다. 이 표현은 "master에는 없지만, experiment에는 있는 커밋"을 의미한다. 여기에서는 설명을 쉽게 하고자 실제 조회 결과가 아니라 그림 6-1의 문자를 사용한다: diff --git a/ko/07-customizing-git/01-chapter7.markdown b/ko/07-customizing-git/01-chapter7.markdown index e93c49a46..8e363021f 100644 --- a/ko/07-customizing-git/01-chapter7.markdown +++ b/ko/07-customizing-git/01-chapter7.markdown @@ -190,7 +190,7 @@ Git config 파일에 이 스크립트를 모두 추가한다. 설정해야 하 diff 결과가 터미널에 출력되는 대신 P4Merge가 실행된다. 그리고 그림 7-1처럼 그 프로그램 안에서 보여준다: Insert 18333fig0701.png -그림 7-1 P4Merge +그림 7-1. P4Merge 브랜치를 Merge할 때 충돌이 나면 `git mergetool` 명령을 실행한다. 이 명령을 실행하면 GUI 도구로 충돌을 해결할 수 있도록 P4Merge를 실행해준다. @@ -454,10 +454,10 @@ Git은 이 파일을 Checkout할 때마다 SHA 값을 삽입해준다: Commit/Checkout할 때 사용하는 필터를 직접 만들어 쓸 수 있다. 방향에 따라 "clean" 필터와 "smudge" 필터라고 부른다. ".gitattributes" 파일에 설정하고 파일 경로마다 다른 필터를 설정할 수 있다. Checkout할 때 파일을 처리하는 것이 "smudge" 필터이고(그림 7-2) 커밋할 때 처리하는 필터가 "clean" 필터이다. 이 필터로 할 수 있는 일은 무궁무진하다. Insert 18333fig0702.png -그림 7-2 "smudge" 필터는 Checkout할 때 실행된다 +그림 7-2. "smudge" 필터는 Checkout할 때 실행된다 Insert 18333fig0703.png -그림 7-3 "clean" 필터는 파일을 Stage할 때 실행된다 +그림 7-3. "clean" 필터는 파일을 Stage할 때 실행된다 커밋하기 전에 `indent` 프로그램으로 C 코드 전부를 필터링하지만 커밋 메시지는 단순한 예제를 보자. `*.c` 파일은 indent 필터를 사용하도록 `.gitattributes` 파일에 설정한다: diff --git a/ko/09-git-internals/01-chapter9.markdown b/ko/09-git-internals/01-chapter9.markdown index 8386c83ea..fcf02085b 100644 --- a/ko/09-git-internals/01-chapter9.markdown +++ b/ko/09-git-internals/01-chapter9.markdown @@ -116,7 +116,7 @@ Git은 Content-addressable 파일시스템이다. 이게 무슨 말이냐 하면 Git이 저장하는 데이터는 대강 그림 9-1과 같다. Insert 18333fig0901.png -그림 9-1 단순화한 Git 데이터 모델 +그림 9-1. 단순화한 Git 데이터 모델 직접 Tree 개체를 만들어 보자. Git은 일반적으로 Staging Area(Index)의 상태대로 Tree 개체를 만들고 기록한다. 그래서 Tree 개체를 만들려면 우선 Staging Area에 파일을 추가해서 Index를 만들어야 한다. 우선 Plumbing 명령어 `update-index`로 `test.txt` 파일만 들어 있는 Index를 만든다. 이 명령어는 파일을 인위적으로 Staging Area에 추가하는 명령다. 아직 Staging Area에 없는 파일이기 때문에 `--add` 옵션을 꼭 줘야 한다(사실 아직 Staging Area도 설정하지 않았다). 그리고 디렉토리에 있는 파일이 아니라 데이터베이스에 있는 파일을 추가하는 것이기 때문에 `--cacheinfo` 옵션이 필요하다. 파일 모드, SHA-1 해시, 파일 이름 정보도 입력한다: @@ -164,7 +164,7 @@ Staging Area를 Tree 개체로 저장할 때는 `write-tree` 명령을 사용한 이 Tree 개체로 워킹 디렉토리를 만들면 파일 두 개와 `bak`이라는 하위 디렉토리가 생긴다. 그리고 `bak` 디렉토리 안에는 test.txt 파일의 처음 버전이 들어 있다. 그림 9-2와 같은 구조로 데이터가 저장된다. Insert 18333fig0902.png -그림 9-2 현재 Git 데이터 구조 +그림 9-2. 현재 Git 데이터 구조 ### 커밋 개체 ### @@ -241,7 +241,7 @@ Insert 18333fig0902.png 내부의 포인터를 따라가면 그림 9-3과 같은 그래프가 그려진다. Insert 18333fig0903.png -그림 9-3 Git 저장소 내의 모든 개체 +그림 9-3. Git 저장소 내의 모든 개체 ### 개체 저장소 ### @@ -326,7 +326,7 @@ Git 브랜치의 역할이 바로 이거다. 브랜치는 어떤 작업들 중 이제 Git 데이터베이스는 그림 9-4처럼 보인다. Insert 18333fig0904.png -그림 9-4 브랜치 레퍼런스가 추가된 Git 데이터베이스 +그림 9-4. 브랜치 레퍼런스가 추가된 Git 데이터베이스 `git branch (branchname)` 명령을 실행하면 Git은 내부적으로 `update-ref` 명령을 실행한다. 입력받은 브랜치 이름과 현 브랜치의 마지막 커밋의 SHA-1 값을 가져다 `update-ref` 명령을 실행한다. From b1229d67970243816611e147f276e8afd0f80ad3 Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 12 Jan 2014 15:02:29 +0100 Subject: [PATCH 079/690] [de] Fix some incorrect comment syntax in german translation - This makes it easier to use tools for automatic merge of original english text to german translation --- de/01-introduction/01-chapter1.markdown | 26 +++--- de/02-git-basics/01-chapter2.markdown | 90 +++++++++---------- de/03-git-branching/01-chapter3.markdown | 28 +++--- de/04-git-server/01-chapter4.markdown | 12 +-- de/05-distributed-git/01-chapter5.markdown | 44 ++++----- de/06-git-tools/01-chapter6.markdown | 12 +-- de/08-git-and-other-scms/01-chapter8.markdown | 4 +- de/09-git-internals/01-chapter9.markdown | 12 +-- 8 files changed, 113 insertions(+), 115 deletions(-) diff --git a/de/01-introduction/01-chapter1.markdown b/de/01-introduction/01-chapter1.markdown index a86cec03a..9e6febd00 100644 --- a/de/01-introduction/01-chapter1.markdown +++ b/de/01-introduction/01-chapter1.markdown @@ -83,11 +83,11 @@ 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, 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: - + + + + + * Geschwindigkeit * Einfaches Design @@ -206,9 +206,9 @@ Die Staging Area ist einfach eine Datei (normalerweise im Git Verzeichnis), in d Der grundlegend Git Arbeitsprozess sieht in etwa so aus: - + + + 1. Du bearbeitest Dateien in Deinem Arbeitsverzeichnis. 2. Du markierst Dateien für den nächsten Commit, indem Du Snapshots zur Staging Area hinzufügst. @@ -330,9 +330,9 @@ Nachdem Du jetzt Git auf Deinem System installiert hast, solltest Du Deine Git K Git umfasst das Werkzeug `git config`, das Dir erlaubt, Konfigurationswerte zu verändern. Auf diese Weise kannst Du anpassen, wie Git aussieht und arbeitet. Diese Werte sind an drei verschiedenen Orten gespeichert: - + + + * Die Datei `/etc/gitconfig` enthält Werte, die für jeden Anwender des Systems und all ihre Projekte gelten. Wenn Du `git config` mit der Option `--system` verwendest, wird diese Datei verwendet. * Die Werte in der Datei `~/.gitconfig` gelten ausschließlich für Dich und all Deine Projekte. Wenn Du `git config` mit der Option `--global` verwendest, wird diese Datei verwendet. @@ -422,8 +422,8 @@ Beispielsweise erhältst Du die Hilfeseite für den `git config` Befehl so: $ git help config - + + 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. diff --git a/de/02-git-basics/01-chapter2.markdown b/de/02-git-basics/01-chapter2.markdown index 7f4598236..e9e64a7bd 100644 --- a/de/02-git-basics/01-chapter2.markdown +++ b/de/02-git-basics/01-chapter2.markdown @@ -227,10 +227,10 @@ Die erste Zeile weist Git an, alle Dateien zu ignorieren, die mit einem `.o` ode Folgende Regeln gelten in einer `.gitignore` Datei: - + + + + * Leere Zeilen oder Zeilen, die mit `#` beginnen, werden ignoriert. * Standard `glob` Muster funktionieren. @@ -386,8 +386,8 @@ und `git diff --cached`, um zu sehen, was für den nächsten Commit vorgesehen i ### Einen Commit erzeugen ### - + + Nachdem Du jetzt alle Änderungen, die Du im nächsten Commit haben willst, in Deiner Staging Area gesammelt hast, kannst Du den Commit anlegen. Denke daran, dass Änderungen, die nicht in der Staging Area sind (also alle Änderungen, die Du vorgenommen hast, seit Du zuletzt `git add` ausgeführt hast), auch nicht in den Commit aufgenommen werden. Sie werden ganz einfach weiterhin als geänderte Dateien im Arbeitsverzeichnis verbleiben. In unserem Beispiel haben wir gesehen, dass alle Änderungen vorgemerkt waren, als wir zuletzt `git status` ausgeführt haben, also können wir den Commit jetzt anlegen. Das geht am einfachsten mit dem Befehl: @@ -644,8 +644,8 @@ Eine sehr nützliche Option ist `-p`. Sie zeigt die Änderungen an, die in einem -end \ No newline at end of file - + + Diese Option zeigt also im Prinzip die gleiche Information wie zuvor, aber zusätzlich zu jedem Eintrag ein Diff. Das ist nützlich, um einen Code Review zu machen oder eben mal eine Reihe von Commits durchzuschauen, die ein Mitarbeiter angelegt hat. Außerdem gibt es verschiedene Optionen, die nützlich sind, um Dinge zusammenzufassen. Beispielsweise kannst Du eine kurze Statistik über jeden Commit mit der Option `--stat` anzeigen lassen: @@ -679,8 +679,8 @@ Diese Option zeigt also im Prinzip die gleiche Information wie zuvor, aber zusä lib/simplegit.rb | 25 +++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 0 deletions(-) - + + Die `--stat` Option zeigt unterhalb jedes Commits eine kurze Statistik über die jeweiligen Änderungen an: welche Dateien geändert wurden und wieviele Zeilen insgesamt hinzugefügt oder entfernt wurden. Eine weitere nützliche Option ist `--pretty`. Diese Option ändert das Format der Ausgabe und es gibt eine Anzahl mitgelieferter Formate. Das `oneline` Format listet jeden Commit in einer einzigen Zeile, was nützlich ist, wenn Du eine große Anzahl von Commits durchsuchen willst. Die `short`, `full` und `fuller` Formate zeigen die Commits in ähnlicher Form an, aber mit jeweils mehr oder weniger Informationen. @@ -702,22 +702,22 @@ Eines der interessantesten Formate ist `format`, das Dir erlaubt, Dein eigenes F Tabelle 2-1 zeigt einige nützliche Optionen, die von `format` akzeptiert werden: - + + + + + + + + + + + + + + + + Option Beschreibung %H Commit Hash @@ -760,17 +760,17 @@ Die `oneline` und `format` Optionen können außerdem zusammen mit einer weitere Das sind nur einige eher simple Format Optionen für die Ausgabe von `git log` – es gibt sehr viel mehr davon. Tabelle 2-2 listet diejenigen Optionen auf, die wir bisher besprochen haben, und einige weitere, die besonders nützlich sind: - + + + + + + + + + + + Option Beschreibung -p Zeigt den Patch, der einem Commit entspricht. @@ -812,12 +812,12 @@ Eine letzte sehr nützliche Option, die von `git log` akzeptiert wird, ist ein P Tabelle 2-3 zeigt die besprochenen und einige weitere, übliche Optionen: - + + + + + + Option Beschreibung -(n) Begrenzt die Ausgabe auf die letzten n commits @@ -981,8 +981,8 @@ Beachte, dass alles was jemals in einem Commit in Git enthalten war, fast immer ## Mit externen Repositorys arbeiten ## - + + Um mit anderen via Git zusammenzuarbeiten, musst Du wissen, wie Du auf externe (engl. „remote“) Repositorys zugreifen kannst. Remote Repositorys sind Versionen Deines Projektes, die im Internet oder irgendwo in einem anderen Netzwerk gespeichert sind. Du kannst mehrere solcher Repositorys haben und Du kannst jedes davon entweder nur lesen oder lesen und schreiben. Mit anderen via Git zusammenzuarbeiten impliziert, solche Repositorys zu verwalten und Daten aus ihnen herunter- oder heraufzuladen, um Deine Arbeit für andere verfügbar zu machen. Um Remote Repositorys zu verwalten, muss man wissen, wie man sie anlegt und wieder entfernt, wenn sie nicht mehr verwendet werden, wie man externe Branches verwalten und nachverfolgen kann, und mehr. In diesem Kapitel werden wir auf diese Aufgaben eingehen. diff --git a/de/03-git-branching/01-chapter3.markdown b/de/03-git-branching/01-chapter3.markdown index c45229239..22945fc2b 100644 --- a/de/03-git-branching/01-chapter3.markdown +++ b/de/03-git-branching/01-chapter3.markdown @@ -27,8 +27,7 @@ Um das zu verdeutlichen, lass uns annehmen, Du hast ein Verzeichnis mit drei Dat $ git add README test.rb LICENSE2 $ git commit -m 'initial commit of my project' - + Wenn Du einen Commit mit dem Kommando `git commit` erstellst, erzeugt Git für jedes Unterverzeichnis eine Prüfsumme (in diesem Fall nur für das Root-Verzeichnis) und speichert diese drei Objekte im Git Repository. Git erzeugt dann ein Commit Objekt, das die Metadaten und den Zeiger zur Wurzel des Projektbaums enthält, um bei Bedarf den Snapshot erneut erzeugen zu können. @@ -140,8 +139,7 @@ Lass uns ein paar Änderungen machen und mit einem Commit festhalten: $ vim test.rb $ git commit -a -m 'made other changes' - + Nun verzweigen sich die Projektverläufe (siehe Abbildung 3-9). Du hast einen Branch erstellt und zu ihm gewechselt, hast ein bisschen gearbeitet, bist zu Deinem Haupt-Zweig zurückgekehrt und hast da was ganz anderes gemacht. Beide Arbeiten existieren vollständig unabhängig voneinander in zwei unterschiedlichen Branches. Du kannst beliebig zwischen den beiden Zweigen wechseln und sie zusammenführen, wenn Du meinst es wäre soweit. Und das alles hast Du mit simplen `branch` und `checkout`-Befehlen vollbracht. @@ -169,9 +167,9 @@ Lass uns mal sehen, warum Du das machen solltest. Lass uns das Ganze an einem Beispiel durchgehen, dessen Workflow zum Thema Branching und Zusammenführen Du im echten Leben verwenden kannst. Folge einfach diesen Schritten: - + + + 1. Arbeite an einer Webseite. 2. Erstell einen Branch für irgendeine neue Geschichte, an der Du arbeitest. @@ -181,10 +179,10 @@ Lass uns das Ganze an einem Beispiel durchgehen, dessen Workflow zum Thema Branc In diesem Augenblick kommt ein Anruf, dass ein kritisches Problem aufgetreten ist und sofort gelöst werden muss. Du machst folgendes: - + + + + 1. Geh zurück zu Deinem „Produktiv“-Zweig. 2. Erstelle eine Branch für den Hotfix. @@ -408,8 +406,8 @@ Das heisst, die Version in HEAD (Deines 'master'-Branches, denn der wurde per 'c please contact us at email.support@github.com - + + Diese Lösung hat von beiden Teilen etwas und ich habe die Zeilen mit `<<<<<<<`, `=======`, und `>>>>>>>` komplett gelöscht. Nachdem Du alle problematischen Bereiche, in allen durch den Konflikt betroffenen Dateien, beseitigt hast, führe einfach `git add` für alle betroffenen Dateien aus und markieren sie damit als bereinigt. Dieses 'staging' der Dateien markiert sie für Git als bereinigt. Wenn Du ein grafischen Tool zur Bereinigung benutzen willst, dann verwende `git mergetool`. Das welches ein passendes grafisches 'merge'-Tool startet und Dich durch die Konfliktbereiche führt: @@ -554,8 +552,8 @@ Es ist leichter sich die verschiedenen Branches als Arbeitsdepots vorzustellen, Insert 18333fig0319.png Abbildung 3-19. Es könnte hilfreich sein, sich die Branches als Depots vorzustellen. - + + Das lässt sich für beliebig viele Stabilitätsabstufungen umsetzen. Manche größeren Projekte haben auch einen `proposed` (Vorgeschlagen) oder `pu` (proposed updates – vorgeschlagene Updates) Zweig mit Branches die vielleicht noch nicht bereit sind in den `next`- oder `master`-Branch integriert zu werden. Die Idee dahinter ist, dass Deine Branches verschiedene Stabilitätsabstufungen repräsentieren. Sobald sie eine stabilere Stufe erreichen, werden sie in den nächsthöheren Branch vereinigt. diff --git a/de/04-git-server/01-chapter4.markdown b/de/04-git-server/01-chapter4.markdown index cb95e87bb..80b14cd2a 100644 --- a/de/04-git-server/01-chapter4.markdown +++ b/de/04-git-server/01-chapter4.markdown @@ -194,8 +194,8 @@ Die Unterseite vom Servieren von Deinem Repository über HTTP ist, dass es recht ## Git auf einen Server bekommen ## - + + Um zunächst einen beliebigen Git Server einzurichten, musst Du ein existierendes Repository in ein neues einfaches Repository exportieren – ein Repository, dass kein Arbeitsverzeichnis enthält. Das ist im Allgemeinen einfach zu erledigen. Um zunächst Dein Repository zu klonen, um ein neues einfaches Repository anzulegen, führst Du den Klonen-Befehl mit der `--bare` Option aus. Per Konvention haben einfache Repository Verzeichnisse die Endung `.git`, wie hier: @@ -285,8 +285,8 @@ Ein anderer Weg ist, einen LDAP-Server zur Authentifizierung zu benutzen oder ei ## Generiere Deinen öffentlichen SSH-Schlüssel ## - + + Darüber hinaus benutzen viele Git-Server öffentliche SSH-Schlüssel zur Authentifizierung. Um einen öffentlichen Schlüssel bereitzustellen muss jeder Benutzer Deines Systems einen solchen Schlüssel generieren, falls sie noch keinen haben. Dieser Prozess ist bei allen Betriebssystemen ähnlich. Als erstes solltest Du überprüfen, ob Du nicht schon einen Schlüssel hast. Standardmäßig werden die SSH-Schlüssel der Benutzer in ihrem `~/.ssh`-Verzeichnis gespeichert. Du kannst einfach überprüfen, ob Du einen Schlüssel hast, indem Du in das Verzeichnis gehst und den Inhalt auflistest: @@ -1130,8 +1130,8 @@ Auf dieser Seite musst Du einen Nutzernamen auswählen, der bisher im System nic Insert 18333fig0403.png Abbildung 4-3. Das Formular für die GitHub Benutzerregistrierung. - + + Wenn Du Deinen öffentlichen SSH Schlüssel zur Hand hast, kannst Du diesen auch gleich bei der Registrierung angeben. Die Vorgehensweise zum Generieren eines Schlüssels haben wir bereits im Kapitel 4.3 besprochen. Du musst den Inhalt der öffentlichen Schlüsseldatei kopieren und in das „SSH Public Key“ Formularfeld einfügen. Wenn Du auf den „explain ssh keys“ Link klickst, erhälst Du detailierte Anweisungen zum Ausführen dieses Vorgangs auf verschiedenen Betriebssystemen. Wenn Du auf den „I agree, sign me up“ Button drückst, landest Du in Deinem neuen Benutzer-Dashboard (siehe Abbildung 4-4). diff --git a/de/05-distributed-git/01-chapter5.markdown b/de/05-distributed-git/01-chapter5.markdown index 404a05c4f..b216da970 100644 --- a/de/05-distributed-git/01-chapter5.markdown +++ b/de/05-distributed-git/01-chapter5.markdown @@ -32,8 +32,8 @@ Bild 5-1. Zentralisierter Workflow Das heißt: wenn zwei Entwickler Code aus dem zentralen Repository abholen und beide Änderungen vornehmen, dann kann der erste Entwickler seine Änderungen ohne Probleme im zentralen Repository abliefern. Der zweite Entwickler muss sie zunächst mit den Änderungen des ersten Entwicklers zusammenführen, damit er dessen Arbeit nicht überschreibt. Dieses Konzept trifft sowohl auf Git als auch auf Subversion (und jedes andere CVCS) zu, und es funktioniert in Git perfekt. - + + In einem kleinen Team oder einem Team, das mit einem zentralisierten Workflow zufrieden ist, kann man diesen Workflow ohne weiteres mit Git realisieren. Man setzt einfach ein einziges Repository auf und gibt jedem im Team Schreibzugriff („push access“). Git sorgt dann dafür, dass niemand die Arbeit von anderen überschreiben kann. Wenn ein Entwickler das Repository klont, Änderungen vornimmt und dann versucht ins zentrale Repository zu pushen, obwohl jemand anders in der Zwischenzeit Änderungen gepusht hat, dann wird der Server das zurückweisen. Dem Entwickler wird dann mitgeteilt, dass er versucht hat, sogeannte „non-fast-forward“ Änderungen hochzuladen und dass er zuvor die Änderungen des anderen Entwicklers herunterladen und mit seinen zusammenführen muss. Viele Leute mögen diesen Arbeitsablauf, weil sie mit dem Paradigma bereits vertraut sind und sich damit wohl fühlen. @@ -45,12 +45,12 @@ In einem kleinen Team oder einem Team, das mit einem zentralisierten Workflow zu Weil Git ermöglicht, eine Vielzahl von externen Repositories zu betreiben, ist es außerdem möglich, einen Arbeitsprozess zu gestalten, in dem jeder Entwickler Schreibzugriff auf sein eigenes öffentliches Repository hat, aber nur Lesezugriff auf die Repositories von allen anderen Beteiligten. In diesem Szenario stellt jedes Repository ein eigenes „offizielles“ Projekt dar. Um zu einem solchen distribuierten Projekt Änderungen beizusteuern, kannst Du einen eigenen, öffentlichen Klon des Projektes anlegen und Deine Änderungen dort publizieren. Anschließend kannst Du den Betreiber des Haupt-Repositories bitten, Deine Änderungen in sein Repository zu übernehmen. Er kann dann Dein Repository als ein externes Repository auf seinem Rechner einrichten, Deine Änderungen lokal testen, sie in einen seiner Branches (z.B. master) mergen und dann in sein öffentliches Repository pushen. Dieser Prozess läuft wie folgt ab (siehe Bild 5-2): - + + + + + + 1. Der Projekt Betreiber pusht in ein öffentliches Repository. 2. Ein Mitarbeiter klont das Repository und nimmt Änderungen daran vor. @@ -75,10 +75,10 @@ Dies ist ein weit verbreiteter Arbeitsablauf wie ihn z.B. auch GitHub ermöglich Dies ist Variante eines Workflows mit zahlreichen Repositories, die normalerweise von sehr großen Projekten mit hunderten von Mitarbeitern verwendet wird. Das bekannteste Beispiel ist wahrscheinlich der Linux Kernel. In diesem Projekt sind zahlreiche Integration Manager, die „Leutnants“, für verschiedene Bereiche des Repositories zuständig. Für sämtliche Leutnants gibt es wiederum einen Integration Manager, der als der „wohlwollende Diktator“ („benevolent dictator“) bezeichnet wird. Das Repository des wohlwollenden Diktators fungiert als das Referenz-Repository aus dem alle Beteiligten ihre eigenen Repositories aktualisieren müssen. Dieser Prozess funktioniert also wie folgt (siehe Bild 5-3) - + + + + 1. Normale Entwickler arbeiten in ihren Arbeitsbranches (xxx) und rebasen (xxx) ihre Änderungen auf der Basis des Master Branches. Der Master Branch ist derjenige des Diktators. 2. Die Leutnants mergen die Arbeitsbranches der Entwickler in ihre Master Branches. @@ -152,8 +152,8 @@ Wenn Du diesen Befehl ausführst, bevor Du einen Commit anlegst, warnt er dich, Versuche außerdem, Deine Änderungen in logisch zusammenhängende Einheiten zu gruppieren. Wenn möglich, versuche Commits möglichst leichtverständlich (xxx) zu gestalten: arbeite nicht ein ganzes Wochenende lang an fünf verschiedenen Problemen und committe sie dann am Montag als einen einzigen, riesigen Commit. Selbst wenn Du am Wochenende keine Commits angelegt hast, verwende die Staging Area, um Deine Änderungen auf mehrere Commits aufzuteilen, jeweils mit einer verständlichen Meldung. Wenn einige Änderungen dieselbe Datei betreffen, probiere sie mit `git add --patch` nur teilweise zur Staging Area hinzuzufügen (das werden wir in Kapitel 6 noch im Detail besprechen). Der Projekt Snapshot wird am Ende derselbe sein, ob Du nun einen einzigen großen oder mehrere kleine Commits anlegst, daher versuche, es anderen Entwickler zu erleichtern machen, Deine Änderungen zu verstehen. Auf diese Weise machst Du es auch einfacher, einzelne Änderungen später herauszunehmen oder rückgängig zu machen. Kapitel 6 beschreibt eine Reihe nützlicher Git Tricks, die hilfreich sind, um die Historie umzuschreiben oder interaktiv Dateien zur Staging Area hinzuzufügen. Verwende diese Hilfsmittel, um eine sauber und leicht verständliche Historie von Änderungen aufzubauen. - + + Ein weitere Sache, der Du ein bisschen 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. @@ -188,8 +188,8 @@ In den folgenden Beispielen hier und fast überall in diesem Buch verwende ich k Das einfachste Setup, mit dem Du zu tun haben wirst, ist ein privates Projekt mit ein oder zwei Entwicklern. Mit „privat“ meine ich, dass es „closed source“, d.h. nicht lesbar für Dritte ist. Alle beteiligten Entwickler haben Schreibzugriff auf das Repository. - + + In einer solchen Umgebung kann man einen ähnlichen Workflow verwenden, wie für Subversion oder ein anderes zentralisiertes System. Du hast dann immer noch Vorteile wie, dass Du offline committen kannst und dass Branching und Merging so unglaublich einfach ist. Der Hauptunterschied ist, dass Merges auf der Client Seite stattfinden und nicht, wenn man committet, auf dem Server. Schauen wir uns an, wie die Arbeit von zwei Entwicklern in einem gemeinsamen Repository abläuft. Der erste Entwickler, John, klont das Repository, nimmt eine Änderung vor und comittet auf seinem Rechner. (Wir kürzen die Beispiele etwas ab und ersetzen die hierfür irrelevanten Protokoll Meldungen mit `xxx`.) @@ -765,8 +765,8 @@ Zunächst musst Du die IMAP Sektion in Deiner `~/.gitconfig` Datei ausfüllen. D port = 993 sslverify = false - + + Wenn Dein IMAP Server kein SSL verwendet, kannst Du die letzten beiden Zeilen wahrscheinlich weglassen und der `host` dürfte mit `imap://` und nicht `imaps://` beginnen. Wenn Du diese Einstellungen konfiguriert hast, kannst Du `git send-email` verwenden, um Deine Patches in den Entwurfsordner des angegebenen IMAP Servers zu kopieren: @@ -818,8 +818,8 @@ Neben dem Wissen, das Du brauchst, um zu einem bestehenden Projekt Änderungen b ### In Topic Branches arbeiten ### - + + Wenn Du Änderungen von anderen übernehmen willst, ist normalerweise eine gute Idee, sie in einem Topic Branch auszuprobieren – d.h., einem temporären Branch, dessen Zweck nur darin besteht, die jeweiligen Änderungen auszuprobieren. Auf diese Weise ist es einfach, Patches ggf. anzupassen oder sie im Zweifelsfall im Topic Branch liegen zu lassen, wenn sie nicht funktionieren und Du im Moment nicht die Zeit hast, Dich weiter damit zu befassen. Es ist empfehlenswert, Topic Branches Namen zu geben, die gut kommunizieren, worum es sich bei den jeweiligen Änderungen dreht, wie z.B. `ruby_client` oder etwas ähnlich aussagekräftiges, das Dir hilft, Dich daran zu erinnern. Der Projekt Betreiber des Git Projektes selbst vergibt Namensräume für solche Branches – wie z.B. `sc/ruby_client`, wobei `sc` ein Kürzel für den jeweiligen Autor des Patches ist. Wie Du inzwischen weißt, kannst Du einen neuen Branch, der auf dem gegenwärtigen `master` Branch basiert, wie folgt erzeugen (xxx falsch, das stimmt nur, wenn `master` der aktuelle Branch ist xxx): @@ -1117,8 +1117,8 @@ Bild 5-22. Nach dem Topic Branch Merge Insert 18333fig0523.png Bild 5-23. Nach dem Topic Branch Release - + + Auf diese Weise kann jeder, der Dein Repository klont, auf einfache Weise Deinen aktuellen `master` Branch verwenden und ihn auf neue Releases aktualisieren. Oder er kann den `develop` Branch ausprobieren, in dem sich die jeweils letzten, brandneuen Änderungen befinden. Du kannst dieses Konzept noch weiterführen, indem Du einen `integrate` Branch pflegst, in den neue Änderungen jeweils integriert werden. Sobald der Code in diesem Branch stabil zu sein scheint und alle Tests durchlaufen (xxx), übernimmst Du die Änderungen in den `develop` Branch. Und wenn sie sich für eine Weile in der Praxis als stabil erwiesen haben, fast-forwardest (xxx) Du den `master` Branch. diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index 032a2ef52..645938ee0 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -286,8 +286,8 @@ Dies ist nützlich, wenn Du vorhast, den `experiment` Branch zu aktualisieren, u $ git log origin/master..HEAD - + + Dieser Befehl zeigt Dir alle Commits im gegenwärtigen, lokalen Branch, die noch nicht im `master` Branch des `origin` Repositories sind. D.h., der Befehl listet diejenigen Commits auf, die auf den Server transferiert würden, wenn Du `git push` benutzt und der aktuelle Branch `origin/master` trackt. Du kannst mit dieser Syntax außerdem eine Seite der beiden Punkte leer lassen. Git nimmt dann an, Du meinst an dieser Stelle HEAD. Z.B. kannst Du dieselben Commits wie im vorherigen Beispiel auch mit `git log origin/master..` anzeigen lassen. Git fügt dann HEAD auf der rechten Seite ein. @@ -316,8 +316,8 @@ Damit hast Du ein sehr mächtiges System von Abfragen zur Verfügung, mit denen #### Drei-Punkte Syntax #### - + + Die letzte wichtige Syntax, mit der man Commit Reihen spezifizieren kann, ist die Drei-Punkte Syntax, die alle Commits anzeigt, die in einer der beiden Referenzen enthalten sind, aber nicht in beiden. Schau Dir noch mal die Commit Historie in Bild 6-1- an. Wenn Du diejenigen Commits anzeigen willst, die in den `master` und `experiment` Branches, nicht aber in beiden Branches gleichzeitig enthalten sind, dann kannst Du folgendes tun: @@ -348,8 +348,8 @@ Mit diesen Hilfsmitteln kannst Du noch einfacher und genauer angeben, welche Com ## Interaktives Stagen ## - + + Git umfasst eine Reihe von Skripten, die so manche Aufgabe auf der Kommandozeile leichter machen. Im folgenden schauen wir uns einige interaktive Befehle an, die dabei hilfreich sein können, wenn man Änderungen in vielen Dateien vorgenommen hat, aber nur einige Änderungen gezielt committen will – nicht alles auf einmal in einem riesigen Commit. Auf diese Weise kann man Commits logisch gruppieren und macht es anderen Entwicklern damit leichter, sie zu verstehen. Wenn Du `git add` mit der `-i` oder `--interactive` Option verwendest, geht Git in einen interaktiven Shell Modus, der in etwa wie folgt aussieht: diff --git a/de/08-git-and-other-scms/01-chapter8.markdown b/de/08-git-and-other-scms/01-chapter8.markdown index f183fdd11..4ae40993d 100644 --- a/de/08-git-and-other-scms/01-chapter8.markdown +++ b/de/08-git-and-other-scms/01-chapter8.markdown @@ -464,8 +464,8 @@ Auf diese Weise müllst Du Dein Projekt nicht mit `.gitignore`-Dateien zu. Das i Die `git svn`-Werkzeuge sind sehr nützlich, wenn Du derzeit (noch) an einen Subversion-Server gebunden bist oder Dich anderweitig in einer Entwicklungsumgebung befindest, die nicht auf einen Subversion-Server verzichten kann. Wie auch immer: Du solltest es als eine Art gestutztes Git ansehen. Anderenfalls läufst Du Gefahr, Dich und Deine Kollegen durcheinander zu bringen. Um dieses Kliff zu umschiffen, solltest Du folgende Richtlinien befolgen: - + + * Versuch, eine „geradlinige“ Git-Historie zu führen, die keine von `git merge` durchgeführten Merges enthält. Alle Arbeiten, die Du außerhalb des Hauptzweiges durchführst, solltest Du mit `rebase` in ihn aufnehmen anstatt sie zu mit `merge` zusammenzuführen. * Setz keinen zusätzlichen, externen Git-Server auf, mit dem Du arbeiten möchtest. Du kannst einen aufsetzen um die Klone für neue Entwickler zu beschleunigen, aber Du solltest keine Änderungen dorthin pushen, die keine `git-svn-id`-Einträge haben. Du solltest vielleicht sogar darüber nachdenken, einen `pre-receive`-Hook einzusetzen, der jede Commit-Nachricht auf eine `git-svn-id` prüft und bestimmte Pushes ablehnt, bei denen diese IDs fehlt. diff --git a/de/09-git-internals/01-chapter9.markdown b/de/09-git-internals/01-chapter9.markdown index e58370210..2b3f3ad99 100644 --- a/de/09-git-internals/01-chapter9.markdown +++ b/de/09-git-internals/01-chapter9.markdown @@ -54,8 +54,8 @@ Damit bleiben vier wichtige Einträge übrig: die Dateien `HEAD` und `index` und ## Git Objekte ## - + + Git ist ein Dateisystem, das Inhalte addressieren kann. Prima. Aber was heißt das? Es bedeutet, dass Git im Kern nichts anderes ist als ein einfacher Key-Value-Store („Schlüssel-Wert-Speicher“). Du kannst darin jede Art von Inhalt ablegen und Git wird einen Schlüssel dafür zurückgeben, den Du dann verwenden kannst, um diesen Inhalt jederzeit nachzuschlagen. Um das auszuprobieren, kannst Du den Plumbing Befehl `hash-object` verwenden. Dieser nimmt einen Inhalt an, speichert ihn in Deinem `.git` Verzeichnis und gibt Dir den Schlüssel zurück, unter dem der Inhalt gespeichert wurde. Dazu initialisierst Du als erstes ein neues Git Repository und verifizierst, dass das `objects` Verzeichnis leer ist: @@ -718,8 +718,8 @@ Außerdem ist toll, dass ein Repository jederzeit neu gepackt werden kann. Git m ## Die Refspec ## - + + In diesem Buch haben wir bisher einfache Mappings von externen Branches auf lokale Referenzen verwendet. Sie können aber auch durchaus komplex sein. Nehmen wir an, Du hast ein externes Repository wie folgt definiert: @@ -1194,8 +1194,8 @@ Es sieht also so aus, als sei der untere Commit derjenige, den Du verloren hast, cac0cab538b970a37ea1e769cbbde608743bc96d second commit fdf4fc3344e67ab068f836878b6c4951e3b15f3d first commit - + + Sehr gut. Du hast jetzt einen neuen Branch `recover-branch`, der diejenigen Commits enthält, die sich zuvor in Deinem `master` Branch befanden. Damit hast Du wieder Zugriff auf die beiden verloren gegangenen Commits. Als nächstes nehmen wir aber außerdem an, dass diese verlorenen Commits aus irgendeinem Grunde nicht im Reflog enthalten sind – Du kannst das z.B. simulieren, indem Du den Branch `recover-branch` und das Reflog löschst. Damit sind die beiden Commits jetzt von nirgendwo her mehr erreichbar: From cdd3c9dd2faa4eac7aa8e7f343943ec9cd8444d1 Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 12 Jan 2014 15:46:27 +0100 Subject: [PATCH 080/690] [de] Chapter 2: Merge original english updates to german translation and translate them --- de/02-git-basics/01-chapter2.markdown | 65 +++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/de/02-git-basics/01-chapter2.markdown b/de/02-git-basics/01-chapter2.markdown index e9e64a7bd..518e1cd7e 100644 --- a/de/02-git-basics/01-chapter2.markdown +++ b/de/02-git-basics/01-chapter2.markdown @@ -245,6 +245,20 @@ Glob Muster sind vereinfachte reguläre Ausdrücke, die von der Shell verwendet Hier ist ein weiteres Beispiel für eine `.gitignore` Datei: + + + + + + + + + + + + + + # ein Kommentar - dieser wird ignoriert # ignoriert alle Dateien, die mit .a enden *.a @@ -252,12 +266,16 @@ Hier ist ein weiteres Beispiel für eine `.gitignore` Datei: !lib.a # ignoriert eine TODO Datei nur im Wurzelverzeichnis, nicht aber /TODO - # in Unterverzeichnissen - # ignoriert alle Dateien im build/ Verzeichnis build/ # ignoriert doc/notes.txt, aber nicht doc/server/arch.txt doc/*.txt + # ignoriert alle .txt Dateien unterhalb des doc/ Verzeichnis + doc/**/*.txt + + + +Die Kombination `**/` wurde in der Git Version 1.8.2 eingeführt. ### Die Änderungen in der Staging Area durchsehen ### @@ -617,11 +635,13 @@ Eine sehr nützliche Option ist `-p`. Sie zeigt die Änderungen an, die in einem index a874b73..8f94139 100644 --- a/Rakefile +++ b/Rakefile - @@ -5,7 +5,7 @@ require 'rake/gempackagetask' + @@ -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 @@ -645,9 +665,36 @@ Eine sehr nützliche Option ist `-p`. Sie zeigt die Änderungen an, die in einem \ No newline at end of file + +Diese Option zeigt also im Prinzip die gleiche Information wie zuvor, aber zusätzlich zu jedem Eintrag ein Diff. Das ist nützlich, um einen Code Review zu machen oder eben mal eine Reihe von Commits durchzuschauen, die ein Mitarbeiter angelegt hat. + + + +Manchmal ist es einfacher Änderungen an Hand der Wörter anstatt zeilenbasiert zu überprüfen. Git bietet dafür die Option `--word-diff`, welche man an den Befehl `git log -p` anhängen kann. Man weist Git damit an, einen Vergleich auf Basis der Wörter anstatt Zeile für Zeile durchzuführen. Dieser Vergleich ist ziemlich nutzlos wenn man Änderungen innerhalb von Quellcode vergleicht. Beim Vergleich von langen Textdateien zeigt er aber seine Stärke. Er bietet sich zum Beispiel für Bücher oder wissenschaftliche Texte an. Hierzu ein Beispiel: + + $ 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" + + + +Wie man in der Ausgabe sehen kann, zeigt dieser Vergleich nicht an, welche Zeilen hinzugekommen und welche entfallen sind. Stattdessen werden Änderungen innerhalb der Zeilen dargestellt. Mit der Sequenz `{+ +}` wird ein neu hinzugekommes Wort gekennzeichnet, mit `[- -]` ein Wort, welches entfernt wurde. Normalerweise zeigt Git bei einem Vergleich drei zusätzliche Zeilen ober- und unterhalb der eigentlichen Änderung an. Bei einem Textvergleich reicht meist eine zusätzliche Zeile. Man kann dies mit der Option `-U1` erreichen, so wie in dem oben gezeigten Beispiel. + -Diese Option zeigt also im Prinzip die gleiche Information wie zuvor, aber zusätzlich zu jedem Eintrag ein Diff. Das ist nützlich, um einen Code Review zu machen oder eben mal eine Reihe von Commits durchzuschauen, die ein Mitarbeiter angelegt hat. Außerdem gibt es verschiedene Optionen, die nützlich sind, um Dinge zusammenzufassen. Beispielsweise kannst Du eine kurze Statistik über jeden Commit mit der Option `--stat` anzeigen lassen: +Außerdem gibt es verschiedene Optionen, die nützlich sind, um Dinge zusammenzufassen. Beispielsweise kannst Du eine kurze Statistik über jeden Commit mit der Option `--stat` anzeigen lassen: $ git log --stat commit ca82a6dff817ec66f44342007202690a93763949 @@ -762,6 +809,7 @@ Das sind nur einige eher simple Format Optionen für die Ausgabe von `git log` + @@ -774,6 +822,7 @@ Das sind nur einige eher simple Format Optionen für die Ausgabe von `git log` Option Beschreibung -p Zeigt den Patch, der einem Commit entspricht. + --word-diff Führt den Vergleich Wort für Wort, anstatt Zeile für Zeile aus. --stat Zeigt Statistiken über die in einem Commit geänderten Dateien und eingefügten/entfernten Zeilen. --shortstat Zeigt nur die Kurzstatistik über eingefügte/entfernte Zeilen aus der `--stat` Option. --name-only Zeigt die Liste der geänderte Dateien nach der Commit Information. @@ -1363,7 +1412,7 @@ Du kannst Commits jederzeit taggen, auch lange Zeit nachdem sie angelegt wurden. Nehmen wir an, dass Du vergessen hast, Version v1.2 des Projekts zu taggen und dass dies der Commit „updated rakefile“ gewesen ist. Du kannst diesen jetzt im Nachhinein taggen, indem Du die Checksumme des Commits (oder einen Teil davon) am Ende des Befehls angibst: - $ git tag -a v1.2 9fceb02 + $ git tag -a v1.2 -m 'version 1.2' 9fceb02 @@ -1435,11 +1484,11 @@ Bevor wir zum Ende dieses Grundlagenkapitels kommen, möchten wir noch einige Ti ### Auto-Vervollständigung ### - + -Wenn Du die Bash Shell verwendest, dann kannst Du ein Skript für die Git Auto-Vervollständigung einbinden. Ein solches Skript wird mit Git zusammen ausgeliefert. Wenn Du den Git Quellcode heruntergeladen hast, findest Du im Verzeichnis `contrib/completion` die Datei `git-completion.bash`. Kopiere diese Datei in Dein Home Verzeichnis und füge die folgende Zeile in Deine `.bashrc` Datei hinzu: +Wenn Du die Bash Shell verwendest, dann kannst Du ein Skript für die Git Auto-Vervollständigung einbinden. Du kannst dieses Skript direkt aus den Git Quellen von https://github.com/git/git/blob/master/contrib/completion/git-completion.bash herunterladen. Kopiere diese Datei in Dein Home Verzeichnis und füge die folgende Zeile in Deine `.bashrc` Datei hinzu: - source ~/.git-completion.bash + source ~/git-completion.bash From 61fa2ee87e3acb3bc80a9052ab2aa79b28c90564 Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 12 Jan 2014 16:29:45 +0100 Subject: [PATCH 081/690] [de] Chapter 3: Merge original english updates to german translation and translate them --- de/03-git-branching/01-chapter3.markdown | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/de/03-git-branching/01-chapter3.markdown b/de/03-git-branching/01-chapter3.markdown index 22945fc2b..484496a93 100644 --- a/de/03-git-branching/01-chapter3.markdown +++ b/de/03-git-branching/01-chapter3.markdown @@ -24,12 +24,12 @@ Wenn Du in Git committest, speichert Git ein sogenanntes Commit-Objekt. Dieses e Um das zu verdeutlichen, lass uns annehmen, Du hast ein Verzeichnis mit drei Dateien, die Du alle zu der Staging-Area hinzufügst und in einem Commit verpackst. Durch das Stagen der Dateien erzeugt Git für jede Datei eine Prüfsumme (der SHA-1 Hash, den wir in Kapitel 1 erwähnt haben), speichert diese Version der Datei im Git-Repository (Git referenziert auf diese als Blobs) und fügt die Prüfsumme der Staging-Area hinzu: - $ git add README test.rb LICENSE2 + $ git add README test.rb LICENSE $ git commit -m 'initial commit of my project' - + -Wenn Du einen Commit mit dem Kommando `git commit` erstellst, erzeugt Git für jedes Unterverzeichnis eine Prüfsumme (in diesem Fall nur für das Root-Verzeichnis) und speichert diese drei Objekte im Git Repository. Git erzeugt dann ein Commit Objekt, das die Metadaten und den Zeiger zur Wurzel des Projektbaums enthält, um bei Bedarf den Snapshot erneut erzeugen zu können. +Wenn Du einen Commit mit dem Kommando `git commit` erstellst, erzeugt Git für jedes Projektverzeichnis eine Prüfsumme und speichert diese als sogenanntes `tree`-Objekt im Git Repository. Git erzeugt dann ein Commit Objekt, das die Metadaten und den Zeiger zum `tree`-Objekt des Wurzelverzeichnis enthält, um bei Bedarf den Snapshot erneut erzeugen zu können. @@ -255,7 +255,7 @@ Zu diesem Zeitpunkt befindet sich das Arbeitsverzeichnis des Projektes in exakt Nun hast Du einen Hotfix zu erstellen. Lass uns dazu einen Hotfix-Branch erstellen, an dem Du bis zu dessen Fertigstellung arbeitest (siehe Abbildung 3-13): - $ 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' @@ -485,9 +485,9 @@ Das `*` vor dem `master`-Branch bedeutet, dass dies der gerade ausgecheckte Bran * master 7a98805 Merge branch 'iss53' testing 782fd34 add scott to the author list in the readmes - + -Mit einer weiteren nützlichen Option kannst Du herausfinden, in welchem Zustand Deine Branches sind: welche der Branches wurden bereits in den aktuellen Branch gemergt und welche wurden es nicht. Die Optionen heißen `--merged` und `--no-merged` und sind seit Version 1.5.6 in Git dabei. Um herauszufinden, welche Branches schon in den aktuell ausgecheckten gemergt wurden, kannst Du einfach `git branch --merged` aufrufen: +Mit einer weiteren nützlichen Option kannst Du herausfinden, in welchem Zustand Deine Branches sind: welche der Branches wurden bereits in den aktuellen Branch gemergt und welche wurden es nicht. Für diesen Zweck gibt es in Git die Optionen `--merged` und `--no-merged`. Um herauszufinden, welche Branches schon in den aktuell ausgecheckten gemergt wurden, kannst Du einfach `git branch --merged` aufrufen: $ git branch --merged iss53 @@ -510,7 +510,7 @@ Die Liste zeigt Dir den anderen Branch. Er enthält Arbeit, die noch nicht gemer $ 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 are sure you want to delete it, run 'git branch -D testing'. @@ -722,7 +722,7 @@ Um einen lokalen Branch mit einem anderem Namen als der Remote-Branch, kannst Du Branch sf set up to track remote branch refs/remotes/origin/serverfix. Switched to a new branch "sf" - + Nun wird Dein lokaler Branch `sf` automatisch push und pull auf `origin/serverfix` durchführen. From 93b3ec5ead4d15f9ce3c6223c81a4d73bee7f4c1 Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 12 Jan 2014 16:29:56 +0100 Subject: [PATCH 082/690] [de] Chapter 4: Merge original english updates to german translation and translate them --- de/04-git-server/01-chapter4.markdown | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/de/04-git-server/01-chapter4.markdown b/de/04-git-server/01-chapter4.markdown index 80b14cd2a..79115b17e 100644 --- a/de/04-git-server/01-chapter4.markdown +++ b/de/04-git-server/01-chapter4.markdown @@ -47,9 +47,9 @@ Oder Du kannst das machen: $ git clone file:///opt/git/project.git - + -Git arbeitet etwas anders, wenn Du am Anfang der URL ausdrücklich `file://` angibst. Wenn Du nur den Pfad angibst, versucht Git harte Links zu benutzen oder Git kopiert direkt die benötigten Dateien. Wenn Du `file://` angibst, startet Git den Prozess, den es normalerweise zum Übertragen von Daten über ein Netzwerk verwendet, dass ist gewöhnlich eine wesentlich ineffizientere Methode zum Übertragen der Daten. Der Hauptgrund das `file://`-Präfix anzugeben ist eine saubere Kopie von dem Repository mit fremden Referenzen oder fehlenden Objekten – generell nach einem Import von einem anderen Versionskontrollsystem oder etwas ähnliches (siehe Kapitel 9 für Wartungsarbeiten). Wir benutzen hier den normalen Pfad, weil das fast immer schneller ist. +Git arbeitet etwas anders, wenn Du am Anfang der URL ausdrücklich `file://` angibst. Wenn Du nur den Pfad angibst, und sowohl die Quelle, als auch das Ziel sich auf dem selben Dateisystem befinden, versucht Git harte Links zu benutzen. Wenn sie sich nicht auf dem selben Dateisystem befinden, kopiert Git die benötigten Objekte mit Hilfe der Standardkopierfunktion des jeweiligen Betriebssystems. Wenn Du `file://` angibst, startet Git den Prozess, den es normalerweise zum Übertragen von Daten über ein Netzwerk verwendet, dass ist gewöhnlich eine wesentlich ineffizientere Methode zum Übertragen der Daten. Der Hauptgrund das `file://`-Präfix anzugeben ist eine saubere Kopie von dem Repository mit fremden Referenzen oder fehlenden Objekten – generell nach einem Import von einem anderen Versionskontrollsystem oder etwas ähnliches (siehe Kapitel 9 für Wartungsarbeiten). Wir benutzen hier den normalen Pfad, weil das fast immer schneller ist. @@ -137,7 +137,8 @@ Das Git Protokoll ist das schnellste verfügbare Transfer Protokoll. Wenn Du vie #### Die Nachteile #### - + + Die Negativseite des Git Protokoll ist das Fehlen der Authentifizierung. Es ist generell unerwünscht, dass das Git Protokoll der einzige Zugang zu dem Projekt ist. Im Allgemeinen willst Du es mit SSH-Zugriff für die Entwickler paaren, die push (Schreib) Zugriff haben und jeder andere benutzt `git://` für Nur-Lese-Zugriff. Es ist vielleicht auch das das schwierigste Protokoll beim Einrichten. Es muss ein eigener Dämon laufen, welcher Git-spezifisch ist – wir wollen im „Gitosis“-Abschnitt in diesem Kapitel schauen, wie man einen einrichtet – es setzt eine `xinetd`-Konfiguration oder ähnliches voraus, das ist nicht immer ein Spaziergang. Es setzt auch einen Firewall-Zugriff auf den Port 9418 voraus, das ist kein Standard-Port, den Firmen-Firewalls immer erlauben. Hinter einer großen Firmen-Firewall ist dieser unklare Port häufig gesperrt. From 5fd6d6110b30ee8bb50ed1adad274dfcd130265a Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 12 Jan 2014 16:52:54 +0100 Subject: [PATCH 083/690] [de] Chapter 5: Merge original english updates to german translation and translate them --- de/05-distributed-git/01-chapter5.markdown | 33 +++++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/de/05-distributed-git/01-chapter5.markdown b/de/05-distributed-git/01-chapter5.markdown index b216da970..d7d2ca314 100644 --- a/de/05-distributed-git/01-chapter5.markdown +++ b/de/05-distributed-git/01-chapter5.markdown @@ -330,7 +330,7 @@ Jessica hat die Arbeit in ihrem Topic Branch abgeschlossen, aber sie will wissen removed invalid default value - + Jetzt kann Jessica zunächst ihren Topic Branch `issue54` in ihren `master` Branch mergen, dann Johns Änderungen aus `origin/master` in ihren `master` Branch mergen und schließlich das Resultat auf den `origin` Server pushen. Als erstes wechselt sie zurück auf ihren `master` Branch: @@ -386,7 +386,7 @@ Beide Entwickler haben jetzt einige Male committed und die Arbeit des jeweils an Insert 18333fig0510.png Bild 5-10. Jessicas Historie nachdem sie sämtliche Änderungen auf den Server gepusht hat - + Dies ist eine der simpelsten Workflow Varianten. Du arbeitest eine Weile, normalerweise in einem Topic Branch, und mergst in Deinen `master` Branch, wenn Du fertig bist. Wenn Du Deine Änderungen anderen zur Verfügung stellen willst, holst Du den aktuellen `origin/master` Branch, mergst Deinen `master` Branch damit und pushst das ganze zurück auf den `origin` Server. Der Ablauf sieht in etwa wie folgt aus (Bild 5-11). @@ -766,9 +766,34 @@ Zunächst musst Du die IMAP Sektion in Deiner `~/.gitconfig` Datei ausfüllen. D sslverify = false - + -Wenn Dein IMAP Server kein SSL verwendet, kannst Du die letzten beiden Zeilen wahrscheinlich weglassen und der `host` dürfte mit `imap://` und nicht `imaps://` beginnen. Wenn Du diese Einstellungen konfiguriert hast, kannst Du `git send-email` verwenden, um Deine Patches in den Entwurfsordner des angegebenen IMAP Servers zu kopieren: +Wenn Dein IMAP Server kein SSL verwendet, kannst Du die letzten beiden Zeilen wahrscheinlich weglassen und der `host` dürfte mit `imap://` und nicht `imaps://` beginnen. Wenn Du diese Einstellungen konfiguriert hast, kannst Du `git imap-send` verwenden, um Deine Patches in den Entwurfsordner des angegebenen IMAP Servers zu kopieren: + + $ cat *.patch |git imap-send + Resolving imap.gmail.com... ok + Connecting to [74.125.142.109]:993... ok + Logging in... + sending 2 messages + 100% (2/2) done + + + +Jetzt kannst Du in Deinen Entwürfe-Ordner wechseln, die Mailingliste an die Du den Patch senden möchtest im An-Feld setzen, vielleicht noch den Maintainer oder die verantwortliche Person in das CC-Feld einfügen und dann das Ganze losschicken. + + + +Man kann Patches auch über einen SMTP-Server schicken. Wie im letzen Beispiel, kann man auch hier jeden einzelnen Wert mit einer Reihe von `git config` Kommandos setzen. Oder aber Du änderst die Sektion sendemail in Deiner `~/.gitconfig` Datei manuell: + + [sendemail] + smtpencryption = tls + smtpserver = smtp.gmail.com + smtpuser = user@gmail.com + smtpserverport = 587 + + + +Nach der Änderungen kannst Du mit `git send-email` die Patches abschicken: $ git send-email *.patch 0001-added-limit-to-log-function.patch From 0b41150bebc7ca362e51010058d10e034fc41595 Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 12 Jan 2014 17:18:45 +0100 Subject: [PATCH 084/690] [de] Chapter 6: Merge original english updates to german translation --- de/06-git-tools/01-chapter6.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index 645938ee0..39e8c219d 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -1322,7 +1322,7 @@ Dann kannst Du diesem Entwickler eine E-Mail schreiben und ihn auf seinen Fehler In manchen großen Projekten möchten die Entwickler die Arbeit in verschiedenen Verzeichnissen aufteilen, sodass das jeweilige Team in diesen Verzeichnissen arbeiten kann. Man trifft diese Vorgehensweise häufig an, wenn ein Team gerade von CVS oder Subversion nach Git gewechselt hat, im alten System ein Modul oder eine Sammlung von solchen Unterverzeichnissen gebildet hat und diesen Arbeitsablauf weiterhin verwenden möchte. - + In Git kann man diese Vorgehensweise gut abbilden, indem man für jedes Unterverzeichnis ein neues Git Repository erzeugt. Zusätzlich kann man dann ein Superprojekt erzeugen und die ganzen Git Repositorys als Submodul hinzufügen. Ein Vorteil dabei ist, dass man mit Hilfe von Tags und Branches im Superprojekt das Verhältnis der einzelnen Submodule zueinander festhalten kann. From 6e6e3afd5c72d4727a22938dd809944c047464ac Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 12 Jan 2014 18:04:22 +0100 Subject: [PATCH 085/690] [de] Chapter 7: Merge original english updates to german translation and translate them --- de/07-customizing-git/01-chapter7.markdown | 75 +++++++++++----------- 1 file changed, 39 insertions(+), 36 deletions(-) diff --git a/de/07-customizing-git/01-chapter7.markdown b/de/07-customizing-git/01-chapter7.markdown index 74dede055..aefff281d 100644 --- a/de/07-customizing-git/01-chapter7.markdown +++ b/de/07-customizing-git/01-chapter7.markdown @@ -115,7 +115,7 @@ Die Einstellung `core.pager` legt fest, welche Anwendung zur Seitenanzeige benut Wenn Du dies ausführst, wird Git immer die komplette Ausgabe aller Befehle anzeigen, egal wie lange sie ist. - + #### user.signingkey #### @@ -140,9 +140,9 @@ In Kapitel 2 habe ich bereits beschrieben, wie Du mit Hilfe der projektspezifisc #### help.autocorrect #### - + -Diese Option ist in Git ab Version 1.6.1 verfügbar. Wenn Du in Git 1.6 einen Befehl falsch schreibst, bekommst Du eine Meldung wie diese: +Diese Option ist in Git ab Version 1.6.1 verfügbar. Wenn Du in Git einen Befehl falsch schreibst, bekommst Du eine Meldung wie diese: $ git com git: 'com' is not a git-command. See 'git --help'. @@ -170,9 +170,9 @@ Wenn Du Git entsprechend konfigurierst, wird es den Großteil der Ausgaben autom $ git config --global color.ui true - + -Wenn dieser Wert gesetzt wurde, benutzt Git für seine Ausgaben Farben, sofern diese zu einem Terminal geleitet werden. Weitere mögliche Einstellungen sind ‚false‘, wodurch alle Farben deaktiviert werden, sowie ‚always‘, wodurch Farben immer aktiviert sind, selbst wenn Du Git Befehle in eine Datei oder über eine Pipe zu einem anderen Befehl umleitest. Diese Option wurde in Git 1.5.5 hinzugefügt. Solltest Du eine ältere Git Version benutzen, so musst Du alle Farbeinstellungen einzeln vornehmen. +Wenn dieser Wert gesetzt wurde, benutzt Git für seine Ausgaben Farben, sofern diese zu einem Terminal geleitet werden. Weitere mögliche Einstellungen sind ‚false‘, wodurch alle Farben deaktiviert werden, sowie ‚always‘, wodurch Farben immer aktiviert sind, selbst wenn Du Git Befehle in eine Datei oder über eine Pipe zu einem anderen Befehl umleitest. @@ -181,9 +181,9 @@ Du wirst selten die Einstellung `color.ui = always` benötigen. In den meisten F #### `color.*` #### - + -Falls Du im Detail einstellen willst, welche Befehle wie gefärbt werden, oder wenn Du eine ältere Version benutzt, dann stellt Git Verb-spezifische Farbeinstellungen zur Verfügung. Jede dieser Optionen kann auf `true`, `false`, oder `always` eingestellt werden: +Falls Du im Detail einstellen willst, welche Befehle wie gefärbt werden, dann stellt Git Verb-spezifische Farbeinstellungen zur Verfügung. Jede dieser Optionen kann auf `true`, `false`, oder `always` eingestellt werden: color.branch color.diff @@ -468,25 +468,33 @@ Um Git anzuweisen alle `pbxproj` Dateien als Binärdateien zu behandeln, kannst *.pbxproj -crlf -diff - + -Ab jetzt wird Git nicht mehr versuchen CRLF Probleme zu lösen oder die Datei beim Commit oder Checkout zu ändern. Außerdem ermittelt Git keine Dateiunterschiede mehr und gibt diese auch nicht aus, wenn Du den Befehl ‚git show‘ oder ‚git diff‘ ausführst. Ab der Git Version 1.6 steht Dir auch ein Makro zur Verfügung, welches den Parametern `-crlf -diff` entspricht: +Ab jetzt wird Git nicht mehr versuchen CRLF Probleme zu lösen oder die Datei beim Commit oder Checkout zu ändern. Außerdem ermittelt Git keine Dateiunterschiede mehr und gibt diese auch nicht aus, wenn Du den Befehl `git show` oder `git diff` ausführst. Alternativ gibt es auch ein integriertes Makro `binary`, welches den Parametern `-crlf -diff` entspricht: *.pbxproj binary #### Diff bei Binärdateien #### - + -Mit Hilfe der Git Attribute können seit der Version 1.6, Unterschiede in binären Dateien effektiv und leicht angezeigt werden. Du kannst Git so konfigurieren, dass es automatisch Binärdateien in Textdateien umwandelt, damit sie mit einem normalen Diff verglichen werden können. +Mit Hilfe der Git Attribute können Unterschiede in binären Dateien effektiv und leicht angezeigt werden. Du kannst Git so konfigurieren, dass es automatisch Binärdateien in Textdateien umwandelt, damit sie mit einem normalen Diff verglichen werden können. Meist stellt sich aber die Frage, wie man binäre Daten in Text konvertieren soll. Wenn man ein Werkzeug findet, welches einem diese Konvertierung abnimmt und die binäre Daten in ein Textformat umwandelt, ist dies meist die beste Lösung. Leider gibt es nur sehr wenige binäre Formate, die sich dafür eignen, dass man sie in lesbare Textformate umwandelt (Ich denke dabei zum Beispiel an Audio-Daten). Wenn dies der Fall ist und Du keine geeignete Möglichkeit gefunden hast, die Daten in lesbare Form zu wandeln, dann ist es oft relativ einfach eine entsprechende Beschreibung des eigentlichen Inhalts zu erhalten. Alternativ gibt es noch Metadaten, wobei Metadaten einem nicht ein vollständiges Abbild vom Dateiinhalt liefern können, aber in diesem Fall ist das besser als gar nichts. + + + +Im folgenden Abschnitt werden wir beide Möglichkeiten besprechen, wie man für weit verbreitete binäre Formate eine lesbare Form für einen Vergleich erhält. + + + +Anmerkung: Es gibt verschiedene Arten von binären Formaten, welche Text beinhalten, und es ist meist sehr schwierig einen passenden Konverter zu finden. In solchen Fällen kann man sein Glück mit dem `strings`-Programm versuchen. Manche der Formate verwenden ein UTF-16 Encoding oder andere Zeichentabellen. In diesem Fall wird es mit dem Programm `strings` meist nicht funktionieren. Da `strings` jedoch auf den meisten Mac- und Linux-Systemen verfügbar ist, sollte man es durchaus auf einen Versuch ankommen lassen. ##### MS Word files ##### - + -Da das eine ziemlich praktische, aber nicht sehr bekannt Funktionalität ist, werde ich einige Beispiele besprechen. Als erstes werden wir diese Technik benutzen um eines der lästigsten Probleme der Menschheit zu lösen: Versionskontrolle von Word Dokumenten. Jeder weiß, dass Word der schrecklichste Editor der Welt ist, aber trotzdem benutzt ihn jeder. Wenn Du Word Dokumente versionieren willst, kannst Du sie in Dein Repository packen und ab und zu einen Commit durchführen. Aber wozu ist das nützlich? Wenn Du einen Vergleich mit `git diff` ausführst, erhälst Du ähnliche Ausgabe wie diese: +Als erstes werden wir die beschriebene Technik benutzen um eines der lästigsten Probleme der Menschheit zu lösen: Versionskontrolle von Word Dokumenten. Jeder weiß, dass Word der schrecklichste Editor der Welt ist, aber trotzdem benutzt ihn jeder. Wenn Du Word Dokumente versionieren willst, kannst Du sie in Dein Repository packen und ab und zu einen Commit durchführen. Aber wozu ist das nützlich? Wenn Du einen Vergleich mit `git diff` ausführst, erhälst Du ähnliche Ausgabe wie diese: $ git diff diff --git a/chapter1.doc b/chapter1.doc @@ -499,26 +507,22 @@ Du kannst zwei Versionen nicht direkt vergleichen, außer Du checkst sie aus und *.doc diff=word - + -Dies weist Git an, dass auf jede Datei, die diesem Dateimuster (.doc) entspricht, der „word“ Filter angewandt werden soll, wenn Du versuchst, einen Diff mit Dateiunterschieden anzusehen. Was ist nun der „word“ Filter? Dieser muss von Dir noch konfiguriert werden. Du kannst Git so konfigurieren, dass es das `strings` Programm verwendet um Word Dokumente in lesbare Textdateien zu konvertieren. Bei jedem Diff wird Git diese Konvertierung durchführen: +Dies weist Git an, dass auf jede Datei, die diesem Dateimuster (.doc) entspricht, der „word“ Filter angewandt werden soll, wenn Du versuchst, einen Diff mit Dateiunterschieden anzusehen. Was ist nun der „word“ Filter? Dieser muss von Dir noch konfiguriert werden. Du kannst Git so konfigurieren, dass es das `catdoc` Programm verwendet um Word Dokumente in lesbare Textdateien zu konvertieren. `catdoc` wurde speziell dafür entwickelt um lesbaren Text aus binären MS Word Dokumenten zu extrahieren (du erhälst es unter `http://www.wagner.pp.ru/~vitus/software/catdoc/`). Bei jedem Diff wird Git diese Konvertierung durchführen: - $ git config diff.word.textconv strings + $ git config diff.word.textconv catdoc Dieser Befehl fügt in der Datei `.git/config` eine Sektion mit folgendem Aufbau hinzu: [diff "word"] - textconv = strings - - - -Anmerkung: Es gibt verschiedene Arten von `.doc` Dateien. Manche verwenden UTF-16 Kodierung oder andere Zeichensätze. Das führt dazu, dass `strings` nichts verwertbares findet. Probier Dein Glück. + textconv = catdoc - + -Bei jedem Vergleich von zwei Schnappschüssen wird Git Dateien mit der Dateiendung `.doc` durch den „word“ Filter jagen, welcher durch das `strings` Programm definiert ist. Das erzeugt gut lesbare Textversionen Deiner Word Dateien, die für den Vergleich herangezogen werden. +Bei jedem Vergleich von zwei Schnappschüssen wird Git Dateien mit der Dateiendung `.doc` durch den „word“ Filter jagen, welcher durch das `catdoc` Programm definiert ist. Das erzeugt gut lesbare Textversionen Deiner Word Dateien, die für den Vergleich herangezogen werden. @@ -529,17 +533,16 @@ Dazu ein Beispiel. Ich habe Kapitel 1 des Buches in ein Word-Dokument einfgefüg 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 war erfolgreich und zeigt nun kurz und bündig an, dass ich den Text „Let's see if this works“ hinzugefügt habe, was korrekt ist. Es ist nicht perfekt, es wird etwas zufälliger Kram am Ende angefügt — aber es funktioniert. Falls Du einen guten Word-nach-Text Konverter findest oder schreibst, dann ist diese Lösung wahrscheinlich äußerst effektiv. Für den Anfang sollte `strings` für die meisten Binärformate jedoch ausreichen, vor allem da es für die meisten Mac und Linux Systeme verfügbar ist. +Git war erfolgreich und zeigt nun kurz und bündig an, dass ich den Text „(See Chapter 3)“ hinzugefügt habe, was korrekt ist. Wie du siehst, funktioniert perfekt. ##### OpenDocument Textdateien ##### @@ -815,9 +818,9 @@ Genau wie bei vielen anderen Versionskontrollsystemen gibt es auch bei Git die M ### Installieren eines Hooks ### - + -Sämtliche Hooks werden im `hooks` Unterverzeichnis des Git Verzeichnisses gespeichert. In den meisten Projekten wird das `.git/hooks` sein. Git installiert in dieses Verzeichnis standardmäßig Beispielskripte. Einige davon sind auch ohne Änderung nützlich und sofort einsetzbar. Zusätzlich dokumentieren diese Beispiele die Eingabewerte des jeweiligen Skripts. Alle Beispiele sind Shellskripte, die hier und da ein Paar Zeilen Perl Code enthalten. Prinzipiell sollte aber jedes ausführbare Skript funktionieren, wenn es korrekt benannt wird. Du kannst also die Skriptsprache Deiner Wahl verwenden, z.B. Ruby oder Python. Ab Version 1.6 haben die Beispieldateien die Endung .sample, sie müssen also noch umbenannt werden. In älteren Versionen sind die Beispieldateien korrekt benannt, aber dafür nicht ausführbar. +Sämtliche Hooks werden im `hooks` Unterverzeichnis des Git Verzeichnisses gespeichert. In den meisten Projekten wird das `.git/hooks` sein. Git installiert in dieses Verzeichnis standardmäßig Beispielskripte. Einige davon sind auch ohne Änderung nützlich und sofort einsetzbar. Zusätzlich dokumentieren diese Beispiele die Eingabewerte des jeweiligen Skripts. Alle Beispiele sind Shellskripte, die hier und da ein Paar Zeilen Perl Code enthalten. Prinzipiell sollte aber jedes ausführbare Skript funktionieren, wenn es korrekt benannt wird. Du kannst also die Skriptsprache Deiner Wahl verwenden, z.B. Ruby oder Python. Die Beispieldateien haben die Endung .sample, sie müssen also nur noch umbenannt werden. @@ -1114,9 +1117,9 @@ Ab jetzt haben alle Benutzer nur für die jeweils freigegebenen Verzeichnisse Zu #### Verweigern von Pushes, welche nicht einem Fast-Forward entsprechen #### - + -Nun müssen wir unser System nur noch so einrichten, dass es nur Fast-Forward Push-Operationen zulässt. Ab der Version 1.6 von Git kann man dazu die `receive.denyDeletes` und `receive.denyNonFastForwards` Konfigurationsparameter verwenden. In älteren Versionen benötigt man dafür einen Hook und man kann diesen dann so konfigurieren, dass die Regeln nur für bestimmte Benutzer gelten. +Nun müssen wir unser System nur noch so einrichten, dass es nur Fast-Forward Push-Operationen zulässt. Man verwendet dafür die `receive.denyDeletes` und `receive.denyNonFastForwards` Konfigurationsparameter. Das gleiche Ergebnis kann man aber auch über einen Hook erreichen und diesen kann man dann so konfigurieren, dass die Regeln nur für bestimmte Benutzer gelten. From fb48cbc8bf061c75a5619dd4fe47a68dff1df3ba Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 12 Jan 2014 18:07:37 +0100 Subject: [PATCH 086/690] [de] Chapter 8: Merge original english updates to german translation --- 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 4ae40993d..19d5fc35b 100644 --- a/de/08-git-and-other-scms/01-chapter8.markdown +++ b/de/08-git-and-other-scms/01-chapter8.markdown @@ -517,7 +517,7 @@ Dies erzeugt Dir die Log-Ausgabe im XML-Format — Du suchst damit nach den Auto Du kannst diese Datei dann `git svn` zur Verfügung stellen um das Tool dabei zu unterstützen, die Autoreninformationen besser zu mappen. Du kannst `git svn` ebenfalls mitteilen, dass es die Metadaten nicht einbeziehen soll, die Subversion normalerweise importiert, indem Du dem `clone` oder `init` Kommando die `--no-metadata`-Option mitgibst. - $ 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 From df1522a5f08dc0bda0e0d9178f55bbbf6e949e48 Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 12 Jan 2014 18:11:03 +0100 Subject: [PATCH 087/690] [de] Chapter 9: Merge original english updates to german translation --- de/09-git-internals/01-chapter9.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/de/09-git-internals/01-chapter9.markdown b/de/09-git-internals/01-chapter9.markdown index 2b3f3ad99..dbbaa1196 100644 --- a/de/09-git-internals/01-chapter9.markdown +++ b/de/09-git-internals/01-chapter9.markdown @@ -618,7 +618,7 @@ Wenn Du Dir den resultierenden Tree anschaust, findest Du den SHA-1 Hash, den di Jetzt kannst Du mit `git cat-file` sehen, wie groß das Objekt ist: - $ Du -b .git/objects/9b/c1dc421dcd51b4ac296e3e5b6e2a99cf44391e + $ du -b .git/objects/9b/c1dc421dcd51b4ac296e3e5b6e2a99cf44391e 4102 .git/objects/9b/c1dc421dcd51b4ac296e3e5b6e2a99cf44391e @@ -643,7 +643,7 @@ Wenn Du jetzt den Tree anschaust, der durch den Commit angelegt wurde, findest D Das Blob ist ein anderes, d.h. obwohl Du lediglich eine einzige Zeile an das Ende einer 400 Zeilen langen Datei angehängt hast, speichert Git den Inhalt jetzt als ein ganz neues Objekt: - $ Du -b .git/objects/05/408d195263d853f09dca71d55116663690c27c + $ du -b .git/objects/05/408d195263d853f09dca71d55116663690c27c 4109 .git/objects/05/408d195263d853f09dca71d55116663690c27c From aa0ded2cb645b34ca8695c585caee87a8400afc9 Mon Sep 17 00:00:00 2001 From: Broda Noel Date: Sun, 12 Jan 2014 15:33:49 -0300 Subject: [PATCH 088/690] Fix broken syntax --- es/04-git-server/01-chapter4.markdown | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/es/04-git-server/01-chapter4.markdown b/es/04-git-server/01-chapter4.markdown index ef8af9cf8..4ddf11685 100755 --- a/es/04-git-server/01-chapter4.markdown +++ b/es/04-git-server/01-chapter4.markdown @@ -404,9 +404,8 @@ Y ya estás preparado para trabajar. Si lo has configurado todo correctamente, p fatal: unrecognized command 'gitosis-serve schacon@quaternion' Connection to gitserver closed. -Indicandote que Gitosis te ha reconocido, pero te está hechando debido a que no estás intentando lanzar ningún comando Git. Por tanto, intentalo con un comando Git real --por ejemplo, clonar el propio repositorio de control de Gitosis - - a tu ordenador personal-- +Indicandote que Gitosis te ha reconocido, pero te está hechando debido a que no estás intentando lanzar ningún comando Git. Por tanto, intentalo con un comando Git real --por ejemplo, clonar el propio repositorio de control de Gitosis a tu ordenador personal-- + $ git clone git@gitserver:gitosis-admin.git Con ello, tendrás una carpeta denominada 'gitosis-admin', con dos partes principales dentro de ella: From bafbd267795b9b0d4fd1fde6bb2a1c42196a4519 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 13 Jan 2014 13:53:14 -0600 Subject: [PATCH 089/690] Reviewed "Distributed Workflow" --- it/05-distributed-git/01-chapter5.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index ccb4ab1c8..fa7d63d8d 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -6,7 +6,7 @@ In questo capitolo, vedremo come lavorare con Git in un ambiente distribuito com ## Workflows distribuiti ## -A differenza dei gestori di versione centralizzati (CVCS), la natura distribuita di Git ti permette di essere più flessibile nel gestire il modo in cui gli sviluppatori collaborano ai progetti. Nel sistemi centralizzati, ogni sviluppatore è un nodo che lavora appoggiandosi ad un nucleo centrale più o meno ugualmente agli altri. Con Git invece, ogni sviluppatore è potenzialmente sia un nodo che un nucleo - infatti ogni sviluppatore può fornire del codice agli altri repository e mantenere un repository pubblico sul quale gli altri basino il proprio lavoro e verso il quale contribuiscano. Questo apre ad una vasta gamma di possibilità di workflow per il vostro progetto e/o il vostro team. Tratterò quindi alcuni paradigmi che sfruttano questa flessibilità. Discuterò i punti di forza e quelli deboli di ogni design. Potrai usarne uno o combinarli per adattarli alle tue necessità. +A differenza dei gestori di versione centralizzati (CVCS), la natura distribuita di Git ti permette di essere più flessibile nel gestire il modo in cui gli sviluppatori collaborano ai progetti. Nel sistemi centralizzati ogni sviluppatore è un nodo che lavora appoggiandosi ad un nucleo centrale più o meno ugualmente agli altri. Con Git, invece, ogni sviluppatore è potenzialmente sia un nodo che un nucleo: infatti ogni sviluppatore può contemporaneamente contribuire al codice di altri repository e mantenere un repository pubblico sul quale gli altri basino il proprio lavoro e verso il quale possano contribuire. Questo apre ad una vasta gamma di possibilità di workflow per il tuo progetto e/o il tuo gruppo. Tratterò quindi alcuni paradigmi che sfruttano questa flessibilità. Discuterò i punti di forza e le possibili debolezze di ogni design: potrai usarne uno o combinarli per adattarli alle tue necessità. ### Workflow centralizzato ### From 87050bbeed2f5ba874904b810a8a5934255ece00 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 13 Jan 2014 14:03:33 -0600 Subject: [PATCH 090/690] Reviewed "Centralized Workflow" --- it/05-distributed-git/01-chapter5.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index fa7d63d8d..27595583c 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -10,15 +10,15 @@ A differenza dei gestori di versione centralizzati (CVCS), la natura distribuita ### Workflow centralizzato ### -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). +Nei sistemi centralizzati, generalmente c'è un solo modo per collaborare: il flusso centralizzato. Un nucleo centrale, c.d. repository, può accettare il codice e tutti sincronizzano il proprio lavoro con questo nucleo. Un numero di sviluppatori sono nodi - utenti del nucleo - e restano sincronizzati con questo nucleo centrale (vedi Figura 5-1). 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. +Questo significa che se due sviluppatori clonano dal nucleo ed entrambi fanno dei cambiamenti, il primo sviluppatore che trasmetterà le proprie modifiche al nucleo non avrà problemi. Il secondo, invece, dovrà prima unire al proprio lavoro quello del primo e quindi potrà inviare i suoi cambiamenti, per non sovrascrivere il lavoro del primo. Questo accade in Git come in Subversion (o un altro CVCS), e questo modello funziona tranquillamente in Git. -Se hai un piccolo team, o nella tua azienda sono già abituati ad un workflow centralizzato, puoi facilmente continuare ad utilizzare questo metodo con Git. Semplicemente crea un singolo repository, e dai ad ognuno la possibilità di effettuare un push; Git non lascerà agli utenti la possibilità di sovrascriversi l'un l'altro. Se uno sviluppatore clona, esegue dei cambiamenti, e poi prova a fare un push delle proprie modifiche dopo che un altro utente ha cambiato qualcosa, il server si rifiuterà di consentire l'operazione. L'utente sarà avvisato che sta cercando di fare un push di una copia non aggiornata, e non sarà capace di caricare le proprie modifiche finché non le unirà con quelle effettuate dagli altri. -Questo metodo è utilizzato da tanti dato che è il paradigma che molti conoscono e a cui sono abituati. +Se hai un piccolo gruppo, o nella tua azienda siete già abituati ad un workflow centralizzato, puoi facilmente continuare ad utilizzare questo metodo con Git. Crea un singolo repository e dai a ognuno del tuo gruppo la possibilità di effettuare una push; Git non lascerà agli utenti la possibilità di sovrascrivere il lavoro di un l'altro. Se uno sviluppatore clona, fa dei cambiamenti, e poi prova a fare una push delle proprie modifiche dopo che un altro utente abbia già inviato le proprie modifiche, il server rifiuterà le modifiche dell'ultimo. Questi sarà avvisato che sta cercando di fare la push di una copia non aggiornata e non potrà caricare le proprie modifiche finché non le unirà con quelle effettuate dagli altri. +Molti usano questo metodo perché sono abituati a lavorare con questo paradigma. ### Workflow con manager d'integrazione ### From bc3aeecedadf270a9c270fabbc85c389f6d7fc49 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 13 Jan 2014 14:12:48 -0600 Subject: [PATCH 091/690] Reviewed "Integration-Manager Workflow" --- it/05-distributed-git/01-chapter5.markdown | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 27595583c..9deece6be 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -22,19 +22,19 @@ Molti usano questo metodo perché sono abituati a lavorare con questo paradigma. ### Workflow con manager d'integrazione ### -Dato che Git ti consente di avere multipli repositories, è possibile avere un workflow dove ogni sviluppatore ha accesso in scrittura al proprio pubblico respository, e accesso in lettura a quello degli altri. In questo scenario spesso esiste un repository che rappresenta il progetto "ufficiale". Per contribuire an progetto di questo tipo, devi creare il tuo clone pubblico del progetto e fare un push delle tue modifiche verso il progetto e successivamente chiedere al mantenitore del progetto di fare un pull delle tue modifiche. Questi può aggiungere il tuo repository come remoto, testarlo localmente, unirlo al proprio ramo e fare un push verso il proprio repository. Il processo funziona così (vedi Figura 5-2): +Poiché Git permette di avere repository multipli, è possibile avere un workflow dove ogni sviluppatore ha accesso in scrittura al proprio respository pubblico e accesso in lettura a quello degli altri. Questo scenario spesso prevede anche un repository classico che rappresenta il progetto "ufficiale". Per contribuire a progetti di questo tipo, devi creare il tuo clone pubblico del progetto e inviarvi (con una push) le tue modifiche e successivamente chiedere al mantenitore del progetto di fare una pull delle stesse. Questi può aggiungere il tuo repository come remoto, testarlo localmente, unirlo al proprio branch e fare una push verso il proprio repository. Il processo funziona così (vedi Figura 5-2): -1. Il mantenitore del progetto fa un push del proprio repository pubblico. -2. Un contributore clona il reposiory ed esegue dei cambiamenti. -3. Il contributore fa un push dei propri cambiamenti. -4. Il contributore invia al mantenitore una e-mail chiedendo di fare un pull dei cambiamenti. +1. Il mantenitore del progetto fa le push sul proprio repository pubblico. +2. Un contributore clona il reposiory ed fa delle cambiamenti. +3. Il contributore invia le modifiche al suo repository pubblico. +4. Il contributore invia al mantenitore una e-mail chiedendo di fare una pull dei cambiamenti. 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. +6. Il mantenitore fa una push dei cambiamenti (compresi quelli aggiunti dal contributore) verso il repository principale. 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 nel proprio fork, in modo che tutti possano accedervi. 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. +Questo è un workflow comune con siti come GitHub, dove è facile eseguire un fork di un progetto e inviare le tue modifiche al tuo fork, in modo che tutti possano accedervi. Uno dei vantaggi principali di questo approccio è che puoi continuare il tuo lavoro mentre il mantenitore del repository principale può eseguire una pull dei tuoi cambiamenti in qualsiasi momento. I contributori non devono aspettare che il progetto incorpori le modifiche: ognuno può lavorare per conto suo. ### Workflow con Dittatori e Tenenti ### From 972c6da3bd91a8bee0aeaca619f7c8947d9de937 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 13 Jan 2014 14:13:34 -0600 Subject: [PATCH 092/690] Reviewed "Dictator and Lieutenants Workflow" wrong title translation --- it/05-distributed-git/01-chapter5.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 9deece6be..e1d5a196e 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -36,7 +36,7 @@ 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 inviare le tue modifiche al tuo fork, in modo che tutti possano accedervi. Uno dei vantaggi principali di questo approccio è che puoi continuare il tuo lavoro mentre il mantenitore del repository principale può eseguire una pull dei tuoi cambiamenti in qualsiasi momento. I contributori non devono aspettare che il progetto incorpori le modifiche: ognuno può lavorare per conto suo. -### Workflow con Dittatori e Tenenti ### +### Workflow con Dittatore e Tenenti ### Questa è una variante del workflow con multipli repository. E' generalmente usata da grandi progetti con centinaia di collaboratori; un esempio famoso è il Kernel Linux. Molti manager d'integrazione sono in carica di certe parti del repository; sono chiamati tenenti. Tutti i tenenti hanno un manager d'integrazione conosciuto come "dittatore benevolo". Il repository del dittatore benevolo funziona come repository di riferimento dal quale tutti i collaboratori eseguono un pull. Il flusso di lavoro è il seguente (vedi Figura 5-3): From 8a4117d3436fe898d71ded2c6b91a9837015569d Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 13 Jan 2014 14:14:35 -0600 Subject: [PATCH 093/690] typo --- it/05-distributed-git/01-chapter5.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index e1d5a196e..187ee22e4 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -22,7 +22,7 @@ Molti usano questo metodo perché sono abituati a lavorare con questo paradigma. ### Workflow con manager d'integrazione ### -Poiché Git permette di avere repository multipli, è possibile avere un workflow dove ogni sviluppatore ha accesso in scrittura al proprio respository pubblico e accesso in lettura a quello degli altri. Questo scenario spesso prevede anche un repository classico che rappresenta il progetto "ufficiale". Per contribuire a progetti di questo tipo, devi creare il tuo clone pubblico del progetto e inviarvi (con una push) le tue modifiche e successivamente chiedere al mantenitore del progetto di fare una pull delle stesse. Questi può aggiungere il tuo repository come remoto, testarlo localmente, unirlo al proprio branch e fare una push verso il proprio repository. Il processo funziona così (vedi Figura 5-2): +Poiché Git permette di avere repository multipli, è possibile avere un workflow dove ogni sviluppatore ha accesso in scrittura al proprio repository pubblico e accesso in lettura a quello degli altri. Questo scenario spesso prevede anche un repository classico che rappresenta il progetto "ufficiale". Per contribuire a progetti di questo tipo, devi creare il tuo clone pubblico del progetto e inviarvi (con una push) le tue modifiche e successivamente chiedere al mantenitore del progetto di fare una pull delle stesse. Questi può aggiungere il tuo repository come remoto, testarlo localmente, unirlo al proprio branch e fare una push verso il proprio repository. Il processo funziona così (vedi Figura 5-2): 1. Il mantenitore del progetto fa le push sul proprio repository pubblico. 2. Un contributore clona il reposiory ed fa delle cambiamenti. @@ -38,7 +38,7 @@ Questo è un workflow comune con siti come GitHub, dove è facile eseguire un fo ### Workflow con Dittatore e Tenenti ### -Questa è una variante del workflow con multipli repository. E' generalmente usata da grandi progetti con centinaia di collaboratori; un esempio famoso è il Kernel Linux. Molti manager d'integrazione sono in carica di certe parti del repository; sono chiamati tenenti. Tutti i tenenti hanno un manager d'integrazione conosciuto come "dittatore benevolo". Il repository del dittatore benevolo funziona come repository di riferimento dal quale tutti i collaboratori eseguono un pull. Il flusso di lavoro è il seguente (vedi Figura 5-3): +Questa è una variante del workflow con repository multipli. È generalmente usata da grandi progetti con centinaia di collaboratori; un esempio famoso è il Kernel Linux. Molti manager d'integrazione sono in carica di certe parti del repository; sono chiamati tenenti. Tutti i tenenti hanno un manager d'integrazione conosciuto come "dittatore benevolo". Il repository del dittatore benevolo funziona come repository di riferimento dal quale tutti i collaboratori eseguono un pull. Il flusso di lavoro è il seguente (vedi Figura 5-3): 1. Normali sviluppatori lavorano nel loro ramo ed eseguono un rebase del proprio lavoro sul master. Il ramo master è quello del dittatore. 2. I tenenti eseguono l'unione del lavoro degli sviluppatori nel ramo master. From 28d3d3234ad9430c1a41c9e0beea02c673f1f8e1 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 13 Jan 2014 14:24:17 -0600 Subject: [PATCH 094/690] Reviewed "Dictator and Lieutenants Workflow" --- it/05-distributed-git/01-chapter5.markdown | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 187ee22e4..79c733acf 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -38,19 +38,19 @@ Questo è un workflow comune con siti come GitHub, dove è facile eseguire un fo ### Workflow con Dittatore e Tenenti ### -Questa è una variante del workflow con repository multipli. È generalmente usata da grandi progetti con centinaia di collaboratori; un esempio famoso è il Kernel Linux. Molti manager d'integrazione sono in carica di certe parti del repository; sono chiamati tenenti. Tutti i tenenti hanno un manager d'integrazione conosciuto come "dittatore benevolo". Il repository del dittatore benevolo funziona come repository di riferimento dal quale tutti i collaboratori eseguono un pull. Il flusso di lavoro è il seguente (vedi Figura 5-3): +Questa è una variante del workflow con repository multipli. Viene generalmente usata da grandi progetti con centinaia di collaboratori: un esempio famoso è il Kernel Linux. Molti manager d'integrazione sono responsabili di certe parti del repository e vengono chiamati tenenti. Tutti i tenenti hanno un manager d'integrazione conosciuto come "dittatore benevolo". Il repository del dittatore benevolo è il repository di riferimento dal quale tutti i collaboratori prendono il codice. Il flusso di lavoro è il seguente (vedi Figura 5-3): -1. Normali sviluppatori lavorano nel loro ramo ed eseguono un rebase del proprio lavoro sul master. Il ramo master è quello del dittatore. -2. I tenenti eseguono l'unione del lavoro degli sviluppatori nel ramo master. -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. +1. Sviluppatori normali lavorano sul loro branch ed eseguono un `rebase` del proprio lavoro sul master. Il branch master è quello del dittatore. +2. I tenenti uniscono il lavoro degli sviluppatori nel proprio branch master. +3. Il dittatore esegue l'unione dei branch master dei tenenti nel proprio branch master. +4. Il dittatore esegue una push del proprio ramo master nel repository di riferimento, cosicché gli sviluppatori possano accedervi. 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. +Questo tipo di workflow non è comune ma può essere utile in progetti molto grandi o in ambienti con una gerarchia forte, perché consente al leader del progetto (il dittatore) di delegare molto del lavoro e raccogliere vasti sottoinsiemi di codice in punti diversi prima di integrarli. -Ci sono alcuni workflow comunemente utilizzati che sono possibili con un sistema distribuito come Git, ma puoi vedere che esistono molte variazioni attuabili per farlo adattare al tuo caso specifico. Ora che hai (spero) determinato quale workflow può funzionare per te, coprirò alcuni specifici esempi su come determinare i ruoli principali per realizzare differenti workflows. +Ci sono alcuni workflow utilizzati comunemente che sono possibili con un sistema distribuito come Git, ma esistono molte possibili varianti per adattarli al tuo caso specifico. Ora che hai (spero) determinato quale combinazione di workflow possa funzionare per te, illustrerò alcuni esempi sui ruoli principali dei diversi workflow. ## Contribuire ad un Progetto ## From 62618c1e7d7c9b7da6ac6e04b9c8ff0c477f22c3 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 13 Jan 2014 14:25:53 -0600 Subject: [PATCH 095/690] Reviewing "Contributing to a Project" --- it/05-distributed-git/01-chapter5.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 79c733acf..d66cb073a 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -54,7 +54,7 @@ Ci sono alcuni workflow utilizzati comunemente che sono possibili con un sistema ## Contribuire ad un Progetto ## -Sai quali sono i diversi worlflows, e dovresti avere chiari i fondamentali utilizzi di Git. In questa sezione, parleremo di alcuni metodi comuni per contribuire ad un progetto. +Conosci i diversi worlflow e dovresti aver chiaro i fondamentali di Git. In questa sezione imparerai alcuni metodi comuni per contribuire a un progetto. La difficoltà maggiore nel descrivere questo processo, è che ci sono molte variazioni su come può venir fatto. Data la natura flessibile di Git, la gente può lavorare insieme in molti modi, ed è difficile descrivere come dovresti contribuire ad un progetto - ogni progetto è diverso. Alcune delle variabili coinvolte sono la quantità di contributori attivi, il workflow deciso, il tuo tipo di accesso per commit, ed eventualmente il metodo di contribuzione esterno. From 73ee4ebab91efddda6369299165d37ecbf722fbb Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 13 Jan 2014 14:28:01 -0600 Subject: [PATCH 096/690] Reviewing "Contributing to a Project" --- it/05-distributed-git/01-chapter5.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index d66cb073a..3a05919c2 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -54,9 +54,9 @@ Ci sono alcuni workflow utilizzati comunemente che sono possibili con un sistema ## Contribuire ad un Progetto ## -Conosci i diversi worlflow e dovresti aver chiaro i fondamentali di Git. In questa sezione imparerai alcuni metodi comuni per contribuire a un progetto. +Conosci i diversi workflow e dovresti aver chiaro i fondamentali di Git. In questa sezione imparerai alcuni metodi comuni per contribuire a un progetto. -La difficoltà maggiore nel descrivere questo processo, è che ci sono molte variazioni su come può venir fatto. Data la natura flessibile di Git, la gente può lavorare insieme in molti modi, ed è difficile descrivere come dovresti contribuire ad un progetto - ogni progetto è diverso. Alcune delle variabili coinvolte sono la quantità di contributori attivi, il workflow deciso, il tuo tipo di accesso per commit, ed eventualmente il metodo di contribuzione esterno. +La difficoltà maggiore nel descrivere questo processo è che ci sono molte variazioni su come può venir fatto. Poiché Git è molto flessibile la gente può lavorare insieme in molti modi (ed effettivamente lo fa), ed è difficile descrivere come dovresti contribuire ad un progetto: ogni progetto è diverso. Alcune delle variabili coinvolte sono la quantità di contributori attivi, il workflow adottato, il tuo tipo di accesso, ed eventualmente il metodo di contribuzione esterno. La prima variabile è il numero di contributori attivi. Quando utenti attivamente contribuiscono con del codice a questo progetto, e quanto spesso? In molte situazioni avrai una manciata di sviluppatori con alcuni commits al giorno, o forse meno per dei progetti meno attivi. Per azienda o progetti davvero grandi, il numero di sviluppatori potrebbe essere nell'ordine delle migliaia, con dozzine o addirittura di centinaia di patches in arrivo ogni giorno. Questo è importante perché con più sviluppatori vai incontro a più problemi nell'applicare le modifiche in maniera pulita. I cambiamenti che fai potrebbero essere stati resi obsoleti o corrotti da altri che sono stati uniti mentre aspettavi che il tuo lavoro venisse approvato a applicato. Come si può tenere il proprio codice aggiornato e le proprie modifiche valide? From 1315be1a0ea5c6d48c8acb271cae48b29d593791 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 13 Jan 2014 14:33:22 -0600 Subject: [PATCH 097/690] Reviewing "Contributing to a Project" --- it/05-distributed-git/01-chapter5.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 3a05919c2..106a26f0f 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -58,7 +58,7 @@ Conosci i diversi workflow e dovresti aver chiaro i fondamentali di Git. In ques La difficoltà maggiore nel descrivere questo processo è che ci sono molte variazioni su come può venir fatto. Poiché Git è molto flessibile la gente può lavorare insieme in molti modi (ed effettivamente lo fa), ed è difficile descrivere come dovresti contribuire ad un progetto: ogni progetto è diverso. Alcune delle variabili coinvolte sono la quantità di contributori attivi, il workflow adottato, il tuo tipo di accesso, ed eventualmente il metodo di contribuzione esterno. -La prima variabile è il numero di contributori attivi. Quando utenti attivamente contribuiscono con del codice a questo progetto, e quanto spesso? In molte situazioni avrai una manciata di sviluppatori con alcuni commits al giorno, o forse meno per dei progetti meno attivi. Per azienda o progetti davvero grandi, il numero di sviluppatori potrebbe essere nell'ordine delle migliaia, con dozzine o addirittura di centinaia di patches in arrivo ogni giorno. Questo è importante perché con più sviluppatori vai incontro a più problemi nell'applicare le modifiche in maniera pulita. I cambiamenti che fai potrebbero essere stati resi obsoleti o corrotti da altri che sono stati uniti mentre aspettavi che il tuo lavoro venisse approvato a applicato. Come si può tenere il proprio codice aggiornato e le proprie modifiche valide? +La prima variabile è il numero di contributori attivi. Quando utenti contribuiscono attivamente al progetto con del codice e quanto spesso? In molte casi avrai due o tre sviluppatori con poche commit quotidiane, o anche meno per dei progetti semi dormienti. Per azienda o progetti molto grandi, il numero di sviluppatori potrebbe essere nell'ordine delle migliaia, con dozzine o addirittura di centinaia di patches rilasciate ogni giorno. Questa è importante perché con più sviluppatori vai incontro a molti problemi nell'applicare le modifiche in maniera pulita o che queste possano essere facilmente integrate. I cambiamenti che fai potrebbero essere stati resi obsoleti o corrotti da altri che sono stati integrati mentre lavoravi o mentre aspettavi che il tuo lavoro venisse approvato o applicato. Come puoi mantenere il tuo codice aggiornato e le tue modifiche valide? La prossima variabile è il workflow in uso nel progetto. E' centralizzato, con ogni sviluppatore avente lo stesso tipo di accesso in scrittura nel repository principale? Il progetto ha un manager d'integrazione che controlla tutte le modifiche? Tutte le modifiche sono riviste da più persone ed approvate? Sei coinvolto in questo processo? E' un sistema con dei tenenti, e devi fornire a loro il tuo lavoro innanzitutto? From 4bffe04dc02314e7149e497307d9f45899b8948f Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 13 Jan 2014 14:45:08 -0600 Subject: [PATCH 098/690] Reviewed "Contributing to a Project" --- it/05-distributed-git/01-chapter5.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 106a26f0f..7ee8bbd16 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -60,11 +60,11 @@ La difficoltà maggiore nel descrivere questo processo è che ci sono molte vari La prima variabile è il numero di contributori attivi. Quando utenti contribuiscono attivamente al progetto con del codice e quanto spesso? In molte casi avrai due o tre sviluppatori con poche commit quotidiane, o anche meno per dei progetti semi dormienti. Per azienda o progetti molto grandi, il numero di sviluppatori potrebbe essere nell'ordine delle migliaia, con dozzine o addirittura di centinaia di patches rilasciate ogni giorno. Questa è importante perché con più sviluppatori vai incontro a molti problemi nell'applicare le modifiche in maniera pulita o che queste possano essere facilmente integrate. I cambiamenti che fai potrebbero essere stati resi obsoleti o corrotti da altri che sono stati integrati mentre lavoravi o mentre aspettavi che il tuo lavoro venisse approvato o applicato. Come puoi mantenere il tuo codice aggiornato e le tue modifiche valide? -La prossima variabile è il workflow in uso nel progetto. E' centralizzato, con ogni sviluppatore avente lo stesso tipo di accesso in scrittura nel repository principale? Il progetto ha un manager d'integrazione che controlla tutte le modifiche? Tutte le modifiche sono riviste da più persone ed approvate? Sei coinvolto in questo processo? E' un sistema con dei tenenti, e devi fornire a loro il tuo lavoro innanzitutto? +La variabile successiva è il workflow usato nel progetto. È centralizzato, con ogni sviluppatore con lo stesso tipo di accesso in scrittura sul repository principale? Il progetto ha un manager d'integrazione che controlla tutte le modifiche? Tutte le modifiche sono riviste da più persone ed approvate? Sei coinvolto in questo processo? È un sistema con dei tenenti, e devi inviare a loro il tuo lavoro? -Il problema successivo è il tuo accesso per il commit. Il workflow richiesto per poter contribuire al progetto è molto diverso a seconda del fatto che tua abbia accesso in scrittura o no. Se non hai accesso in scrittura, come viene preferito il lavoro dei contributori? Esiste qualche regola a riguardo? Quando contribuisci per volta? Quanto spesso? +Il problema successivo riguarda i tuoi permessi per effettuare commit. Il workflow richiesto per poter contribuire al progetto è molto diverso a seconda del fatto che tua abbia accesso in scrittura o solo lettura. Se non hai accesso in scrittura, qual'è il modo preferito dal progetto per accettare il lavoro dei contributori? Esistono regole a riguardo? Quanto contribuisci? Quanto spesso? -Tutte queste domande possono influire effettivamente sul progetto e sul tipo di workflow preferibile per la tua situazione. Coprirò aspetti di ognuno di questi in una serie di casi d'uso, spaziando dal semplice al complesso; dovresti essere capace di ricostruire il workflow specifico per il tuo caso basandoti sugli esempi. +Tutte queste domande possono influire sul modo in cui contribuisci al progetto e quale tipo di workflow sia quello preferito o disponibile. Illustrerò gli aspetti di ciascuno di questi in una serie di casi d'uso, dal più semplice al più complesso: dovresti essere capace di definire il workflow specifico per il tuo caso basandoti su questi esempi. ### Linee guida per il commit ### From d578f0fa9c42ec1f7afc23764c52b1dc812a9cc5 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 13 Jan 2014 14:46:22 -0600 Subject: [PATCH 099/690] Reviewing "Commit Guidelines" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit è femminile --- it/05-distributed-git/01-chapter5.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 7ee8bbd16..c2272898f 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -66,7 +66,7 @@ Il problema successivo riguarda i tuoi permessi per effettuare commit. Il workfl Tutte queste domande possono influire sul modo in cui contribuisci al progetto e quale tipo di workflow sia quello preferito o disponibile. Illustrerò gli aspetti di ciascuno di questi in una serie di casi d'uso, dal più semplice al più complesso: dovresti essere capace di definire il workflow specifico per il tuo caso basandoti su questi esempi. -### Linee guida per il commit ### +### Linee guida per le commit ### Prima di guardare ai casi specifici, una breve nota riguardo ai messaggi di commit. Avere una linea guida per creare commit e aderirvi rende il lavoro con Git e la collaborazione con altri molto più semplice. Il progetto Git fornisce un documento che da alcuni suggerimenti per la creazione di messaggi di commit - puoi leggerlo nel codice sorgente di Git nel file `Documentation/SubmittingPatches`. From bef44856f5b5f2f4c0da838800fc20355d20e873 Mon Sep 17 00:00:00 2001 From: Christian Finnberg Date: Mon, 13 Jan 2014 23:24:43 +0200 Subject: [PATCH 100/690] Update 01-chapter5.markdown Fixed typo. --- es/05-distributed-git/01-chapter5.markdown | 346 +-------------------- 1 file changed, 2 insertions(+), 344 deletions(-) diff --git a/es/05-distributed-git/01-chapter5.markdown b/es/05-distributed-git/01-chapter5.markdown index 2f4f74e7e..91972492e 100644 --- a/es/05-distributed-git/01-chapter5.markdown +++ b/es/05-distributed-git/01-chapter5.markdown @@ -1,6 +1,6 @@ # Git en entornos distribuidos # -Ahora que ya tienes un repositorio Git, configurado como punto de trabajo para compartir código entre desarrolladores. Y ahora que ya conoces los comandos básicos de Git para flujos de trabajo locales. Puedes hechar un vistazo a algunos de los flujos de trabajo distribuidos que Git permite. +Ahora que ya tienes un repositorio Git, configurado como punto de trabajo para compartir código entre desarrolladores. Y ahora que ya conoces los comandos básicos de Git para flujos de trabajo locales. Puedes echar un vistazo a algunos de los flujos de trabajo distribuidos que Git permite. En este capítulo, verás cómo trabajar con Git en un entorno distribuido, bien como colaborador o bien como integrador. Es decir, aprenderás cómo contribuir adecuadamente a un proyecto; de la forma más efectiva posible, tanto para tí, como para quien gestione el proyecto. Y aprenderás también a gestionar proyectos en los que colaboren multiples desarrolladores. @@ -545,346 +545,4 @@ Tras esto, Git escupirá una serie de información de registro, con pinta más o 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 - -En estos momentos, deberías poder ir a tu carpeta de borradores (Drafts), cambiar el destinatario (To) para apuntar a la lista de correo donde estés enviando el parche, puede que poner en copia (CC) al gestor o persona responsable, y enviar el mensaje. - -### Recapitulación ### - -En esta sección hemos visto unos cuantos de los flujos de trabajo más habituales para lidiar con distintos tipos de proyectos Git. Y hemos introducido un par de nuevas herramientas para ayudarte a gestionar estos procesos. A continuación veremos cómo trabajar en el otro lado de la moneda: manteniendo y gestionando un proyecto Git. Vas a aprender cómo ser un dictador benevolente o un gestor de integración. - -## Gestionando un proyecto ## - -Además de conocer cómo contribuir de forma efectiva a un proyecto, es posible que desees saber tambien cómo mantener uno. Lo cual implicará saber aceptar y aplicar parches generados vía `format-patch`, enviados a tí a través de correo-e; o saber integrar cambios realizados en ramas de repositorios que añadirás como remotos a tu proyecto. Tanto si gestionas un repositorio canónico, como si deseas colaborar verificando o aprobando parches, necesitas saber cómo aceptar trabajo de otros de la forma más clara para tus contribuyentes y más sostenible para tí a largo plazo. - -### 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--. -Como recordarás, la forma de crear una rama basandola en tu rama master es: - - $ git branch sc/ruby_client master - -O, si deseas crearla y saltar inmediatamente a ella, puedes también utilizar la opción '-b' del comando 'checkout': - - $ git checkout -b sc/ruby_client master - -Tras esto, estarás listo para añadir tu trabajo a esa rama puntual y ver si deseas o no fusionarla luego con alguna otra de tus ramas de más largo recorrido. - -### Aplicar parches recibidos por correo-e ### - -Si vas a integrar en tu proyecto un parche recibido a través de un correo electrónico. Antes de poder evaluarlo, tendrás que incorporarlo a una de tus ramas puntuales. Tienes dos caminos para incorporar un parche recibido por correo-e: usando el comando 'git apply' o usando el comando 'git am'. - -#### Incorporando un parche con apply #### - -Si recibes un parche de alguien que lo ha generado con el comando 'git diff' o con un comando 'diff' de Unix, puedes incorporalo con el comando 'git apply'. Suponiendo que has guardado el parche en '/tmp/patch-ruby-client.patch', puedes incorporarlo con una orden tal como: - - $ git apply /tmp/patch-ruby-client.patch - -Esto modificará los archivos en tu carpeta de trabajo. Es prácticamente idéntico a lanzar el comando 'patch -p1', aunque es más paranoico y acepta menos coincidencias aproximadas. Además, es capaz de manejar adicciones, borrados o renombrados de archivos, si vienen en formato 'git diff'. Mientras que 'patch' no puede hacerlo. Por ultimo, citar que 'git apply' sigue un modelo de "aplicar todo o abortar todo", incorporando todos los cambios o no incorporando ninguno. Mientras que 'patch' puede incorporar cambios parcialmente, dejando tu carpeta de trabajo en un estado inconsistente. 'git apply' es, de lejos, mucho más paranoico que 'patch'. Nunca creará una confirmación de cambios (commit) por tí, --tras ejecutar el comando, tendrás que preparar (stage) y confirmar (commit) manualmente todos los cambios introducidos--. - -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 - error: patch failed: ticgit.gemspec:1 - error: ticgit.gemspec: patch does not apply - -Si obtienes una salida vacia, el parche se podrá incorporar limpiamente. Además, este comando retorna con un status no-cero en caso de fallar la comprobación, por lo que puedes utilizarlo en scripts si lo deseas. - -#### Incorporando un parche con am #### - -Si la persona que contribuye es usuaria de Git y conoce lo suficiente como para utilizar el comando 'format-patch' al generar su parche, tendrás mucho camino recorrido al incorporarlo; ya que el parche traerá consigo información sobre el o la autora, además de un mensaje de confirmación de cambios. Si puedes, anima a tus colaboradoras a utilizar 'format-patch' en lugar de 'diff' cuando vayan a generar parches. Solo deberías utilizar 'git apply' en caso de parches antiguos y similares. - -Para incorporar un parche generado con 'format-patch', utilizarás el comando 'git am'. Técnicamente, 'git am' se construyó para leer un archivo de buzón de correo (mbox file), que no es más que un simple formato de texto plano para almacenar uno o varios mensajes de correo electrónico en un solo archivo de texto. Es algo parecido a esto: - - 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 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. - -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 - 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: - - $ 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 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. - -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 - 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". - -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 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 - 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. - -En este caso, estamos intentando incorporar un parche que ya tenemos incorporado. Sin la opción '-3', tendríamos problemas. - -Al aplicar varios parches desde un mbox, puedes lanzar el comando 'am' en modo interactivo; haciendo que se detenga en cada parche y preguntandote si aplicarlo o no: - - $ 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 - -Es una utilidad interesante si tienes tienes almacenados unos cuantos parches, porque puedes ir revisando previamente cada parche y aplicarlos selectivamente. - -Cuando tengas integrados y confirmados todos los parches relativos al tema puntual en que estas trabajando, puedes plantearte cómo y cuándo lo vas a integar en alguna otra rama de más largo recorrido. - -### Recuperando ramas remotas ### - -Si recibes una contribución de un usuario que ha preparado su propio repositorio, ha guardado unos cuantos cambios en este, y luego te ha enviado la URL del repositorio y el nombre de la rama remota donde se encuentran los cambios. Puedes añadir dicho repositorio como un remoto y fusionar los cambios localmente. - -Por ejemplo, si Jessica te envia un correo electrónico comentandote que tiene una nueva e interesante funcionalidad en la rama 'ruby-client' de su repositorio. Puedes probarla añadiendo el remoto correspondiente y recuperando localmente dicha rama. - - $ git remote add jessica git://github.com/jessica/myproject.git - $ git fetch jessica - $ git checkout -b rubyclient jessica/ruby-client - -Si más tarde vuelva a enviarte otro correo-e avisandote de otra gran funcionalidad que ha incorporado, puedes recuperarla (fetch y checkout) directamente, porque tienes el remoto ya definido. - -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. - -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: - - $ git pull git://github.com/onetimeguy/project.git - From git://github.com/onetimeguy/project - * branch HEAD -> FETCH_HEAD - Merge made by recursive. - -### Revisando lo introducido ### - -Ahora que tienes una rama puntual con trabajo aportado por otras personas. Tienes que decidir lo que deseas hacer con él. En esta sección revisaremos un par de comandos, que te ayudarán a ver exactamente los cambios que introducirás si fusionas dicha rama puntual con tu rama principal. - -Suele ser util revisar todas las confirmaciones de cambios (commits) que esten es esta rama, pero no en tu rama principal. Puedes excluir de la lista las confirmaciones de tu rama principal añadiendo la opción '--not' delante del nombre de la rama. Por ejemplo, si la persona colaboradora te envia dos parches y tu creas una rama 'contrib' donde aplicar dichos parches; puedes lanzar algo como esto: - - $ 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 - -Para ver en detalle los cambios introducidos por cada confirmación (commit), recuerda que pasando la opción '-p' al comando 'git log', obtendrás un listado extendido con las diferencias introducidas por cada confirmación. - -Para ver plenamente todas las diferencias y lo que sucederá realmente si fusionas esta rama puntual con otra rama, tendrás que utilizar un pequeño truco para obtener los resultados correctos. Puedes pensar en lanzar esto: - - $ git diff master - -Este comando te dará las diferencias, pero puede ser engañoso. Si tu rama 'master' ha avanzado con respecto al momento en que se creó la rama puntual a partir de ella, puedes obtener resultados realmente extraños. Debido a que Git compara directamente las instantáneas de la última confirmación de cambios en la rama puntual donde te encuentras y en la rama 'master'. Por ejemplo, si en la rama 'master' habias añadido una línea a un archivo, la comparación directa de instantáneas te llevará a pensar que la rama puntual va a borrar dicha línea. - -Si 'master' es un ancestro directo de tu rama puntual, no tendrás problemas. Pero si los historiales de las dos ramas son divergentes, la comparación directa de diferencias dará la apariencia de estar añadiendo todo el material nuevo en la rama puntual y de estar borrando todo el material nuevo en la rama 'master'. - -Y lo que realmente querías ver eran los cambios introducidos por la rama puntual, --el trabajo que vas a introducir si la fusionas con la rama 'master'--. Lo puedes hacer indicando a Git que compare la última confirmación de cambios en la rama puntual, con el más reciente ancestro común que tenga esta respecto de la rama 'master'. - -Técnicamente, lo puedes hacer descubriendo tu mismo dicho ancestro común y lanzando la comprobación de diferencias respecto de él: - - $ git merge-base contrib master - 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 - $ 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: - - $ git diff master...contrib - -Este comando mostrará únicamente el trabajo en tu actual rama puntual que haya sido introducido a partir de su ancestro común con la rama 'master'. Es una sintaxis muy util, que merece recordar. - -### Integrando el trabajo aportado por otros ### - -Cuando todo el trabajo presente en tu rama puntual esté listo para ser integrado en una rama de mayor rango, la cuestión es cómo hacerlo. Yendo aún más lejos, ?cual es el sistema de trabajo que deseas utilizar para el mantenimiento de tu proyecto? Tienes bastantes opciones, y vamos a ver algunas de ellas. - -#### Fusionando flujos de trabajo #### - -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 -Figura 5-19. Historial con varias ramas puntuales. - -Insert 18333fig0520.png -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). - -Insert 18333fig0521.png -Figura 5-21. Antes de fusionar una rama puntual. - -Insert 18333fig0522.png -Figura 5-22. Tras fusionar una rama puntual. - -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. -Puedes continuar ampliando este concepto, disponiendo de una rama 'integrate' donde ir fusionando todo el trabajo entre sí. A continuación, cuando el código en dicha rama sea estable y pase todas las pruebas, la fusionarás con la rama 'develop'; y, cuando se demuestre que permanece estable durante un cierto tiempo, avanzarás la rama 'master' hasta ahí. - -#### Flujos de trabajo con grandes fusiones #### - -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 -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 -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. - -#### Flujos de trabajo reorganizando o entresacando #### - -Otros gestores de mantenimiento, al procesar el trabajo recibido de las personas colaboradoras, en lugar de fusiones (merge), suelen preferir reorganizar (rebase) o entresacar (cherry-pick) sobre su propia rama principal; obteniendo así un historial prácticamente lineal. Cuando desees integrar el trabajo que tienes en una rama puntual, te puedes situar sobre ella y lanzar el comando 'rebase'; de esta forma recompondrás los cambios encima de tu actual rama 'master' (o 'develop' o lo que corresponda). Si funciona, se realizará un avance rápido (fast-forward) en tu rama 'master', y acabarás teniendo un historial lineal en tu proyecto. - -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 -Figura 5-26. Historial de ejemplo, antes de entresacar. - -Si deseas integar únicamente la confirmación 'e43a6' en tu rama 'master', puedes lanzar: - - $ 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(-) - -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 -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. - -### Marcando tus lanzamientos de versiones ### - -Cuando decides dar por preparada una versión, probablemente querrás etiquetar dicho punto de algún modo; de tal forma que, más adelante, puedas volver a generar esa versión en cualquier momento. Puedes crear una nueva etiqueta tal y como se ha comentado en el capítulo 2. Si decides firmar la etiqueta como gestor de mantenimientos que eres, el proceso será algo como: - - $ 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 - -Si firmas tus etiquetas, puedes tener un problema a la hora de distribuir la clave PGP pública utilizada en la firma. Los gestores del proyeto Git ha resuelto este problema incluyendo sus claves públicas como un objeto en el repositorio, añadiendo luego una etiqueta apuntando directamente a dicho contenido. Para ello, has de seleccionar cada clave que deseas incluir, lanzando el comando '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] - -Tras esto, puedes importar directamente la clave en la base de datos Git, exportandola y redirigiendola a través del comando 'git hash-object'. Para, de esta forma, escribir un nuevo objeto dentro de Git y obtener de vuelta la firma SHA-1 de dicho objeto. - - $ gpg -a --export F721C45A | git hash-object -w --stdin - 659ef797d181633c87ec71ac3f9ba29fe5775b92 - -Una vez tengas el contenido de tu clave guardado en Git, puedes crear una etiquta que apunte directamente al mismo; indicando para ello el nuevo valor SHA-1 que te ha devuelto el objeto 'hash-object': - - $ 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:, - - $ git show maintainer-pgp-pub | gpg --import - -De esta forma, pueden utilizar esa clave para verificar todas las etiquetas que firmes. Además, si incluyes instrucciones en el mensaje de etiquetado, con el comando `git show `, los usuarios podrán tener directrices específicas acerca de la verificación de etiquetas. - -### Generando un número de ensamblado ### - -Debido a que Git no dispone de una serie monótona ascendente de números para cada confirmación de cambios (commit), si deseas tener un nombre humanamente comprensible por cada confirmación, has de utilizar el comando 'git describe'. Git te dará el nombre de la etiqueta más cercana, mas el número de confirmaciones de cambios entre dicha etiqueta y la confirmación que estas describiendo, más una parte de la firma SHA-1 de la confirmación: - - $ git describe master - v1.6.2-rc1-20-g8c5b85c - -De esta forma, puedes exportar una instantánea u obtener un nombre comprensible por cualquier persona. Es más, si compilas Git desde código fuente clonado desde el repositorio Git, el comando 'git --version' te dará algo parecido. Si solicitas descripción de una confirmación de cambios (commit) etiquetada directamente con su propia etiqueta particular, obtendrás dicha etiqueta como descripción. - -El comando 'git describe' da preferencia a las etiquetas anotativas (etiquetas creadas con las opciones '-a' o '-s'). De esta forma las etiquetas para las versiones pueden ser creadas usando 'git describe', asegurandose el que las confirmaciones de cambios (commit) son adecuadamente nombradas cuando se describen. Tambien puedes utilizar esta descripción para indicar lo que deseas activar (checkout) o mostrar (show); pero realmente estarás usando solamente la parte final de la firma SHA-1 abreviada, por lo que no siempre será válida. Por ejemplo, el kernel de Linux ha saltado recientemente de 8 a 10 caracteres, para asegurar la unicidad de los objetos SHA-1; dando como resultado que los nombres antiguos de 'git describe' han dejado de ser válidos. - -### Preparando un lanzamiento de versión ### - -Si quieres lanzar una nueva versión. Una de las cosas que desearas crear es un archivo con la más reciente imagen de tu código, para aquellas pobres almas que no utilizan Git. El comando para hacerlo es 'git archive': - - $ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz - $ ls *.tar.gz - v1.6.2-rc1-20-g8c5b85c.tar.gz - -Quien abra ese archivo tarball, obtendrá la más reciente imagen de tu proyecto; puesta bajo una carpeta de proyecto. También puedes crear un archivo zip de la misma manera, tan solo indicando la opción '--format=zip' al comando 'git archive': - - $ git archive master --prefix='project/' --format=zip > `git describe master`.zip - -Así, tendrás sendos archivos tarball y zip con tu nueva versión, listos para subirlos a tu sitio web o para ser enviados por correo electrónico a tus usuarios. - -### El registro rápido ### - -Ya va siendo hora de enviar un mensaje a tu lista de correo, informando a las personas que desean conocer la marcha de tu proyecto. Una manera elegante de generar rápidamente una lista con los principales cambios añadidos a tu proyecto desde la anterior versión, es utilizando el comando 'git shortlog'. Este comando resume todas las confirmaciones de cambios (commits) en el rango que le indiques. Por ejemplo, si tu último lanzamiento de versión lo fué de la 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 - -Obtendrás un claro resumen de todas las confirmaciones de cambios (commit) desde la versión v1.0.1, agrupadas por autor, y listas para ser incorporadas en un mensaje a tu lista de correo. - -## Recapitulación ## - -A estas alturas, deberías sentirte confortable tanto contribuyendo a un proyecto, como manteniendo tu propio proyecto o integrando contribuciones de otras personas. Felicidades por haber llegado a ser un desarrollador Git efectivo!. En el capítulo siguiente, aprenderás el uso de más herramientas avanzadas y algunos trucos para tratar con situaciones complejas; haciendo de tí un verdadero maestro Git. + Message-Id: <12437153 From e85c37f16805ca4d0c6c613cb6c16f5811176b6f Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 13 Jan 2014 16:39:22 -0600 Subject: [PATCH 101/690] Reviewed "Commit Guidelines" --- it/05-distributed-git/01-chapter5.markdown | 36 ++++++++++------------ 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index c2272898f..19cb4562c 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -68,9 +68,9 @@ Tutte queste domande possono influire sul modo in cui contribuisci al progetto e ### Linee guida per le commit ### -Prima di guardare ai casi specifici, una breve nota riguardo ai messaggi di commit. Avere una linea guida per creare commit e aderirvi rende il lavoro con Git e la collaborazione con altri molto più semplice. Il progetto Git fornisce un documento che da alcuni suggerimenti per la creazione di messaggi di commit - puoi leggerlo nel codice sorgente di Git nel file `Documentation/SubmittingPatches`. +Prima di vedere i casi specifici faccio una breve nota riguardo i messaggi delle commit. Avere una linea guida per le commit e aderirvi rende il lavoro con Git e la collaborazione con altri molto più semplice. Il progetto di Git fornisce un documento che da molti suggerimenti circa le commit per da cui creare patch: puoi trovarlo nel codice sorgente di Git nel file `Documentation/SubmittingPatches`. -Innanzitutto, non è il caso di inserire spazi bianchi. Git fornisce un modo semplice per cercarli - prima di un commit, esegui `git diff --check`, che identifica possibili errori riguardanti spazi bianchi e li lista per te. Qui c'è un esempio, dove ho sistituiro il colore rosso del terminale con delle lettere `X`: +Innanzitutto non è il caso di inviare errori con degli spazi. Git fornisce un modo semplice per verificarli: esegui, prima di un commit, `git diff --check`, che identifica possibili errori riguardanti gli spazi e li elenca per te. Qui c'è un esempio in cui ho sostituiro il colore rosso del terminale con delle `X`: $ git diff --check lib/simplegit.rb:5: trailing whitespace. @@ -80,34 +80,32 @@ Innanzitutto, non è il caso di inserire spazi bianchi. Git fornisce un modo sem lib/simplegit.rb:26: trailing whitespace. + def command(git_cmd)XXXX -Se esegui quel commando prima del commit, puoi vedere se stai per inserire degli spazi bianchi che potrebbero infastidire altri sviluppatori. +Se esegui il commando prima della commit, puoi vedere se stai per committare degli spazi bianchi che potrebbero infastidire altri sviluppatori. -In seguito, prova a rendere ogni commit un insieme logico di cambiamenti. Se puoi, cerca di rendere i cambiamenti "digeribili" - non scrivere codice per un intero weekend su cinque diversi problemi e poi fare un commit massivo il Lunedì. Anche se non esegui commit nel weekend, usa l'area di staging il Lunedì per suddividere il tuo lavoro in almeno un commit per problema, con un utile messaggio. Se diverse modifiche coinvolgono lo stesso file, usa `git add --patch` per aggiungere file in maniera parziale all'area di staging (spiegato nel dettaglio nel capitolo 6). Il risultato finale sarà lo stesso sia che tu faccia un commit sia che tu ne faccia cinque, finché tutti i cambiamenti sono aggiunti ad un certo punto, per cui cerca di rendere le cose più semplici ai tuoi colleghi sviluppatori quando devono controllare i tuoi cambiamenti. Questo approccio inoltre rende più semplice includere o escludere uno dei cambiamenti nel caso ti serva in seguito. Il capitolo 6 descrive una manciata di utili trucchetti di Git per riscrivere la storia ed aggiungere files all'area di staging in maniera interattiva - usa questi strumenti per mantenere una comprensibile cronologia. +Cerca quindi di aver per ciascuna commit un insieme logico di modifiche. Se puoi, cerca di rendere i cambiamenti "digeribili": non lavorare per un intero fine settimana su cinque diversi problemi per fare poi una commit massiva il lunedì. Anche se non fai commit nel weekend, il lunedì usa l'area di staging per suddividere il tuo lavoro in almeno un commit per problema con un messaggio utile per ciascuna. Se modifiche diverse coinvolgono lo stesso file, usa `git add --patch` per aggiungere parti del file all'area di staging (trattato in dettaglio nel capitolo 6). Il risultato finale sarà lo stesso che tu faccia una o cinque commit quando queste vengano integrate in un punto, per cui cerca di rendere le cose più semplici ai tuoi colleghi sviluppatori quando devono controllare le tue modifiche. Questo approccio inoltre rende più semplice includere o escludere alcuni dei cambiamenti, nel caso ti serva successivamente. Il capitolo 6 descrive una serie di trucchi di Git utili per riscrivere la storia e aggiungere interattivamente file all'area di staging: usa questi strumenti per mantenere la cronologia pulita e comprensibile. -L'ultima cosa da tenere in mente è il messaggio di commit. Prendere l'abitudine di creare messaggi di commit di qualità rende usare e collaborare tramite Git molto più semplice. Come regola generale, i tuoi messaggi dovrebbero iniziare con una singola linea di al massimo 50 caratteri che descrive il set di cambiamenti in maniera concisa, seguito da una linea bianca, ed in seguito una spiegazione dettagliata. Il progetto Git richiede che la spiegazione dettagliata includa il motivo del cambiamento ed il confronto con il comportamento precedente - questa è una buona linea guida da seguire. E' anche una buona idea usare la forma imperativa nel messaggio. In altre parole, usa dei comandi. Al posto di "Ho aggiunto dei test per" oppure "Aggiungere dei test per", usa "Aggiunti dei test per". -Questo è un modello scritto originariamente da Tim Pope su tpope.net: +L'ultima cosa da tenere a mente è il messaggio di commit. Prendere l'abitudine di creare messaggi di commit di qualità rende l'uso e la collaborazione tramite Git molto più semplice. Come regola generale, i tuoi messaggi dovrebbero iniziare con una sola linea di massimo 50 caratteri che descriva sinteticamente l'insieme delle modifiche seguito da una linea bianca e quindi una spiegazione dettagliata. Il progetto di Git prevede che una spiegazione molto dettagliata includa il motivo della modifica e confrontare l'implementazione committata con la precedente: questa è una buona linea guida da seguire. È una buona idea anche usare l'imperativo presente in questi messaggi. In altre parole, usa dei comandi. Al posto di "Ho aggiunto dei test per" o "Aggiungendo test per", usa "Aggiungi dei test per". +Questo modello è stato originariamente scritto da Tim Pope su tpope.net: Breve (50 caratteri o meno) riassunto delle modifiche - Testo di spiegazione più dettagliato, se necessario. Suddividilo ogni - circa 72 caratteri. In alcuni contesti, la prima linea è trattata - come l'oggetto di un'email, ed il resto come il contenuto. La linea - vuota che separa il riassunto dal testo è importante (a meno che tu - non ometta il testo del tutto); strumenti come rebase possono andare - in confusione senza di essa. + Spiegazione più dettagliata, se necessario. Manda a capo ogni 72 caratteri + circa. In alcuni contesti, la prima linea è trattata come l'oggetto di + un'email, ed il resto come il contenuto. La linea vuota che separa l'oggetto + dal testo è importante (a meno che tu non ometta il testo del tutto): + strumenti come rebase possono confondersi se non dovesse esserci. - Ulteriore paragrafo dopo alcune linee vuote. + Ulteriori paragrafi vanno dopo altre linee vuote. - Le liste puntate sono concesse - - Di solito un trattino od un asterisco viene usato come separatore, - preceduto da uno spazio singolo, con linee vuote tra i punti, - ma le convenzioni potrebbero variare in questo caso + - Di solito viene usato un trattino o un asterisco come separatore, + preceduto da uno spazio singolo, con delle linee vuote tra i punti, + ma le convenzioni possono essere diverse -Se tutti i tuoi messaggi di commit hanno questo aspetto, le cose saranno molto più semplici per per te e gli sviluppatore con cui lavori. Il progetto Git ha dei messaggi di commit ben formattati - ti incoraggio ad eseguire `git log --no-merges` per vedere qual'è l'aspetto di una cronologia ben leggibile. +Se tutti i tuoi messaggi di commit fossero così, per te e gli altri sviluppatori con cui lavori le cose saranno molto più semplici per te e per gli sviluppatore con cui lavori. Il progetto di Git ha dei messaggi di commit ben formattati: ti incoraggio a eseguire `git log --no-merges` per vedere qual è l'aspetto di una cronologia ben leggibile. -Nei seguenti esempi, ed attraverso la maggior parte di questo libro, per brevità non formatterò i messaggi così accuratamente; invece userò l'opzione `-m` di `git commit`. -Fa come dico, non come faccio. +Nei esempi che seguono e nella maggior parte di questo libro, per brevità, non formatterò i messaggi accuratamente come descritto: userò invece l'opzione `-m` di `git commit`. Fa' come dico, non come faccio. ### Piccoli team privati ### From 91bb38964f03435a1c2be1dc8a2eff07a685b279 Mon Sep 17 00:00:00 2001 From: "Ann + J.M" Date: Wed, 15 Jan 2014 00:39:58 +0100 Subject: [PATCH 102/690] [de] Fix typos in section 6 --- de/06-git-tools/01-chapter6.markdown | 110 +++++++++++++-------------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index 39e8c219d..a5143a50e 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -695,18 +695,18 @@ 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, sodass 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. +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 einen 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, sodass 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, sodass Du Dein Ergebnis danach mit anderen teilen kannst und es damit Deinem gewünschten Ergebnis entspricht. +In diesem Kapitel werden wir die nützlichen Arbeitsschritte besprechen, die Dir helfen, Deine Commit-Historie Deinen Wünschen entsprechend zu gestalten, sodass 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. +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 eigentlichen Inhalt des Schnappschusses durch Hinzufügen, Ändern oder Löschen von Dateien. @@ -716,7 +716,7 @@ Die letzte Commit-Nachricht noch einmal zu ändern ist sehr einfach: -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. +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ältst einen neuen Commit mit dem gleichen Inhalt und Deiner neuen Commit-Nachricht. @@ -731,22 +731,22 @@ Mit dem Befehl `--amend` sollte man vorsichtig umgehen, weil mit jeder nachträg -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. +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. +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 den ü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. +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ältst Du Dich nicht daran, werden sich andere Entwickler über Dich ärgern oder wundern, weil es jetzt eine alternative Version 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: +Wenn Du den Befehl ausführst, erhältst 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 @@ -765,7 +765,7 @@ Wenn Du den Befehl ausführst, erhälst Du eine Reihe von Commits in Deinem Text -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: +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 @@ -774,7 +774,7 @@ Vielleicht ist es Dir schon aufgefallen, die Commits werden genau in der umgekeh -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. +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 bedeutet, dass anstatt des neuesten, der älteste Commit ganz oben steht, weil dieser der erste Commit ist, der bearbeitet wird. @@ -786,7 +786,7 @@ Du musst das Skript so anpassen, dass es an jedem Commit anhält, den Du ändern -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: +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 @@ -812,7 +812,7 @@ Im sich öffnenden Texteditor kannst Du jetzt die Commit-Nachricht ändern und d -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`). +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 ### @@ -863,7 +863,7 @@ Wenn Du statt „pick“ oder „edit“, den Befehl „squash“ angibst, führ -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: +Nach dem Speichern und Beenden des Editors, 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. @@ -887,7 +887,7 @@ Du kannst nun die Commit-Nachricht entsprechend anpassen oder auch entsprechend -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: +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 angezeigte 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 @@ -895,7 +895,7 @@ Man kann mit Git einen einzelnen Commit auch aufsplitten. Das bedeutet, man setz -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: +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 dass die Änderungen im Arbeitsverzeichnis zurückgesetzt werden. Das heißt, der Commit im Repository wird 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 @@ -906,7 +906,7 @@ Nach dem Speichern und Schließen des Editors, setzt Git die Änderungen entspre -Git speichert dazu den letzten Commit (`a5f4a0d`) aus dem Skript im Repository. Das Resultet sieht in etwa folgendermaßen aus: +Git speichert dazu den letzten Commit (`a5f4a0d`) aus dem Skript im Repository. Das Resultat sieht in etwa folgendermaßen aus: $ git log -4 --pretty=format:"%h %s" 1c002dd added cat-file @@ -916,21 +916,21 @@ Git speichert dazu den letzten Commit (`a5f4a0d`) aus dem Skript im Repository. -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. +Ich möchte Dich noch einmal darauf hinweisen, dass jede SHA-Prüfsumme von allen Commits aus 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. +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 wurden). 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: +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) @@ -964,7 +964,7 @@ Nach der Ausführung dieses Befehls ist das „trunk“ Verzeichnis das neue Arb -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`: +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" ]; @@ -978,7 +978,7 @@ Verflixt, es ist schon wieder passiert. Du hast vergessen den Befehl `git config -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. +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 wird 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 ## @@ -992,7 +992,7 @@ Git bietet auch ein paar Werkzeuge, die den Debug-Vorgang bei einem Projekt unte -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: +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') @@ -1009,11 +1009,11 @@ Wenn Du nach einem Bug in Deinem Code suchst und gerne wissen willst, wann und w -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 bisschen 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. +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 bisschen 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: +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 aufgeteilt, 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) @@ -1032,18 +1032,18 @@ Eine weitere herausragende Eigenschaft von Git ist die Tatsache, dass es nicht p -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 ist enorm hilfreich. Für gewöhnlich erhältst 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. +`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]`: +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 @@ -1053,7 +1053,7 @@ Nehmen wir zum Beispiel an, dass Du gerade eben Deinen Code in einer Produktivum -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: +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 @@ -1061,7 +1061,7 @@ Nach Ausführen des letzten Befehls, zeigt Git Dir als erstes an, dass in etwa 1 -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 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 @@ -1069,7 +1069,7 @@ Git hat Dir jetzt einen weiteren Commit ausgecheckt und zwar wieder den mittlere -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 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 @@ -1090,14 +1090,14 @@ Wenn Du fertig mit der Fehlersuche bist, solltest Du den Befehl `git bisect rese -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: +Wie Du vielleicht gesehen hast, ist dieser Befehl ein mächtiges Werkzeug, um Hunderte von Commits 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. +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 eines Skripts kannst Du natürlich auch `make` oder `make tests` oder eine beliebige, andere Testumgebung starten. ## Submodule ## @@ -1108,7 +1108,7 @@ Oft möchte man während der Arbeit an einem Projekt ein weiteres Projekt darin -Dazu ein Beispiel. Nehmen wir an, Du entwickelt gerade eine Webseite, die unter anderem einen Atom-Feed zur Verfügung stellen soll. Anstatt den notwendigen Code zur Auslieferung des Atom-Feeds selber zu schreiben, entscheidest Du Dich für eine geeignete Bibliothek. Dann wirst Du wahrscheinlich den Code in Dein Projekt inkludieren müssen, zum Beispiel durch eine CPAN Installation oder Ruby gem oder durch Kopieren des Quellcodes in das Arbeitsverzeichnis Deines Projekts. Das Problem beim Einbinden einer Bibliothek ist, dass es schwierig ist, diese an die eigene Bedürfnisse anzupassen. Noch schwieriger gestaltet sich dann die Veröffentlichung des Projekts, da man sicherstellen muss, dass jeder der die Software verwendet, auf die Bibliothek zugreifen kann. Wenn man die Bibliothek im eigenen Projekt projektspezifisch anpasst, hat man meist ein Problem, wenn man eine neue Version der Bibliothek einspielen will. +Dazu ein Beispiel. Nehmen wir an, Du entwickelt gerade eine Webseite, die unter anderem einen Atom-Feed zur Verfügung stellen soll. Anstatt den notwendigen Code zur Auslieferung des Atom-Feeds selber zu schreiben, entscheidest Du Dich für eine geeignete Bibliothek. Dann wirst Du wahrscheinlich den Code in Dein Projekt inkludieren müssen, zum Beispiel durch eine CPAN-Installation oder ein Ruby-Gem oder durch Kopieren des Quellcodes in das Arbeitsverzeichnis Deines Projekts. Das Problem beim Einbinden einer Bibliothek ist, dass es schwierig ist, diese an die eigene Bedürfnisse anzupassen. Noch schwieriger gestaltet sich dann die Veröffentlichung des Projekts, da man sicherstellen muss, dass jeder der die Software verwendet, auf die Bibliothek zugreifen kann. Wenn man die Bibliothek im eigenen Projekt projektspezifisch anpasst, hat man meist ein Problem, wenn man eine neue Version der Bibliothek einspielen will. @@ -1119,7 +1119,7 @@ Git löst dieses Problem mit Hilfe von Submodulen. Mit Hilfe von Submodulen kann -Nehmen wir einmal an, dass Du die Rack Bibliothek (eine Ruby Gateway Schnittstelle für Webserver) zu Deinem Projekt hinzufügen willst. Dabei möchtest Du Deine eigenen Änderungen an dieser Bibliothek nachverfolgen, aber auch weiterhin Änderungen von den Rack Bibliothek-Entwicklern verwalten und zusammenmergen. Das erste was Du dazu tun musst, ist das Repository der Rack Bibliothek in ein Unterverzeichnis Deines Projekts zu klonen. Diesen Vorgang kannst Du mit Hilfe des Befehls `git submodule add` ausführen: +Nehmen wir einmal an, dass Du die Rack-Bibliothek (eine Ruby Gateway-Schnittstelle für Webserver) zu Deinem Projekt hinzufügen willst. Dabei möchtest Du Deine eigenen Änderungen an dieser Bibliothek nachverfolgen, aber auch weiterhin Änderungen von den Rack Bibliothek-Entwicklern verwalten und zusammenmergen. Das erste was Du dazu tun musst, ist das Repository der Rack Bibliothek in ein Unterverzeichnis Deines Projekts zu klonen. Diesen Vorgang kannst Du mit Hilfe des Befehls `git submodule add` ausführen: $ git submodule add git://github.com/chneukirchen/rack.git rack Initialized empty Git repository in /opt/subtest/rack/.git/ @@ -1131,7 +1131,7 @@ Nehmen wir einmal an, dass Du die Rack Bibliothek (eine Ruby Gateway Schnittstel -Innerhalb Deines Projekts befindet sich nun im Unterverzeichnis `rack` das komplette Rack-Projekt. Man kann jetzt in diesem Verzeichnis Änderungen vornehmen und ein eigenes Remote Repository mit Schreibrechten, zu welchem man pushen kann, hinzufügen. Ebenso ist es möglich, Änderungen von den Rack Entwicklern in sein Repository zu laden und diese mit den eigenen Ergebnissen zu mergen. Im Prinzip kann man innerhalb eines Submoduls die gleichen Vorgänge, wie in einem normalen Repository ausführen. Vorher müssen wir aber noch ein paar weitere Dinge zu Submodulen besprechen. Wenn Du gleich nach dem Hinzufügen des Submoduls, den Befehl `git status` ausführst, wirst Du gleich zwei Dinge bemerken: +Innerhalb Deines Projekts befindet sich nun im Unterverzeichnis `rack` das komplette Rack-Projekt. Man kann jetzt in diesem Verzeichnis Änderungen vornehmen und ein eigenes Remote Repository mit Schreibrechten, zu welchem man pushen kann, hinzufügen. Ebenso ist es möglich, Änderungen von den Rack Entwicklern in sein Repository zu laden und diese mit den eigenen Ergebnissen zu mergen. Im Prinzip kann man innerhalb eines Submoduls die gleichen Vorgänge, wie in einem normalen Repository ausführen. Vorher müssen wir aber noch ein paar weitere Dinge zu Submodulen besprechen. Wenn Du gleich nach dem Hinzufügen des Submoduls, den Befehl `git status` ausführst, wirst Du gleich zwei Dinge bemerken: $ git status # On branch master @@ -1170,15 +1170,15 @@ Die zweite Auffälligkeit bei der Ausgabe von `git status` ist der Eintrag rack. -Obwohl `rack` ein Unterverzeichnis in Deinem Arbeitsverzeichnis ist, erkennt Git dieses Verzeichnis als Submodul und verfolgt die Änderungen innerhalb dieses Verzeichnis nicht, wenn Git nicht innerhalb dieses Verzeichnis aufgerufen wird. Stattdessen erfässt Git welcher Commit in diesem Repository ausgecheckt ist. Wenn Du also Änderungen in diesem Unterverzeichnis durchführst und eincheckst, kann das Superprojekt erkennen, dass sich der aktuelle HEAD von diesem Projekt geändert hat. Das Superprojekt kann sich jetzt diesen Commit merken. Auf diese Art und Weise ist es möglich den kompletten Zustand des Projekts mit allen Projekten, die als Submodul hinzugefügt wurden, zu reproduzieren. In der Git Terminologie wird das Projekt, welches eines oder mehrere Submodule enthält, als Superprojekt bezeichnet. +Obwohl `rack` ein Unterverzeichnis in Deinem Arbeitsverzeichnis ist, erkennt Git dieses Verzeichnis als Submodul und verfolgt die Änderungen innerhalb dieses Verzeichnis nicht, wenn Git nicht innerhalb dieses Verzeichnis aufgerufen wird. Stattdessen erfässt Git, welcher Commit in diesem Repository ausgecheckt ist. Wenn Du also Änderungen in diesem Unterverzeichnis durchführst und eincheckst, kann das Superprojekt erkennen, dass sich der aktuelle HEAD von diesem Projekt geändert hat. Das Superprojekt kann sich jetzt diesen Commit merken. Auf diese Art und Weise ist es möglich den kompletten Zustand des Projekts mit allen Projekten, die als Submodul hinzugefügt wurden, zu reproduzieren. In der Git Terminologie wird das Projekt, welches eines oder mehrere Submodule enthält, als Superprojekt bezeichnet. -Dabei muss man sich folgender Eigenschaft bewusst sein: Git verwaltet den exakten Commit, der gerade ausgecheckt ist und nicht etwa den Branch oder eine andere Referenz. Git kann also zum Beispiel nicht speichern, dass der aktuelle Stand im Branch `master` enthalten ist. +Dabei muss man sich folgender Eigenschaft bewusst sein: Git verwaltet den exakten Commit, der gerade ausgecheckt ist und nicht etwa den Branch oder eine andere Referenz. Git kann also zum Beispiel nicht speichern, dass der aktuelle Stand im Branch `master` enthalten ist. -Wenn Du Dein Projekt das erste mal eincheckst, erhälst Du in etwa folgende Ausgabe: +Wenn Du Dein Projekt das erste Mal eincheckst, erhältst Du in etwa folgende Ausgabe: $ git commit -m 'first commit with submodule rack' [master 0550271] first commit with submodule rack @@ -1188,7 +1188,7 @@ Wenn Du Dein Projekt das erste mal eincheckst, erhälst Du in etwa folgende Ausg -Der Mode 160000, der für den rack Eintrag gilt, ist ein spezieller Mode in Git. Er bedeutet in etwa, dass man einen Commit als Verzeichnis-Eintrag in Git verwaltet und damit nicht wie normalerweise ein Verzeichnis oder eine Datei. +Der Mode 160000, der für den rack Eintrag gilt, ist ein spezieller Mode in Git. Er bedeutet in etwa, dass man einen Commit als Verzeichnis-Eintrag in Git verwaltet und damit nicht wie normalerweise ein Verzeichnis oder eine Datei. @@ -1246,7 +1246,7 @@ Das Verzeichnis `rack` wurde zwar erzeugt, aber es ist leer. Deshalb musst Du zw -Nach Ausführung der beiden Befehle befindet sich das Verzeichnis `rack` in genau dem gleichen Zustand, wie wir es ursprünglich eingecheckt haben. Wenn ein anderer Entwickler Änderungen am Rack Code durchführt, diese eincheckt und Du diese dann pullst und mergst, erhält man einen etwas seltsamen Zustand: +Nach Ausführung der beiden Befehle befindet sich das Verzeichnis `rack` in genau dem gleichen Zustand, wie wir es ursprünglich eingecheckt haben. Wenn ein anderer Entwickler Änderungen am Rack Code durchführt, diese eincheckt und Du diese dann pullst und mergst, erhält man einen etwas seltsamen Zustand: $ git merge origin/master Updating 0550271..85a3eee @@ -1290,11 +1290,11 @@ Dieser Zustand tritt auf, weil der Zeiger auf den Commit im Submodul derzeit nic -Dieser Update muss jedes mal ausgeführt werden, wenn man das Superprojekt pullt und dort ein Änderung in einem Submodul enthalten ist. Es ist vielleicht ein wenig merkwürdig, aber es funktioniert. +Dieser Update muss jedes Mal ausgeführt werden, wenn man das Superprojekt pullt und dort ein Änderung in einem Submodul enthalten ist. Es ist vielleicht ein wenig merkwürdig, aber es funktioniert. -Häufig tritt beim Arbeiten mit Submodulen ein Problem bei folgendem Szenario auf: Ein Entwickler führt Änderungen in einem Submodul durch, checkt diese ein, vergisst aber diese Änderungen zum zentralen Server zu pushen. Wenn dann im Superprojekt die Änderung des Submoduls ebenso eingecheckt wird und dieses dann gepusht wird, tritt ein Problem auf. Wenn jetzt andere Entwickler den neuen Stand des Superprojekts holen und den Befehl `git submodule update` ausführen, erhalten sie eine Fehlermeldung, dass der entsprechend referenzierte Commit von dem Submodul nicht gefunden werden konnte. Das passiert weil dieser Commit bei dem zweiten Entwickler noch gar nicht existiert. Wenn ein solcher Fall auftritt, erhält man in etwa folgende Fehlermeldung: +Häufig tritt beim Arbeiten mit Submodulen ein Problem bei folgendem Szenario auf: Ein Entwickler führt Änderungen in einem Submodul durch, checkt diese ein, vergisst aber diese Änderungen zum zentralen Server zu pushen. Wenn dann im Superprojekt die Änderung des Submoduls ebenso eingecheckt wird und dieses dann gepusht wird, tritt ein Problem auf. Wenn jetzt andere Entwickler den neuen Stand des Superprojekts holen und den Befehl `git submodule update` ausführen, erhalten sie eine Fehlermeldung, dass der entsprechend referenzierte Commit von dem Submodul nicht gefunden werden konnte. Das passiert weil dieser Commit bei dem zweiten Entwickler noch gar nicht existiert. Wenn ein solcher Fall auftritt, erhält man in etwa folgende Fehlermeldung: $ git submodule update fatal: reference isn’t a tree: 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 @@ -1302,7 +1302,7 @@ Häufig tritt beim Arbeiten mit Submodulen ein Problem bei folgendem Szenario au -Dann kann man allerdings herausfinden, wer zum letzten mal eine Änderung eingecheckt hat: +Dann kann man allerdings herausfinden, wer zum letzten Mal eine Änderung eingecheckt hat: $ git log -1 rack commit 85a3eee996800fcfa91e2119372dd4172bf76678 @@ -1331,7 +1331,7 @@ In Git kann man diese Vorgehensweise gut abbilden, indem man für jedes Unterver -Die Arbeit mit Submodulen verläuft jedoch nicht immer reibungslos. Man muss verhältnismäßig gut aufpassen, wenn man in einem Submodul-Verzeichnis arbeitet. Wenn man nämlich den Befehl `git submodule update` ausführt, checkt Git den entsprechenden Zustand des Commits aus, aber checkt dabei keinen Branch aus. Diesen Zustand nennt man auch `detached HEAD`. Das bedeutet das die Datei HEAD direkt auf einen Commit zeigt und nicht wie sonst üblich auf eine symbolische Referenz, also zum Beispiel auf einen Branch. Das Problem dabei ist, dass man normalerweise in einem solchen Zustand nicht weiterarbeiten möchte, weil es sehr leicht vorkommen kann, dass Änderungen verloren gehen. Wenn man also den Befehl `git submodule update` aufruft, dann einen Commit in dem entsprechenden Submodul-Verzeichnis ausführt, ohne davor einen Branch auszuchecken, und dann noch einmal `git submodule update` im Superprojekt aufruft, ohne dass man die Änderungen im Submodul im Superprojekt eingecheckt hat, verliert man die ganzen Änderungen, ohne das Git einen darauf vorher hinweist. Tatsächlich ist es so, dass die Änderungen nicht verloren gehen, aber es gibt keinen Branch der auf die entsprechenden Commits hinzeigt und damit kann es schwierig werden die entsprechenden Commits wiederherzustellen beziehungsweise sichtbar zu machen. +Die Arbeit mit Submodulen verläuft jedoch nicht immer reibungslos. Man muss verhältnismäßig gut aufpassen, wenn man in einem Submodul-Verzeichnis arbeitet. Wenn man nämlich den Befehl `git submodule update` ausführt, checkt Git den entsprechenden Zustand des Commits aus, aber checkt dabei keinen Branch aus. Diesen Zustand nennt man auch `detached HEAD`. Das bedeutet, dass die Datei HEAD direkt auf einen Commit zeigt und nicht wie sonst üblich auf eine symbolische Referenz, also zum Beispiel auf einen Branch. Das Problem dabei ist, dass man normalerweise in einem solchen Zustand nicht weiterarbeiten möchte, weil es sehr leicht vorkommen kann, dass Änderungen verloren gehen. Wenn man also den Befehl `git submodule update` aufruft, dann einen Commit in dem entsprechenden Submodul-Verzeichnis ausführt, ohne davor einen Branch auszuchecken, und dann noch einmal `git submodule update` im Superprojekt aufruft, ohne dass man die Änderungen im Submodul im Superprojekt eingecheckt hat, verliert man die ganzen Änderungen, ohne dass Git einen darauf vorher hinweist. Tatsächlich ist es so, dass die Änderungen nicht verloren gehen, aber es gibt keinen Branch, der auf die entsprechenden Commits hinzeigt, und damit kann es schwierig werden, die entsprechenden Commits wiederherzustellen beziehungsweise sichtbar zu machen. @@ -1364,11 +1364,11 @@ Wenn ein Projekt ein Submodul enthält und man im Superprojekt zwischen einzelne -In diesem Fall muss man das Verzeichnis entweder an einen anderen Ort verschieben oder löschen. Im letzteren Fall muss man aber wieder das Submodul komplett klonen, wenn man in den anderen Zweig zurückwechselt. Außerdem kann man dabei lokale Änderungen zu nichte machen oder Zweige, welche man noch nicht gepusht hat, verlieren. +In diesem Fall muss man das Verzeichnis entweder an einen anderen Ort verschieben oder löschen. Im letzteren Fall muss man aber wieder das Submodul komplett klonen, wenn man in den anderen Zweig zurückwechselt. Außerdem kann man dabei lokale Änderungen zunichte machen oder Zweige, welche man noch nicht gepusht hat, verlieren. -Die letzte Falle in die viele Leute tappen, tritt auf, wenn man bereits vorhandene Verzeichnisse in Submodule umwandeln will. Wenn man also Dateien, die bereits von Git verwaltet werden, entfernen und in ein entsprechendes Submodul verschieben möchte, muss man vorsichtig sein. Ansonsten können schwer zu behebende Probleme mit Git auftreten. Nehmen wir zum Beispiel an, dass Du die Dateien vom Rack Projekt in ein Unterverzeichnis Deines Projekts abgelegt hast und diese jetzt aber in ein Submodul verschieben möchtest. Wenn Du das Unterverzeichnis einfach löschst und dann den Befehl `submodule add` ausführst, zeigt Dir Git folgende Fehlermeldung an: +Die letzte Falle, in die viele Leute tappen, tritt auf, wenn man bereits vorhandene Verzeichnisse in Submodule umwandeln will. Wenn man also Dateien, die bereits von Git verwaltet werden, entfernen und in ein entsprechendes Submodul verschieben möchte, muss man vorsichtig sein. Ansonsten können schwer zu behebende Probleme mit Git auftreten. Nehmen wir zum Beispiel an, dass Du die Dateien vom Rack Projekt in ein Unterverzeichnis Deines Projekts abgelegt hast und diese jetzt aber in ein Submodul verschieben möchtest. Wenn Du das Unterverzeichnis einfach löschst und dann den Befehl `submodule add` ausführst, zeigt Dir Git folgende Fehlermeldung an: $ rm -Rf rack/ $ git submodule add git@github.com:schacon/rack.git rack @@ -1413,19 +1413,19 @@ Wenn man dann wieder in den Zweig mit dem Submodul zurückwechseln will, erhält -Nachdem wir neben den Vor- und Nachteilen beim Arbeiten mit Submodulen kennengelernt haben, möchte ich jetzt noch eine alternative Lösung zeigen, wie man ähnliche Probleme lösen kann. Wenn Git etwas zusammenführt, also mergt, analysiert es die Teile, die es mergen muss. Auf Basis dieser Analyse entscheidet Git sich für eine geeignete Merging-Methode. Wenn man zwei Branches mergt, dann verwendet Git automatisch, die sogenannte Recursive-Strategie. Wenn man mehr als zwei Branches mergt, verwendet Git die sogenannte Octopus Strategie. Diese Strategien werden automatisch für Dich gewählt, weil die Recursive-Strategie normalerweise sehr gut geeignet ist, um einen Drei-Wege-Merge (engl. three-way merge) durchzuführen — zum Beispiel, wenn es mehr als einen gemeinsamen Vorgänger-Commit gibt — aber der Drei-Wege-Merge ist nur für das Mergen von zwei Branches geeignet. Die Octopus-Merge-Strategie kann mehrere Branches zusammenführen, aber es wird dabei vorsichtiger vorgegangen um schwierig aufzulösende Konflikte zu vermeiden. Aus diesem Grund wird diese Strategie standardmäßig verwendet, wenn man mehr als zwei Branches zusammenführen möchte. +Nachdem wir neben den Vor- und Nachteilen beim Arbeiten mit Submodulen kennengelernt haben, möchte ich jetzt noch eine alternative Lösung zeigen, wie man ähnliche Probleme lösen kann. Wenn Git etwas zusammenführt, also mergt, analysiert es die Teile, die es mergen muss. Auf Basis dieser Analyse entscheidet Git sich für eine geeignete Merging-Methode. Wenn man zwei Branches mergt, dann verwendet Git automatisch, die sogenannte Recursive-Strategie. Wenn man mehr als zwei Branches mergt, verwendet Git die sogenannte Octopus-Strategie. Diese Strategien werden automatisch für Dich gewählt, weil die Recursive-Strategie normalerweise sehr gut geeignet ist, um einen Drei-Wege-Merge (engl. three-way merge) durchzuführen — zum Beispiel, wenn es mehr als einen gemeinsamen Vorgänger-Commit gibt — aber der Drei-Wege-Merge ist nur für das Mergen von zwei Branches geeignet. Die Octopus-Merge-Strategie kann mehrere Branches zusammenführen, aber es wird dabei vorsichtiger vorgegangen, um schwierig aufzulösende Konflikte zu vermeiden. Aus diesem Grund wird diese Strategie standardmäßig verwendet, wenn man mehr als zwei Branches zusammenführen möchte. -Es gibt jedoch noch weitere Strategien die man verwenden kann. Einer dieser Strategien ist der sogenannte Subtree-Merge. Dies kann verwendet werden um unser Problem mit Unterprojekten zu lösen. Ich möchte Dir im folgenden aufzeigen, wie man das Rack-Projekt aus dem letzten Kapitel einbindet und dabei den Subree-Merge anstatt den Submodulen verwendet. +Es gibt jedoch noch weitere Strategien, die man verwenden kann. Einer dieser Strategien ist der sogenannte Subtree-Merge. Dies kann verwendet werden, um unser Problem mit Unterprojekten zu lösen. Ich möchte Dir im folgenden aufzeigen, wie man das Rack-Projekt aus dem letzten Kapitel einbindet und dabei den Subree-Merge anstatt der Submodule verwendet. -Das Prinzip, das hinter einem Subtree-Merge steckt, ist, dass man zwei Projekte hat und eines der Projekte wird in ein Unterverzeichnis des anderen Projekts abgebildet. Wenn man ein Subtree-Merge ausführt, ist Git schlau genug um zu erkennen, dass ein Projekt ein Abbild von einem anderen Projekt ist und es kann den Merge in geeigneter Weise durchführen — das ist wirklich sehr erstaunlich. +Das Prinzip, das hinter einem Subtree-Merge steckt, ist, dass man zwei Projekte hat und eines der Projekte wird in ein Unterverzeichnis des anderen Projekts abgebildet. Wenn man ein Subtree-Merge ausführt, ist Git schlau genug, um zu erkennen, dass ein Projekt ein Abbild von einem anderen Projekt ist und es kann den Merge in geeigneter Weise durchführen — das ist wirklich sehr erstaunlich. -Als erstes musst Du dazu die Rack Applikation zu Deinem Projekt hinzufügen. Dazu fügst Du das Rack Projekt als neues Remote Repository in Deinem Projekt hinzu und checkst dieses in einem separaten Branch aus: +Als erstes musst Du dazu die Rack-Applikation zu Deinem Projekt hinzufügen. Dazu fügst Du das Rack-Projekt als neues Remote Repository in Deinem Projekt hinzu und checkst dieses in einem separaten Branch aus: $ git remote add rack_remote git@github.com:schacon/rack.git $ git fetch rack_remote @@ -1458,13 +1458,13 @@ Nach der Ausführung der drei Befehle befindet sich das Rack Projekt in Deinem B -Jetzt möchten wir das Rack Projekt in Deinen Branch `master` als Unterverzeichnis hinzufügen. Dies kann man in Git mit dem Befehl `git read-tree` durchführen. In Kapitel 9 werde ich den Befehl `read-tree` und dessen verwandten Befehle näher erläutern. Hier möchte ich nur erklären, dass der Befehl das Wurzelverzeichnis eines Branches in die aktuelle Staging Area und in das Arbeitsverzeichnis packt. Damit hast Du jetzt zu Deinem Branch `master` zurückgewechselt, den Inhalt des Branches `rack` in das Unterverzeichnis `rack` im Branch `master` Deines Projekts hinterlegt: +Jetzt möchten wir das Rack Projekt in Deinen Branch `master` als Unterverzeichnis hinzufügen. Dies kann man in Git mit dem Befehl `git read-tree` durchführen. In Kapitel 9 werde ich den Befehl `read-tree` und dessen verwandte Befehle näher erläutern. Hier möchte ich nur erklären, dass der Befehl das Wurzelverzeichnis eines Branches in die aktuelle Staging Area und in das Arbeitsverzeichnis packt. Damit hast Du jetzt zu Deinem Branch `master` zurückgewechselt, den Inhalt des Branches `rack` in das Unterverzeichnis `rack` im Branch `master` Deines Projekts hinterlegt: $ git read-tree --prefix=rack/ -u rack_branch -Wenn Du jetzt einen Commit ausführst, erscheint es einem so, als ob die ganzen Dateien aus dem Rack Projekt in diesem Unterverzeichnis liegen — als ob man das Projekt aus einem Tarball-Container hineinkopiert hätte. Das Besondere ist jetzt aber, dass man Änderungen zwischen den verschiedenen Branches jetzt einfach zusammenführen kann. Das beduetet, wenn das Rack Projekt aktualisiert wird, kann man sich diese Änderungen einfach holen indem man in diese Branch wechselt und dort einen Pull durchführt: +Wenn Du jetzt einen Commit ausführst, erscheint es einem so, als ob die ganzen Dateien aus dem Rack Projekt in diesem Unterverzeichnis liegen — als ob man das Projekt aus einem Tarball-Container hineinkopiert hätte. Das Besondere ist jetzt aber, dass man Änderungen zwischen den verschiedenen Branches jetzt einfach zusammenführen kann. Das bedeutet, wenn das Rack Projekt aktualisiert wird, kann man sich diese Änderungen einfach holen, indem man in diesen Branch wechselt und dort einen Pull durchführt: $ git checkout rack_branch $ git pull @@ -1480,7 +1480,7 @@ Danach kann man diese Änderungen wieder in den master Branch mergen. Wenn man d -Die ganzen Änderungen des Rack Projekts wurden nun zusammengeführt, Du musst jetzt nur noch einen entsprechenden Commit durchführen. Man kann aber auch genau das Gegenteil machen: Man führt Änderungen im Unterverzeichnis `rack` des master Branch aus und mergt diese dann später in den Zweig `rack_branch`. Diesen kann man dann den Entwicklern des Rack Projekts zur Verfügung stellen. +Die ganzen Änderungen des Rack Projekts wurden nun zusammengeführt, Du musst jetzt nur noch einen entsprechenden Commit durchführen. Man kann aber auch genau das Gegenteil machen: Man führt Änderungen im Unterverzeichnis `rack` des master Branches aus und mergt diese dann später in den Zweig `rack_branch`. Diesen kann man dann den Entwicklern des Rack Projekts zur Verfügung stellen. @@ -1499,4 +1499,4 @@ Um Dein Verzeichnis `rack` mit dem letzten Stand des Branches `master` auf dem S -In diesem Kapitel hast Du viele ausgeklügelte Werzeuge kennengelernt, die es Dir ermöglichen Commits und die Staging Area nach Deinen Vorstellungen zu beeinflussen. Wenn ein Problem in Deinem Projekt auftaucht, solltest Du jetzt leicht bestimmen können, welcher Commit den Fehler verursacht hat, genauso die Information wann und von wem der Fehler begangen wurde. Wenn Du andere Projekte in Deinem Projekt verwendet möchtest, hast Du jetzt mehrere Möglichkeiten kennengelernt, wie Du dies handhaben kannst. An dieser Stelle solltest Du jetzt in der Lage sein die meisten Dinge, die Du bei der täglichen Arbeit benötigst, in der Kommandozeile durchzuführen, ohne das Dir dabei Schweißperlen auf der Stirn stehen. +In diesem Kapitel hast Du viele ausgeklügelte Werzeuge kennengelernt, die es Dir ermöglichen Commits und die Staging Area nach Deinen Vorstellungen zu beeinflussen. Wenn ein Problem in Deinem Projekt auftaucht, solltest Du jetzt leicht bestimmen können, welcher Commit den Fehler verursacht hat, sowie wann und von wem der Fehler begangen wurde. Wenn Du andere Projekte in Deinem Projekt verwenden möchtest, hast Du jetzt mehrere Möglichkeiten kennengelernt, wie Du dies handhaben kannst. An dieser Stelle solltest Du jetzt in der Lage sein, die meisten Dinge, die Du bei der täglichen Arbeit benötigst, in der Kommandozeile durchzuführen, ohne dass Dir dabei Schweißperlen auf der Stirn stehen. From e9bc4cb01fac71ecdf38fa39f125d92373006437 Mon Sep 17 00:00:00 2001 From: harupong Date: Wed, 15 Jan 2014 09:55:48 +0900 Subject: [PATCH 103/690] Apply 1ca5ef1 to ja --- ja/05-distributed-git/01-chapter5.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ja/05-distributed-git/01-chapter5.markdown b/ja/05-distributed-git/01-chapter5.markdown index 21d250d28..d78946f7a 100644 --- a/ja/05-distributed-git/01-chapter5.markdown +++ b/ja/05-distributed-git/01-chapter5.markdown @@ -171,7 +171,7 @@ John の手元に Jessica がプッシュした内容が届きましたが、さ マージがうまくいきました。John のコミット履歴は図 5-5 のようになります。 Insert 18333fig0505.png -図 5-5. origin/master をマージした後の John のリポジトリ +図 5-5. `origin/master` をマージした後の John のリポジトリ 自分のコードが正しく動作することを確認した John は、変更内容をサーバーにプッシュします。 @@ -212,7 +212,7 @@ Jessica のトピックブランチ上での作業が完了しました。プッ removed invalid default value -Jessica はトピックブランチの内容を自分の master ブランチにマージし、同じく John の作業 (`origin/master`) も自分の `master` ブランチにマージして再び変更をサーバーにプッシュすることになります。まずは master ブランチに戻り、これまでの作業を統合できるようにします。 +Jessica はトピックブランチの内容を自分の `master` ブランチにマージし、同じく John の作業 (`origin/master`) も自分の `master` ブランチにマージして再び変更をサーバーにプッシュすることになります。まずは `master` ブランチに戻り、これまでの作業を統合できるようにします。 $ git checkout master Switched to branch "master" @@ -252,7 +252,7 @@ Insert 18333fig0509.png Insert 18333fig0510.png 図 5-10. すべての変更をサーバーに書き戻した後の Jessica の履歴 -これがもっとも単純なワークフローです。トピックブランチでしばらく作業を進め、統合できる状態になれば自分の master ブランチにマージする。他の開発者の作業を取り込む場合は、`origin/master` を取得してもし変更があればマージする。そして最終的にそれをサーバーの `master` ブランチにプッシュする。全体的な流れは図 5-11 のようになります。 +これがもっとも単純なワークフローです。トピックブランチでしばらく作業を進め、統合できる状態になれば自分の `master` ブランチにマージする。他の開発者の作業を取り込む場合は、`origin/master` を取得してもし変更があればマージする。そして最終的にそれをサーバーの `master` ブランチにプッシュする。全体的な流れは図 5-11 のようになります。 Insert 18333fig0511.png 図 5-11. 複数開発者での Git を使ったシンプルな開発作業のイベントシーケンス From 7c94d2639694359f416b244465509eb6f1d4d393 Mon Sep 17 00:00:00 2001 From: harupong Date: Wed, 15 Jan 2014 10:10:51 +0900 Subject: [PATCH 104/690] Apply 15f2bf1 to ja tree --- ja/05-distributed-git/01-chapter5.markdown | 23 +++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/ja/05-distributed-git/01-chapter5.markdown b/ja/05-distributed-git/01-chapter5.markdown index d78946f7a..2b68260f7 100644 --- a/ja/05-distributed-git/01-chapter5.markdown +++ b/ja/05-distributed-git/01-chapter5.markdown @@ -528,7 +528,26 @@ Insert 18333fig0518.png port = 993 sslverify = false -IMAP サーバーで SSL を使っていない場合は、最後の二行はおそらく不要でしょう。そして host のところが `imaps://` ではなく `imap://` となります。ここまでの設定が終われば、`git send-email` を実行して IMAP サーバーの Drafts フォルダにパッチを置くことができるようになります。 +IMAP サーバーで SSL を使っていない場合は、最後の二行はおそらく不要でしょう。そして host のところが `imaps://` ではなく `imap://` となります。ここまでの設定が終われば、`git imap-send` を実行して IMAP サーバーの Drafts フォルダにパッチを置くことができるようになります。 + + $ cat *.patch |git imap-send + Resolving imap.gmail.com... ok + Connecting to [74.125.142.109]:993... ok + Logging in... + sending 2 messages + 100% (2/2) done + +あとは、Drafts フォルダに移動して To フィールドをメーリングリストのアドレスに変更し (おそらく CC には担当メンテなのアドレスを入れ)、送信できるようになりました。 + +SMTP サーバーを使ってパッチを送ることもできます。IMAP サーバー同様、設定は `git config` コマンドで順に設定してもいいですし、`~/.gitconfig` ファイルの sendmail セクションに直接入力してもかまいません。 + + [sendemail] + smtpencryption = tls + smtpserver = smtp.gmail.com + smtpuser = user@gmail.com + smtpserverport = 587 + +設定が追加できたら、`git send-email` を実行してパッチを送信します。 $ git send-email *.patch 0001-added-limit-to-log-function.patch @@ -555,8 +574,6 @@ Git はその後、各パッチについてこのようなログ情報をはき Result: OK -あとは、Drafts フォルダに移動して To フィールドをメーリングリストのアドレスに変更し (おそらく CC には担当メンテなのアドレスを入れ)、送信できるようになりました。 - ### まとめ ### このセクションでは、今後みなさんが遭遇するであろうさまざまな形式の Git プロジェクトについて、関わっていくための作業手順を説明しました。そして、その際に使える新兵器もいくつか紹介しました。次はもう一方の側、つまり Git プロジェクトを運営する側について見ていきましょう。慈悲深い独裁者、あるいは統合マネージャーとしての作業手順を説明します。 From ea953b3cbb816efac441040fbeefef310e96635f Mon Sep 17 00:00:00 2001 From: harupong Date: Wed, 15 Jan 2014 10:23:55 +0900 Subject: [PATCH 105/690] Apply 2a0a837 to ja tree --- ja/04-git-server/01-chapter4.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ja/04-git-server/01-chapter4.markdown b/ja/04-git-server/01-chapter4.markdown index 43155723e..08a0f12d7 100644 --- a/ja/04-git-server/01-chapter4.markdown +++ b/ja/04-git-server/01-chapter4.markdown @@ -26,7 +26,7 @@ Git では、データ転送用のネットワークプロトコルとして Loc $ git clone file:///opt/git/project.git -URL の先頭に `file://` を明示するかどうかで、Git の動きは微妙に異なります。単にパスを指定した場合は、Git はハードリンクを行うか、必要に応じて直接ファイルをコピーします。`file://` を指定した場合は、Git がプロセスを立ち上げ、そのプロセスが (通常は) ネットワーク越しにデータを転送します。一般的に、直接のコピーに比べてこれは非常に非効率的です。`file://` プレフィックスをつける最も大きな理由は、(他のバージョン管理システムからインポートしたときなどにあらわれる) 関係のない参照やオブジェクトを除いたクリーンなコピーがほしいということです。本書では通常のパス表記を使用します。そのほうがたいていの場合に高速となるからです。 +URL の先頭に `file://` を明示するかどうかで、Git の動きは微妙に異なります。`file://` を明示せずパスだけを指定し、かつコピー元とコピー先が同一のファイルシステム上にある場合は、Git は必要なオブジェクトにハードリンクを張ろうとします。もし異なるファイルシステム上にある場合は、Git はシステムデフォルトのファイルコピー機能を使って必要なオブジェクトをコピーします。一方 `file://` を指定した場合は、Git がプロセスを立ち上げ、そのプロセスが (通常は) ネットワーク越しにデータを転送します。一般的に、直接のコピーに比べてこれは非常に非効率的です。`file://` プレフィックスをつける最も大きな理由は、(他のバージョン管理システムからインポートしたときなどにあらわれる) 関係のない参照やオブジェクトを除いたクリーンなコピーがほしいということです。本書では通常のパス表記を使用します。そのほうがたいていの場合に高速となるからです。 ローカルのリポジトリを既存の Git プロジェクトに追加するには、このようなコマンドを実行します。 From af8ca93e5a3232298f0640386c4446b9ccda7bbf Mon Sep 17 00:00:00 2001 From: harupong Date: Wed, 15 Jan 2014 10:25:30 +0900 Subject: [PATCH 106/690] Apply bdef6f7 to ja tree --- 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 71afcde2d..1690e53b3 100644 --- a/ja/03-git-branching/01-chapter3.markdown +++ b/ja/03-git-branching/01-chapter3.markdown @@ -458,7 +458,7 @@ Insert 18333fig0326.png Branch sf set up to track remote branch refs/remotes/origin/serverfix. Switched to a new branch "sf" -これで、ローカルブランチ sf が自動的に origin/serverfix を追跡するようになりました。 +これで、ローカルブランチ sf が自動的に `origin/serverfix` を追跡するようになりました。 ### リモートブランチの削除 ### From ccfd0e64bd63ced336c3ed25902d2d5962d700d9 Mon Sep 17 00:00:00 2001 From: "Ann + J.M" Date: Wed, 15 Jan 2014 20:09:30 +0100 Subject: [PATCH 107/690] Fix wrong comma --- de/06-git-tools/01-chapter6.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index a5143a50e..bc3a7f83b 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -765,7 +765,7 @@ Wenn Du den Befehl ausführst, erhältst Du eine Reihe von Commits in Deinem Tex -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: +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 From 48bdfab00460dd63acfd03b2627966b2e7d62032 Mon Sep 17 00:00:00 2001 From: "Ann + J.M" Date: Wed, 15 Jan 2014 21:39:21 +0100 Subject: [PATCH 108/690] [de] Connect compound nouns with dash, more minor fixes --- de/06-git-tools/01-chapter6.markdown | 168 +++++++++++++-------------- 1 file changed, 84 insertions(+), 84 deletions(-) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index bc3a7f83b..31bcf958a 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -3,11 +3,11 @@ -Bis hierher hast Du die meisten täglichen Kommandos und Arbeitsweisen gelernt, die Du brauchst um ein Git Repository für Deine Quellcode Kontrolle, zu benutzen. Du hast die grundlegenden Aufgaben des tracking und committing von Dateien gemeistert und Du hast von der Macht der staging area, des branching und des merging Gebrauch gemacht. +Bis hierher hast Du die meisten täglichen Kommandos und Arbeitsweisen gelernt, die Du brauchst um ein Git-Repository für Deine Quellcode-Kontrolle, zu benutzen. Du hast die grundlegenden Aufgaben des Nachverfolgens und Eincheckens von Dateien gemeistert und Du hast von der Macht der Staging-Area, des Branching und des Mergens Gebrauch gemacht. -Als nächstes werden wir einige sehr mächtige Werkzeuge besprechen, die Dir Git zur Verfügung stellt. Du wirst zwar nicht unbedingt jeden Tag verwenden, aber mit Sicherheit an einem bestimmten Punkt gute brauchen können. +Als Nächstes werden wir einige sehr mächtige Werkzeuge besprechen, die Dir Git zur Verfügung stellt. Du wirst zwar nicht unbedingt jeden Tag verwenden, aber mit Sicherheit an einem bestimmten Punkt gut brauchen können. ## Revision Auswahl ## @@ -21,18 +21,18 @@ Git erlaubt Dir, Commits auf verschiedenste Art und Weise auszuwählen. Diese si -Du kannst offensichtlich mithilfe des SHA-1 hash einen commit auswählen, aber es gibt auch Menschen freundlichere Methoden auf ein commit zu verweisen. Dieser Bereich skizziert die verschiedenen Wege, die man gehen kann um auf ein einzelnen commit zu referenzieren. +Du kannst offensichtlich mithilfe des SHA-1-Hashes einen Commit auswählen, aber es gibt auch menschenfreundlichere Methoden, auf einen Commit zu verweisen. Dieser Bereich skizziert die verschiedenen Wege, die man gehen kann, um sich auf ein einzelnen Commit zu beziehen. ### Abgekürztes SHA ### -Git ist intelligent genug, den richtigen commit herauszufinden, wenn man nur die ersten paar Zeichen angibt aber nur unter der Bedingung, dass der SHA-1 hash mindestens vier Zeichen lang und einzigartig ist — das bedeutet, dass es nur ein Objekt im derzeitigen Repository gibt, das mit diesem bestimmten SHA-1 hash beginnt. +Git ist intelligent genug, den richtigen Commit herauszufinden, wenn man nur die ersten paar Zeichen angibt, aber nur unter der Bedingung, dass der SHA-1-Hash mindestens vier Zeichen lang und einzigartig ist — das bedeutet, dass es nur ein Objekt im derzeitigen Repository gibt, das mit diesem bestimmten SHA-1-Hash beginnt. -Um zum Beispiel einen bestimmten commit zu sehen, kann man das `git log` Kommando ausführen und den commit identifizieren in dem man eine bestimmte Funktionalität hinzugefügt hat: +Um zum Beispiel einen bestimmten Commit zu sehen, kann man das `git log` Kommando ausführen und den Commit identifizieren, indem man eine bestimmte Funktionalität hinzugefügt hat: $ git log commit 734713bc047d87bf7eac9674765ae793478c50d3 @@ -56,7 +56,7 @@ Um zum Beispiel einen bestimmten commit zu sehen, kann man das `git log` Kommand -In diesem Fall wählt man `1c002dd....` wenn Du diesen commit mit `git show` anzeigen lassen willst, die folgenden Kommandos sind äquivalent (vorausgesetzt die verkürzte Version ist einzigartig): +In diesem Fall wählt man `1c002dd....`, wenn man diesen Commit mit `git show` anzeigen lassen will, die folgenden Kommandos sind äquivalent (vorausgesetzt die verkürzte Version ist einzigartig): $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b $ git show 1c002dd4b536e7479f @@ -64,7 +64,7 @@ In diesem Fall wählt man `1c002dd....` wenn Du diesen commit mit `git show` anz -Git kann auch selber eine Kurzform für Deine einzigartigen SHA-1 Werte erzeugen. Wenn Du `--abbrev-commit` dem `git log` Kommando übergibst, wird es den kürzeren Wert benutzen diesen aber einzigartig halten; die Standardeinstellung sind sieben Zeichen aber es werden automatisch mehr benutzt wenn dies nötig ist um den SHA-1 hash eindeutig zu bezeichnen. +Git kann auch selber eine Kurzform für Deine einzigartigen SHA-1-Werte erzeugen. Wenn Du `--abbrev-commit` dem `git log` Kommando übergibst, wird es den kürzeren Wert benutzen, diesen aber einzigartig halten; die Standardeinstellung sind sieben Zeichen, aber es werden automatisch mehr benutzt, wenn dies nötig ist, um den SHA-1-Hash eindeutig zu bezeichnen. $ git log --abbrev-commit --pretty=oneline ca82a6d changed the version number @@ -73,40 +73,40 @@ Git kann auch selber eine Kurzform für Deine einzigartigen SHA-1 Werte erzeugen -Generell kann man sagen das acht bis zehn Zeichen mehr als ausreichend in einem Projekt sind, um eindeutig zu bleiben. Eines der größten Git Projekte, der Linux Kernel, fängt langsam an 12 von maximal 40 Zeichen zu nutzen um eindeutig zu bleiben. +Generell kann man sagen, dass acht bis zehn Zeichen mehr als ausreichend in einem Projekt sind, um eindeutig zu bleiben. Eines der größten Git-Projekte, der Linux-Kernel, fängt langsam an 12 von maximal 40 Zeichen zu nutzen, um eindeutig zu bleiben. ### EINE KURVE NOTIZ ÜBER SHA-1 ### -Eine Menge Leute machen sich Sorgen, dass ab einem zufälligen Punkt zwei Objekte im Repository vorhanden sind, die den gleichen SHA-1 hash wert haben. Was Dann? +Eine Menge Leute machen sich Sorgen, dass ab einem zufälligen Punkt zwei Objekte im Repository vorhanden sind, die den gleichen SHA-1-Hashwert haben. Was dann? -Wenn es passiert, dass bei einem commit, ein Objekt mit dem gleichen SHA-1 hash Wert im Repository vorhanden ist, wird Git sehen, dass das vorherige Objekt bereits in der Datenbank vorhanden ist und davon ausgehen, dass es bereits geschrieben wurde. Wenn Du versuchst das Objekt später wieder auszuchecken wirst Du immer die Daten des ersten Objekts bekommen. +Wenn es passiert, dass bei einem Commit, ein Objekt mit dem gleichen SHA-1-Hashwert im Repository vorhanden ist, wird Git sehen, dass das vorherige Objekt bereits in der Datenbank vorhanden ist und davon ausgehen, dass es bereits geschrieben wurde. Wenn Du versuchst, das Objekt später wieder auszuchecken, wirst Du immer die Daten des ersten Objekts bekommen. -Allerdings solltest Du Dir bewusst machen wie unglaublich unwahrscheinlich dieses Szenario ist. Die Länge des SHA-1 hashs beträgt 20 bytes oder 160bits. Die Anzahl der Objekte die benötigt werden, um eine 50% Chance einer Kollision zu haben, beträgt ungefähr 2^80 (die Formel zum berechnen der Kollisionswahrscheinlichkeit lautet ‚p = (n(n-1)/2) * (1/2^160))‘. 2^80 ist somit 1.2 x 10^24 oder eine Trilliarden. Das ist 1200 mal die Anzahl der Sandkörner die es auf der Erde gibt. +Allerdings solltest Du Dir bewusst machen, wie unglaublich unwahrscheinlich dieses Szenario ist. Die Länge des SHA-1-Hashs beträgt 20 Bytes oder 160 Bits. Die Anzahl der Objekte, die benötigt werden, um eine 50% Chance einer Kollision zu haben, beträgt ungefähr 2^80 (die Formel zum Berechnen der Kollisionswahrscheinlichkeit lautet `p = (n(n-1)/2) * (1/2^160))`. 2^80 ist somit 1.2 x 10^24 oder eine Trilliarde. Das ist 1200 Mal so viel, wie es Sandkörner auf der Erde gibt. -Hier ist ein Beispiel welches Dir eine Vorstellung davon geben wird was nötig ist um in SHA-1 eine Kollision zu bekommen. Wenn alle 6,5 Milliarden Menschen auf der Erde Programmieren würden und jeder jede Sekunde Code schreiben würde, der der gesamten Geschichte des Linux Kernels (1 Millionen Git Objekte) entspricht und diesen dann in ein gigantisches Git Repository übertragen würden, würde es fünf Jahre dauern bis das Repository genügend Objekte hätte um eine 50% Wahrscheinlichkeit für eine einzige SHA-1 Kollision aufzuweisen. Es ist wahrscheinlicher das jedes Mitglied Deines Programmierer Teams, unabhängig voneinander, in einer Nacht von Wölfen angegriffen und getötet wird. +Hier ist ein Beispiel, das Dir eine Vorstellung davon gibt, was nötig ist, um in SHA-1 eine Kollision zu bekommen. Wenn alle 6,5 Milliarden Menschen auf der Erde programmieren würden und jeder jede Sekunde Code schreiben würde, der der gesamten Geschichte des Linux-Kernels (1 Million Git-Objekte) entspricht, und diesen dann in ein gigantisches Git-Repository übertragen würde, würde es fünf Jahre dauern, bis das Repository genügend Objekte hätte, um eine 50% Wahrscheinlichkeit für eine einzige SHA-1-Kollision aufzuweisen. Es ist wahrscheinlicher, dass jedes Mitglied Deines Programmierer-Teams, unabhängig voneinander, in einer Nacht von Wölfen angegriffen und getötet wird. ### Branch Referenzen ### -Am direktesten kannst Du einen Commit spezifizieren, wenn eine Branch Referenz direkt auf ihn zeigt. In dem Fall kannst Du in allen Git Befehlen, die ein Commit Objekt oder einen SHA-1 Wert erwarten, statt dessen den Branch Namen verwenden. Wenn Du z.B. den letzten Commit in einem Branch sehen willst, sind die folgenden Befehle äquivalent (vorausgesetzt der `topic1` Branch zeigt auf den Commit `ca82a6d`): +Am direktesten kannst Du einen Commit spezifizieren, wenn eine Branch-Referenz direkt auf ihn zeigt. In dem Fall kannst Du in allen Git-Befehlen, die ein Commit-Objekt oder einen SHA-1-Wert erwarten, stattdessen den Branch-Namen verwenden. Wenn Du z.B. den letzten Commit in einem Branch sehen willst, sind die folgenden Befehle äquivalent (vorausgesetzt der `topic1` Branch zeigt auf den Commit `ca82a6d`): $ git show ca82a6dff817ec66f44342007202690a93763949 $ git show topic1 -Wenn Du sehen willst, auf welchen SHA-1 Wert ein Branch zeigt, oder wie unsere Beispiele intern in SHA-1 Werte übersetzt aussähen, kannst Du den Git Plumbing Befehl `rev-parse` verwenden. In Kapitel 9 werden wir genauer auf Plumbing Befehle eingehen. Kurz gesagt ist `rev-parse` als eine Low-Level Operation gedacht und nicht dafür, im tagtäglichen Gebrauch eingesetzt zu werden. Aber es kann manchmal hilfreich sein, wenn man wissen muss, was unter der Haube vor sich geht: +Wenn Du sehen willst, auf welchen SHA-1-Wert ein Branch zeigt, oder wie unsere Beispiele intern in SHA-1-Werte übersetzt aussähen, kannst Du den Git-Plumbing-Befehl `rev-parse` verwenden. In Kapitel 9 werden wir genauer auf Plumbing-Befehle eingehen. Kurz gesagt ist `rev-parse` als eine Low-Level-Operation gedacht und nicht dafür, im tagtäglichen Gebrauch eingesetzt zu werden. Aber es kann manchmal hilfreich sein, wenn man wissen muss, was unter der Haube vor sich geht: $ git rev-parse topic1 ca82a6dff817ec66f44342007202690a93763949 @@ -116,7 +116,7 @@ Wenn Du sehen willst, auf welchen SHA-1 Wert ein Branch zeigt, oder wie unsere B -Eine andere Sache, die während Deiner täglichen Arbeit im Hintergrund passiert ist, dass Git ein sogenanntes Reflog führt, d.h. ein Log darüber, wohin Deine HEAD und Branch Referenzen in den letzten Monaten jeweils gezeigt haben. +Eine andere Sache, die während Deiner täglichen Arbeit im Hintergrund passiert ist, dass Git ein sogenanntes Reflog führt, d.h. ein Log darüber, wohin Deine HEAD- und Branch-Referenzen in den letzten Monaten jeweils gezeigt haben. @@ -133,7 +133,7 @@ Du kannst das Reflog mit `git reflog` anzeigen: -Immer dann, wenn ein Branch in irgendeiner Weise aktualisiert wird oder Du den aktuellen Branch wechselst, speichert Git diese Information ebenso im Reflog wie Commits und anderen Informationen. Wenn Du wissen willst, welches der fünfte Wert vor dem HEAD war, kannst Du die `@{n}` Referenz angeben, die Du in Reflog Ausgabe sehen kannst: +Immer dann, wenn ein Branch in irgendeiner Weise aktualisiert wird oder Du den aktuellen Branch wechselst, speichert Git diese Information ebenso im Reflog wie Commits und anderen Informationen. Wenn Du wissen willst, welches der fünfte Wert vor dem HEAD war, kannst Du die `@{n}` Referenz angeben, die Du in Reflog-Ausgabe sehen kannst: $ git show HEAD@{5} @@ -170,13 +170,13 @@ Um Reflog Informationen in einem Format wie in `git log` anzeigen, kannst Du `gi -Es ist wichtig zu verstehen, dass das Reflog ausschließlich lokale Daten enthält. Es ist ein Log darüber, was Du in Deinem Repository getan hast, und es ist nie dasselbe wie in einem anderen Clone des selben Repositories. Direkt nachdem Du ein Repository geklont hast, ist das Reflog leer, weil noch keine weitere Aktivität stattgefunden hat. `git show HEAD@{2.months.ago}` funktioniert nur dann, wenn das Projekt mindestens zwei Monate alt ist – wenn Du es vor fünf Minuten erst geklont hast, erhältst Du keine Ergebnisse. +Es ist wichtig zu verstehen, dass das Reflog ausschließlich lokale Daten enthält. Es ist ein Log darüber, was Du in Deinem Repository getan hast, und es ist nie dasselbe wie in einem anderen Klon des selben Repositorys. Direkt nachdem Du ein Repository geklont hast, ist das Reflog leer, weil noch keine weitere Aktivität stattgefunden hat. `git show HEAD@{2.months.ago}` funktioniert nur dann, wenn das Projekt mindestens zwei Monate alt ist – wenn Du es vor fünf Minuten erst geklont hast, erhältst Du keine Ergebnisse. ### Vorfahren Referenzen ### - -Suppose you look at the history of your project: + Außerdem kann man Commits über ihre Vorfahren spezifizieren. Wenn Du ein `^` ans Ende einer Referenz setzt, schlägt Git den direkten Vorfahren dieses Commits nach. Nehmen wir an, Deine Historie sieht so aus: @@ -204,7 +204,7 @@ Du kannst jetzt den vorletzten Commit mit `HEAD^` referenzieren, d.h. „den dir -Außerdem kannst Du nach dem `^` eine Zahl angeben. Beispielsweise heißt `d921970^2`: „der zweite Vorfahr von d921970“. Diese Syntax ist allerdings nur für Merge Commits nützlich, die mehr als einen Vorfahren haben. Der erste Vorfahr ist der Branch auf dem Du Dich beim Merge befandest, der zweite ist der Commit auf dem Branch den Du gemergt hast. +Außerdem kannst Du nach dem `^` eine Zahl angeben. Beispielsweise heißt `d921970^2`: „der zweite Vorfahr von d921970“. Diese Syntax ist allerdings nur für Merge Commits nützlich, die mehr als einen Vorfahren haben. Der erste Vorfahr ist der Branch, auf dem Du Dich beim Merge befandest, der zweite ist der Commit auf dem Branch, den Du gemergt hast. $ git show d921970^ commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b @@ -222,7 +222,7 @@ Außerdem kannst Du nach dem `^` eine Zahl angeben. Beispielsweise heißt `d9219 -Eine andere Vorfahren Spezifikation ist `~`. Dies bezieht sich ebenfalls auf den ersten Vorfahren, d.h. `HEAD~` und `HEAD^` sind äquivalent. Einen Unterschied macht es allerdings, wenn Du außerdem eine Zahl angibst. `HEAD~2` bedeutet z.B. „der Vorfahr des Vorfahren von HEAD“ oder „der n-te Vorfahr von HEAD“. Beispielsweise würde `HEAD~3` in der obigen Historie auf den folgenden Commit zeigen: +Eine andere Vorfahren-Spezifikation ist `~`. Dies bezieht sich ebenfalls auf den ersten Vorfahren, d.h. `HEAD~` und `HEAD^` sind äquivalent. Einen Unterschied macht es allerdings, wenn Du außerdem eine Zahl angibst. `HEAD~2` bedeutet z.B. „der Vorfahr des Vorfahren von HEAD“ oder „der n-te Vorfahr von HEAD“. Beispielsweise würde `HEAD~3` in der obigen Historie auf den folgenden Commit zeigen: $ git show HEAD~3 commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d @@ -251,14 +251,14 @@ Du kannst diese Schreibweisen auch kombinieren und z.B. auf den zweiten Vorfahre -Nachdem Du jetzt einzelne Commits spezifizieren kannst, schauen wir uns an, wie man auf Commit Reihen zugreift. Dies ist vor allem nützlich, um Branches zu verwalten, z.B. wenn man viele Branches hat und solche Fragen beantworten will wie „Welche Änderungen befinden sich in diesem Branch, die ich noch nicht in meinen Hauptbranch gemergt habe“. +Nachdem Du jetzt einzelne Commits spezifizieren kannst, schauen wir uns an, wie man auf Commit-Reihen zugreift. Dies ist vor allem nützlich, um Branches zu verwalten, z.B. wenn man viele Branches hat und solche Fragen beantworten will wie „Welche Änderungen befinden sich in diesem Branch, die ich noch nicht in meinen Hauptbranch gemergt habe?“. -#### Zwei-Punkte Syntax #### +#### Zwei-Punkte-Syntax #### -Die gängigste Weise, Commit Reihen anzugeben, ist die Zwei-Punkte Notation. Allgemein gesagt evaluiert Git eine Reihe von Commits, die von einem Commit aus erreichbar sind, nicht aber von einem anderen (xxx ??? xxx). Nehmen wir z.B. an, Du hättest eine Commit Historie wie die folgende (Bild 6-1). +Die gängigste Weise, Commit-Reihen anzugeben, ist die Zwei-Punkte-Notation. Allgemein gesagt evaluiert Git eine Reihe von Commits, die von einem Commit aus erreichbar sind, nicht aber von einem anderen (xxx ??? xxx). Nehmen wir z.B. an, Du hättest eine Commit-Historie wie die folgende (Bild 6-1). @@ -266,7 +266,7 @@ Insert 18333fig0601.png -Du willst jetzt herausfinden, welche Änderungen in Deinem `experiment` Branch sind, die noch nicht in den `master` Branch gemergt wurden. Dann kannst Du ein Log dieser Commits mit `master..experiment` anzeigen, d.h. „alle Commits, die von `experiment` aus erreichbar sind, aber nicht von `master`“. Um die folgenden Beispiele ein bisschen abzukürzen und deutlicher zu machen, verwende ich für die Commit Objekte die Buchstaben aus dem Diagramm anstelle der tatsächlichen Log Ausgabe: +Du willst jetzt herausfinden, welche Änderungen in Deinem `experiment`-Branch sind, die noch nicht in den `master`-Branch gemergt wurden. Dann kannst Du ein Log dieser Commits mit `master..experiment` anzeigen, d.h. „alle Commits, die von `experiment` aus erreichbar sind, aber nicht von `master`“. Um die folgenden Beispiele ein bisschen abzukürzen und deutlicher zu machen, verwende ich für die Commit-Objekte die Buchstaben aus dem Diagramm anstelle der tatsächlichen Log Ausgabe: $ git log master..experiment D @@ -282,21 +282,21 @@ Wenn Du allerdings – anders herum – diejenigen Commits anzeigen willst, die -Dies ist nützlich, wenn Du vorhast, den `experiment` Branch zu aktualisieren, und anzeigen willst, was Du dazu mergen wirst. Oder wenn Du vorhast, in ein Remote Repository zu pushen und sehen willst, welche Commits betroffen sind: +Dies ist nützlich, wenn Du vorhast, den `experiment`-Branch zu aktualisieren, und anzeigen willst, was Du dazu mergen wirst. Oder wenn Du vorhast, in ein Remote-Repository zu pushen und sehen willst, welche Commits betroffen sind: $ git log origin/master..HEAD -Dieser Befehl zeigt Dir alle Commits im gegenwärtigen, lokalen Branch, die noch nicht im `master` Branch des `origin` Repositories sind. D.h., der Befehl listet diejenigen Commits auf, die auf den Server transferiert würden, wenn Du `git push` benutzt und der aktuelle Branch `origin/master` trackt. Du kannst mit dieser Syntax außerdem eine Seite der beiden Punkte leer lassen. Git nimmt dann an, Du meinst an dieser Stelle HEAD. Z.B. kannst Du dieselben Commits wie im vorherigen Beispiel auch mit `git log origin/master..` anzeigen lassen. Git fügt dann HEAD auf der rechten Seite ein. +Dieser Befehl zeigt Dir alle Commits im gegenwärtigen, lokalen Branch, die noch nicht im `master`-Branch des `origin` Repositories sind. D.h., der Befehl listet diejenigen Commits auf, die auf den Server transferiert würden, wenn Du `git push` benutzt und der aktuelle Branch `origin/master` trackt. Du kannst mit dieser Syntax außerdem eine Seite der beiden Punkte leer lassen. Git nimmt dann an, Du meinst an dieser Stelle HEAD. Z.B. kannst Du dieselben Commits wie im vorherigen Beispiel auch mit `git log origin/master..` anzeigen lassen. Git fügt dann HEAD auf der rechten Seite ein. #### Mehrfache Punkte (xxx) #### -Die Zwei-Punkte Syntax ist eine nützliche Abkürzung, aber möglicherweise willst Du mehr als nur zwei Branches angeben, um z.B. herauszufinden, welche Commits in einem beliebigen anderen Branch enthalten sind, ausgenommen in demjenigen, auf dem Du Dich gerade befindest. Dazu kannst Du in Git das `^` Zeichen oder `--not` verwenden, um Commits auszuschließen, die von den angegebenen Referenzen aus erreichbar sind. D.h., die folgenden drei Befehle sind äquivalent: +Die Zwei-Punkte-Syntax ist eine nützliche Abkürzung, aber möglicherweise willst Du mehr als nur zwei Branches angeben, um z.B. herauszufinden, welche Commits in einem beliebigen anderen Branch enthalten sind, ausgenommen in demjenigen, auf dem Du Dich gerade befindest. Dazu kannst Du in Git das `^` Zeichen oder `--not` verwenden, um Commits auszuschließen, die von den angegebenen Referenzen aus erreichbar sind. D.h., die folgenden drei Befehle sind äquivalent: $ git log refA..refB $ git log ^refA refB @@ -304,7 +304,7 @@ Die Zwei-Punkte Syntax ist eine nützliche Abkürzung, aber möglicherweise will -Das ist praktisch, weil Du auf diese Weise mehr als nur zwei Referenzen angeben kannst, was mit der Zwei-Punkte Notation nicht geht. Wenn Du beispielsweise alle Commits sehen willst, die von `refA` oder `refB` erreichbar sind, nicht aber von `refC`, dann kannst Du folgende (äquivalente) Befehle benutzen: +Das ist praktisch, weil Du auf diese Weise mehr als nur zwei Referenzen angeben kannst, was mit der Zwei-Punkte-Notation nicht geht. Wenn Du beispielsweise alle Commits sehen willst, die von `refA` oder `refB` erreichbar sind, nicht aber von `refC`, dann kannst Du folgende (äquivalente) Befehle benutzen: $ git log refA refB ^refC $ git log refA refB --not refC @@ -319,7 +319,7 @@ Damit hast Du ein sehr mächtiges System von Abfragen zur Verfügung, mit denen -Die letzte wichtige Syntax, mit der man Commit Reihen spezifizieren kann, ist die Drei-Punkte Syntax, die alle Commits anzeigt, die in einer der beiden Referenzen enthalten sind, aber nicht in beiden. Schau Dir noch mal die Commit Historie in Bild 6-1- an. Wenn Du diejenigen Commits anzeigen willst, die in den `master` und `experiment` Branches, nicht aber in beiden Branches gleichzeitig enthalten sind, dann kannst Du folgendes tun: +Die letzte wichtige Syntax, mit der man Commit-Reihen spezifizieren kann, ist die Drei-Punkte-Syntax, die alle Commits anzeigt, die in einer der beiden Referenzen enthalten sind, aber nicht in beiden. Schau Dir noch mal die Commit Historie in Bild 6-1 an. Wenn Du diejenigen Commits anzeigen willst, die in den `master`- und `experiment`-Branches, nicht aber in beiden Branches gleichzeitig enthalten sind, dann kannst Du folgendes tun: $ git log master...experiment F @@ -329,7 +329,7 @@ Die letzte wichtige Syntax, mit der man Commit Reihen spezifizieren kann, ist di -Dies gibt Dir wiederum ein normale `log` Ausgabe, aber zeigt nur die Informationen dieser vier Commits – wie üblich sortiert nach dem Commit Datum. +Dies gibt Dir wiederum ein normale `log` Ausgabe, aber zeigt nur die Informationen dieser vier Commits – wie üblich sortiert nach dem Commit-Datum. @@ -351,7 +351,7 @@ Mit diesen Hilfsmitteln kannst Du noch einfacher und genauer angeben, welche Com -Git umfasst eine Reihe von Skripten, die so manche Aufgabe auf der Kommandozeile leichter machen. Im folgenden schauen wir uns einige interaktive Befehle an, die dabei hilfreich sein können, wenn man Änderungen in vielen Dateien vorgenommen hat, aber nur einige Änderungen gezielt committen will – nicht alles auf einmal in einem riesigen Commit. Auf diese Weise kann man Commits logisch gruppieren und macht es anderen Entwicklern damit leichter, sie zu verstehen. Wenn Du `git add` mit der `-i` oder `--interactive` Option verwendest, geht Git in einen interaktiven Shell Modus, der in etwa wie folgt aussieht: +Git umfasst eine Reihe von Skripten, die so manche Aufgabe auf der Kommandozeile leichter machen. Im Folgenden schauen wir uns einige interaktive Befehle an, die dabei hilfreich sein können, wenn man Änderungen in vielen Dateien vorgenommen hat, aber nur einige Änderungen gezielt committen will – nicht alles auf einmal in einem riesigen Commit. Auf diese Weise kann man Commits logisch gruppieren und macht es anderen Entwicklern damit leichter, sie zu verstehen. Wenn Du `git add` mit der `-i` oder `--interactive` Option verwendest, geht Git in einen interaktiven Shell-Modus, der in etwa wie folgt aussieht: $ git add -i staged unstaged path @@ -366,7 +366,7 @@ Git umfasst eine Reihe von Skripten, die so manche Aufgabe auf der Kommandozeile -Wie Du siehst zeigt dieser Befehl eine andere Ansicht der Staging Area an – im wesentlichen also die Information, die Du auch mit `git status` erhältst, aber anders formatiert, ein bisschen kürzer (xxx succinct? xxx) und informativer. Sie listet alles Änderungen, die in der Staging Area enthalten sind, auf der linken Seite, und alle anderen Änderungen auf der rechten Seite. +Wie Du siehst, zeigt dieser Befehl eine andere Ansicht der Staging-Area an – im Wesentlichen also die Information, die Du auch mit `git status` erhältst, aber anders formatiert, kurz und knapp, und informativer. Sie listet alle Änderungen, die in der Staging-Area enthalten sind, auf der linken Seite, und alle anderen Änderungen auf der rechten Seite. @@ -377,7 +377,7 @@ Danach folgt eine Liste von Befehlen wie, u.a., Dateien ganz oder teilweise stag -Wenn Du am `What now>` Prompt `2` oder `u` eingibst, wirst Du als nächstes gefragt, welche Dateien Du stagen willst: +Wenn Du am `What now>` Prompt `2` oder `u` eingibst, wirst Du als Nächstes gefragt, welche Dateien Du stagen willst: What now> 2 staged unstaged path @@ -399,7 +399,7 @@ Um z.B. die TODO und index.html Dateien zu stagen, gibst Du die jeweiligen Zahle -Das `*` neben den Dateinamen bedeutet, dass die Datei ausgewählt ist und zur Staging Area hinzugefügt werden wird, sobald Du (bei einem sonst leeren `Update>>` Prompt) Enter drückst: +Das `*` neben den Dateinamen bedeutet, dass die Datei ausgewählt ist und zur Staging-Area hinzugefügt werden wird, sobald Du (bei einem sonst leeren `Update>>` Prompt) Enter drückst: Update>> updated 2 paths @@ -415,7 +415,7 @@ Das `*` neben den Dateinamen bedeutet, dass die Datei ausgewählt ist und zur St -Du kannst sehen, dass die TODO und index.html Dateien jetzt gestaged sind, während simplegit.rb immer noch ungestaged ist. Wenn Du die TODO unstagen willst, kannst Du die Option `3` oder `r` (für revert) nutzen: +Du kannst sehen, dass die TODO und index.html Dateien jetzt gestaget sind, während simplegit.rb immer noch ungestaget ist. Wenn Du die TODO unstagen willst, kannst Du die Option `3` oder `r` (für revert) nutzen: *** Commands *** 1: status 2: update 3: revert 4: add untracked @@ -435,7 +435,7 @@ Du kannst sehen, dass die TODO und index.html Dateien jetzt gestaged sind, währ -Wenn Du wiederum Deinen Git status ansiehst, kannst Du sehen dass Du die TODO ungestaged hast. +Wenn Du wiederum Deinen Git-Status ansiehst, kannst Du sehen, dass Du die TODO ungestaget hast. *** Commands *** 1: status 2: update 3: revert 4: add untracked @@ -448,7 +448,7 @@ Wenn Du wiederum Deinen Git status ansiehst, kannst Du sehen dass Du die TODO un -Um einen Diff dessen zu sehen, das Du gestaged hast, kannst Du den Befehl `6` oder `d` (für diff) nutzen. Dieser zeigt Dir eine Liste der gestageden Dateien, und Du kannst diejenigen auswählen, von denen Du den gestageden Diff sehen willst. Dies ähnelt sehr dem Befehl `git diff --cached` auf der Kommandozeile. +Um einen Diff dessen zu sehen, das Du gestaget hast, kannst Du den Befehl `6` oder `d` (für diff) nutzen. Dieser zeigt Dir eine Liste der gestageten Dateien, und Du kannst diejenigen auswählen, von denen Du den gestageten Diff sehen willst. Dies ähnelt sehr dem Befehl `git diff --cached` auf der Kommandozeile. *** Commands *** 1: status 2: update 3: revert 4: add untracked @@ -472,14 +472,14 @@ Um einen Diff dessen zu sehen, das Du gestaged hast, kannst Du den Befehl `6` od -Mit diesen grundlegenden Befehlen kannst Du den interaktiven add Modus nutzen um Dir den Umgang mit Deiner Staging area etwas zu erleichtern. +Mit diesen grundlegenden Befehlen kannst Du den interaktiven add Modus nutzen, um Dir den Umgang mit Deiner Staging-Area etwas zu erleichtern. ### Patches stagen ### -Es ist für Git auch möglich bestimmte Teile einer Datei zu stagen und nicht den Rest. Wenn Du z. B. 2 Veränderungen an der simplegit.rb machst und eine davon stagen willst und die andere nicht, ist dies sehr einfach in Git möglich. Wähle `5` oder `p` (für patch) auf dem interactive prompt. Git wird Dich fragen welche Dateien Du teilweise stagen willst; dann wird es für jeden Abschnitt der gewählten Dateien diff hunks ausgeben und Dich jeweils einzeln fragen ob Du sie stagen willst. +Es ist für Git auch möglich, bestimmte Teile einer Datei zu stagen und nicht den Rest. Wenn Du z.B. 2 Veränderungen an der simplegit.rb machst und eine davon stagen willst und die andere nicht, ist dies sehr einfach in Git möglich. Wähle `5` oder `p` (für patch) auf dem interaktiven Prompt. Git wird Dich fragen, welche Dateien Du teilweise stagen willst; dann wird es für jeden Abschnitt der gewählten Dateien Diff-Ausschnitte ausgeben und Dich jeweils einzeln fragen, ob Du sie stagen willst. diff --git a/lib/simplegit.rb b/lib/simplegit.rb index dd5ecc4..57399e0 100644 @@ -498,7 +498,7 @@ Es ist für Git auch möglich bestimmte Teile einer Datei zu stagen und nicht de -Du hast an diesem Punkt viele Options. Tippe `?` ein um eine Liste der Möglichkeiten zu bekommen: +Du hast an diesem Punkt viele Optionen. Tippe `?` ein, um eine Liste der Möglichkeiten zu bekommen: Stage this hunk [y,n,a,d,/,j,J,g,e,?]? ? y - stage this hunk @@ -517,7 +517,7 @@ Du hast an diesem Punkt viele Options. Tippe `?` ein um eine Liste der Möglichk -Im Allgemeinen, wirst Du `y` oder `n` nutzen wenn Du jeden Hunk stagen willst, aber alle Hunks in bestimmten Dateien zu stagen oder die Entscheidung für einen Hunk auf später zu verschieben kann auch sehr hilfreich sein. Wenn Du nur einen Teil der Datei stagest und den anderen ungestaged lässt, sieht Deine Status-Ausgabe in etwa so aus: +Im Allgemeinen, wirst Du `y` oder `n` nutzen, wenn Du jeden Ausschnitt stagen willst, aber alle Ausschnitte in bestimmten Dateien zu stagen oder die Entscheidung für einen Ausschnitt auf später zu verschieben kann auch sehr hilfreich sein. Wenn Du nur einen Teil der Datei stagest und den anderen ungestaget lässt, sieht Deine Status-Ausgabe in etwa so aus: What now> 1 staged unstaged path @@ -527,11 +527,11 @@ Im Allgemeinen, wirst Du `y` oder `n` nutzen wenn Du jeden Hunk stagen willst, a -Der Status der simplegit.rb ist interessant. Er zeigt Dir, dass ein paar Zeilen gestagd und ein paar ungestaged sind. Du hast diese Datei teilweise gestaged. An dieser Stelle kannst Du das interaktive add Skript verlassen und `git commit` ausführen, um die teilweise gestageden Dateien zu commiten. +Der Status der simplegit.rb ist interessant. Er zeigt Dir, dass ein paar Zeilen gestaget und ein paar ungestaget sind. Du hast diese Datei teilweise gestaget. An dieser Stelle kannst Du das interaktive Hinzufüge-Skript verlassen und `git commit` ausführen, um die teilweise gestageten Dateien zu commiten. -Letztendlich musst Du nicht den interactive add Modus nutzen um Dateien teilweise zu stagen – Du kannst das gleiche Skript starten in dem Du `git add -p` oder `git add --patch` auf der Kommandozeile eingibst. +Letztendlich musst Du nicht den interaktiven Hinzufüge-Modus nutzen, um Dateien teilweise zu stagen – Du kannst das gleiche Skript starten, indem Du `git add -p` oder `git add --patch` auf der Kommandozeile eingibst. ## Stashen ## @@ -542,14 +542,14 @@ Während man an einer bestimmten Funktion eines Projekts arbeitet, ist es oft so -Beim Stashen werden die aus Deinem Arbeitsverzeichnis noch nicht committeten Änderungen – also Deine geänderten beobachteten Dateien und die in der Staging Area enthaltenen Dateien – in einem Stack voller unfertiger Änderungen gespeichert. Diese kannst Du dann jederzeit wieder vom Stack holen und auf Dein Arbeitsverzeichnis anwenden. +Beim Stashen werden die aus Deinem Arbeitsverzeichnis noch nicht committeten Änderungen – also Deine geänderten beobachteten Dateien und die in der Staging-Area enthaltenen Dateien – in einem Stack voller unfertiger Änderungen gespeichert. Diese kannst Du dann jederzeit wieder vom Stack holen und auf Dein Arbeitsverzeichnis anwenden. ### Stash verwenden ### -Um dies zu demonstrieren, gehst Du in Dein Projekt und beginnst an ein paar Dateien zu arbeiten und merkst ein paar dieser Änderungen in der Staging Area vor. Wenn Du den Befehl `git status` ausführst, siehst Du, dass sich einige Dateien seit dem letzen Commit verändert haben. +Um dies zu demonstrieren, gehst Du in Dein Projekt und beginnst an ein paar Dateien zu arbeiten und merkst ein paar dieser Änderungen in der Staging-Area vor. Wenn Du den Befehl `git status` ausführst, siehst Du, dass sich einige Dateien seit dem letzen Commit verändert haben. $ git status # On branch master @@ -566,7 +566,7 @@ Um dies zu demonstrieren, gehst Du in Dein Projekt und beginnst an ein paar Date -Jetzt kommt der Zeitpunkt an dem Du den aktuellen Branch wechseln möchtest. Allerdings willst Du den aktuellen Zustand auch nicht committen, da Deine Arbeit noch nicht ganz fertiggestellt ist. Darum legst Du Deine Änderungen jetzt in einem Stash ab. Um diesen neuen Stash auf dem Stack abzulegen, verwendest Du den Befehl `git stash`: +Jetzt kommt der Zeitpunkt, an dem Du den aktuellen Branch wechseln möchtest. Allerdings willst Du den aktuellen Zustand auch nicht committen, da Deine Arbeit noch nicht ganz fertiggestellt ist. Darum legst Du Deine Änderungen jetzt in einem Stash ab. Um diesen neuen Stash auf dem Stack abzulegen, verwendest Du den Befehl `git stash`: $ git stash Saved working directory and index state \ @@ -576,7 +576,7 @@ Jetzt kommt der Zeitpunkt an dem Du den aktuellen Branch wechseln möchtest. All -In Deinem Arbeitsverzeichnis befinden sich jetzt keine geänderten Dateien mehr und die Staging Area ist auch leer: +In Deinem Arbeitsverzeichnis befinden sich jetzt keine geänderten Dateien mehr und die Staging-Area ist auch leer: $ git status # On branch master @@ -593,7 +593,7 @@ In diesem Zustand, kannst Du in beliebig andere Branches wechseln und an etwas a -In diesem Beispiel waren bereits zwei Stashes auf dem Stack vorhanden. Sie wurden zu einem früheren Zeitpunkt gespeichert. Dir stehen jetzt also drei verschiedene Stashes auf dem Stack zur Verfügung. Mit dem Befehl `git stash apply` kannst Du die zuletzt gestashten Änderungen in Deinem Arbeitsverzeichnis wiederherstellen. Git zeigt diesen Befehlsaufruf auch bei Ausführen des Befehls `git stash` als Hilfestellung an. Wenn Du einen der älteren Stashes auf Dein Arbeitsverzeichnis anwenden willst, kannst Du den entsprechenden Stashnamen an den Befehl anhängen: `git stash apply stash@{2}`. Wie Du bereits gesehen hast, verwendet Git die zuletzt gestashten Änderungen und versucht diese im Arbeitsverzeichnis wiederherzuellen, wenn der Stashname nicht angegeben wird: +In diesem Beispiel waren bereits zwei Stashes auf dem Stack vorhanden. Sie wurden zu einem früheren Zeitpunkt gespeichert. Dir stehen jetzt also drei verschiedene Stashes auf dem Stack zur Verfügung. Mit dem Befehl `git stash apply` kannst Du die zuletzt gestashten Änderungen in Deinem Arbeitsverzeichnis wiederherstellen. Git zeigt diesen Befehlsaufruf auch bei Ausführen des Befehls `git stash` als Hilfestellung an. Wenn Du einen der älteren Stashes auf Dein Arbeitsverzeichnis anwenden willst, kannst Du den entsprechenden Stashnamen an den Befehl anhängen: `git stash apply stash@{2}`. Wie Du bereits gesehen hast, verwendet Git die zuletzt gestashten Änderungen und versucht diese im Arbeitsverzeichnis wiederherzustellen, wenn der Stashname nicht angegeben wird: $ git stash apply # On branch master @@ -610,7 +610,7 @@ Wie Du sehen kannst, stellt Git die Dateien wieder her, die Du in einem Stash ge -Die Änderungen an den Dateien wurden in Deinem Arbeitsverzeichnis wiederhergestellt. Allerdings ist die Datei, die beim Stashen in der Staging Area vorhanden war, nicht automatisch wieder in die Staging Area gewandert. Wenn Du die Option `--index` an den Befehl `git stash apply` anhängst, wird Git versuchen, die Dateien wieder zu stagen. Wenn Du diesen Befehl angewandt hättest, wäre Dein Arbeitsverzeichnis und Deine Staging Area im exakt gleichen Zustand, wie vor dem Stashen: +Die Änderungen an den Dateien wurden in Deinem Arbeitsverzeichnis wiederhergestellt. Allerdings ist die Datei, die beim Stashen in der Staging-Area vorhanden war, nicht automatisch wieder in die Staging-Area gewandert. Wenn Du die Option `--index` an den Befehl `git stash apply` anhängst, wird Git versuchen, die Dateien wieder zu stagen. Wenn Du diesen Befehl angewandt hättest, wäre Dein Arbeitsverzeichnis und Deine Staging-Area im exakt gleichen Zustand, wie vor dem Stashen: $ git stash apply --index # On branch master @@ -627,7 +627,7 @@ Die Änderungen an den Dateien wurden in Deinem Arbeitsverzeichnis wiederhergest -Mit der Option `apply` wird nur versucht die Änderungen wiederherzustellen. Der Stash an sich bleibt weiterhin auf dem Stack vorhanden. Um diesen zu entfernen kannst Du den Befehl `git stash drop` zusammen mit dem Namen des Stashes anwenden: +Mit der Option `apply` wird nur versucht die Änderungen wiederherzustellen. Der Stash an sich bleibt weiterhin auf dem Stack vorhanden. Um diesen zu entfernen, kannst Du den Befehl `git stash drop` zusammen mit dem Namen des Stashes anwenden: $ git stash list stash@{0}: WIP on master: 049d078 added the index file @@ -720,11 +720,11 @@ Nach Eingabe dieses Befehls wird der Texteditor mit dem Inhalt der letzten Commi -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. +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. +Mit dem Befehl `--amend` sollte man vorsichtig umgehen, weil sich mit jeder nachträglichen Modifikation eines Commits auch die SHA-1-Prüfsumme ändert. 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 ### @@ -855,7 +855,7 @@ Man kann mit einem interaktiven Rebase auch mehrere Commits zu einem einzelnen C -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: +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 @@ -887,7 +887,7 @@ Du kannst nun die Commit-Nachricht entsprechend anpassen oder auch entsprechend -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 angezeigte Skript, welches Dir der Befehl `rebase -i` erzeugt, folgendermaßen anpassen: +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 angezeigte 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 @@ -938,18 +938,18 @@ Dieses Szenario tritt sogar relativ häufig auf. Nehmen wir einmal an, jemand f -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. +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. +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: +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) @@ -978,7 +978,7 @@ Verflixt, es ist schon wieder passiert. Du hast vergessen, den Befehl `git confi -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 wird 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. +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 wird 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 ## @@ -1009,11 +1009,11 @@ Wenn Du nach einem Bug in Deinem Code suchst und gerne wissen willst, wann und w -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 bisschen 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. +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 SHA-1-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 bisschen verwirrend, denn nun kennst Du bereits drei Möglichkeiten, wie Git mit dem Zeichen `^` einer SHA-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 aufgeteilt, 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: +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 angegebene 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 aufgeteilt, 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) @@ -1069,7 +1069,7 @@ Git hat Dir jetzt einen weiteren Commit ausgecheckt, und zwar wieder den mittler -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 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 SHA-1-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 @@ -1108,18 +1108,18 @@ Oft möchte man während der Arbeit an einem Projekt ein weiteres Projekt darin -Dazu ein Beispiel. Nehmen wir an, Du entwickelt gerade eine Webseite, die unter anderem einen Atom-Feed zur Verfügung stellen soll. Anstatt den notwendigen Code zur Auslieferung des Atom-Feeds selber zu schreiben, entscheidest Du Dich für eine geeignete Bibliothek. Dann wirst Du wahrscheinlich den Code in Dein Projekt inkludieren müssen, zum Beispiel durch eine CPAN-Installation oder ein Ruby-Gem oder durch Kopieren des Quellcodes in das Arbeitsverzeichnis Deines Projekts. Das Problem beim Einbinden einer Bibliothek ist, dass es schwierig ist, diese an die eigene Bedürfnisse anzupassen. Noch schwieriger gestaltet sich dann die Veröffentlichung des Projekts, da man sicherstellen muss, dass jeder der die Software verwendet, auf die Bibliothek zugreifen kann. Wenn man die Bibliothek im eigenen Projekt projektspezifisch anpasst, hat man meist ein Problem, wenn man eine neue Version der Bibliothek einspielen will. +Dazu ein Beispiel. Nehmen wir an, Du entwickelst gerade eine Webseite, die unter anderem einen Atom-Feed zur Verfügung stellen soll. Anstatt den notwendigen Code zur Auslieferung des Atom-Feeds selber zu schreiben, entscheidest Du Dich für eine geeignete Bibliothek. Dann wirst Du wahrscheinlich den Code in Dein Projekt einbinden müssen, zum Beispiel durch eine CPAN-Installation oder ein Ruby-Gem oder durch Kopieren des Quellcodes in das Arbeitsverzeichnis Deines Projekts. Das Problem beim Einbinden einer Bibliothek ist, dass es schwierig ist, diese an die eigene Bedürfnisse anzupassen. Noch schwieriger gestaltet sich dann die Veröffentlichung des Projekts, da man sicherstellen muss, dass jeder der die Software verwendet, auf die Bibliothek zugreifen kann. Wenn man die Bibliothek im eigenen Projekt projektspezifisch anpasst, hat man meist ein Problem, wenn man eine neue Version der Bibliothek einspielen will. -Git löst dieses Problem mit Hilfe von Submodulen. Mit Hilfe von Submodulen kann man innerhalb eines Git Repositorys ein weiteres Git Repository in einem Unterverzeichnis verwalten. Daraus entsteht der Vorteil, dass man ein anderes Repository in das eigene Projekt klonen kann und die Commits der jeweiligen Projekte trennen kann. +Git löst dieses Problem mit Hilfe von Submodulen. Mit Hilfe von Submodulen kann man innerhalb eines Git-Repositorys ein weiteres Git-Repository in einem Unterverzeichnis verwalten. Daraus entsteht der Vorteil, dass man ein anderes Repository in das eigene Projekt klonen kann und die Commits der jeweiligen Projekte trennen kann. ### Die ersten Schritte mit Submodulen ### -Nehmen wir einmal an, dass Du die Rack-Bibliothek (eine Ruby Gateway-Schnittstelle für Webserver) zu Deinem Projekt hinzufügen willst. Dabei möchtest Du Deine eigenen Änderungen an dieser Bibliothek nachverfolgen, aber auch weiterhin Änderungen von den Rack Bibliothek-Entwicklern verwalten und zusammenmergen. Das erste was Du dazu tun musst, ist das Repository der Rack Bibliothek in ein Unterverzeichnis Deines Projekts zu klonen. Diesen Vorgang kannst Du mit Hilfe des Befehls `git submodule add` ausführen: +Nehmen wir einmal an, dass Du die Rack-Bibliothek (eine Ruby-Gateway-Schnittstelle für Webserver) zu Deinem Projekt hinzufügen willst. Dabei möchtest Du Deine eigenen Änderungen an dieser Bibliothek nachverfolgen, aber auch weiterhin Änderungen von den Rack-Bibliothek-Entwicklern verwalten und zusammenmergen. Das erste was Du dazu tun musst, ist das Repository der Rack Bibliothek in ein Unterverzeichnis Deines Projekts zu klonen. Diesen Vorgang kannst Du mit Hilfe des Befehls `git submodule add` ausführen: $ git submodule add git://github.com/chneukirchen/rack.git rack Initialized empty Git repository in /opt/subtest/rack/.git/ @@ -1131,7 +1131,7 @@ Nehmen wir einmal an, dass Du die Rack-Bibliothek (eine Ruby Gateway-Schnittstel -Innerhalb Deines Projekts befindet sich nun im Unterverzeichnis `rack` das komplette Rack-Projekt. Man kann jetzt in diesem Verzeichnis Änderungen vornehmen und ein eigenes Remote Repository mit Schreibrechten, zu welchem man pushen kann, hinzufügen. Ebenso ist es möglich, Änderungen von den Rack Entwicklern in sein Repository zu laden und diese mit den eigenen Ergebnissen zu mergen. Im Prinzip kann man innerhalb eines Submoduls die gleichen Vorgänge, wie in einem normalen Repository ausführen. Vorher müssen wir aber noch ein paar weitere Dinge zu Submodulen besprechen. Wenn Du gleich nach dem Hinzufügen des Submoduls, den Befehl `git status` ausführst, wirst Du gleich zwei Dinge bemerken: +Innerhalb Deines Projekts befindet sich nun im Unterverzeichnis `rack` das komplette Rack-Projekt. Man kann jetzt in diesem Verzeichnis Änderungen vornehmen und ein eigenes Remote Repository mit Schreibrechten, zu welchem man pushen kann, hinzufügen. Ebenso ist es möglich, Änderungen von den Rack-Entwicklern in sein Repository zu laden und diese mit den eigenen Ergebnissen zu mergen. Im Prinzip kann man innerhalb eines Submoduls die gleichen Vorgänge, wie in einem normalen Repository ausführen. Vorher müssen wir aber noch ein paar weitere Dinge zu Submodulen besprechen. Wenn Du gleich nach dem Hinzufügen des Submoduls, den Befehl `git status` ausführst, wirst Du gleich zwei Dinge bemerken: $ git status # On branch master @@ -1170,7 +1170,7 @@ Die zweite Auffälligkeit bei der Ausgabe von `git status` ist der Eintrag rack. -Obwohl `rack` ein Unterverzeichnis in Deinem Arbeitsverzeichnis ist, erkennt Git dieses Verzeichnis als Submodul und verfolgt die Änderungen innerhalb dieses Verzeichnis nicht, wenn Git nicht innerhalb dieses Verzeichnis aufgerufen wird. Stattdessen erfässt Git, welcher Commit in diesem Repository ausgecheckt ist. Wenn Du also Änderungen in diesem Unterverzeichnis durchführst und eincheckst, kann das Superprojekt erkennen, dass sich der aktuelle HEAD von diesem Projekt geändert hat. Das Superprojekt kann sich jetzt diesen Commit merken. Auf diese Art und Weise ist es möglich den kompletten Zustand des Projekts mit allen Projekten, die als Submodul hinzugefügt wurden, zu reproduzieren. In der Git Terminologie wird das Projekt, welches eines oder mehrere Submodule enthält, als Superprojekt bezeichnet. +Obwohl `rack` ein Unterverzeichnis in Deinem Arbeitsverzeichnis ist, erkennt Git dieses Verzeichnis als Submodul und verfolgt die Änderungen innerhalb dieses Verzeichnisses nicht, wenn Git nicht innerhalb dieses Verzeichnisses aufgerufen wird. Stattdessen erfässt Git, welcher Commit in diesem Repository ausgecheckt ist. Wenn Du also Änderungen in diesem Unterverzeichnis durchführst und eincheckst, kann das Superprojekt erkennen, dass sich der aktuelle HEAD von diesem Projekt geändert hat. Das Superprojekt kann sich jetzt diesen Commit merken. Auf diese Art und Weise ist es möglich, den kompletten Zustand des Projekts mit allen Projekten, die als Submodul hinzugefügt wurden, zu reproduzieren. In der Git-Terminologie wird das Projekt, welches eines oder mehrere Submodule enthält, als Superprojekt bezeichnet. @@ -1188,11 +1188,11 @@ Wenn Du Dein Projekt das erste Mal eincheckst, erhältst Du in etwa folgende Aus -Der Mode 160000, der für den rack Eintrag gilt, ist ein spezieller Mode in Git. Er bedeutet in etwa, dass man einen Commit als Verzeichnis-Eintrag in Git verwaltet und damit nicht wie normalerweise ein Verzeichnis oder eine Datei. +Der Mode 160000, der für den rack-Eintrag gilt, ist ein spezieller Mode in Git. Er bedeutet in etwa, dass man einen Commit als Verzeichnis-Eintrag in Git verwaltet und damit nicht wie normalerweise ein Verzeichnis oder eine Datei. -Das Verzeichnis `rack` kann man wie ein separates Projekt behandeln und verwenden. Und von Zeit zur Zeit aktualisiert man auch das Superprojekt und speichert damit die letzte Commit Id des Unterprojekts. Jedes Git Kommando arbeitet unabhängig in einem der beiden Unterverzeichnisse: +Das Verzeichnis `rack` kann man wie ein separates Projekt behandeln und verwenden. Und von Zeit zur Zeit aktualisiert man auch das Superprojekt und speichert damit die letzte Commit-ID des Unterprojekts. Jedes Git-Kommando arbeitet unabhängig in einem der beiden Unterverzeichnisse: $ git log -1 commit 0550271328a0038865aad6331e620cd7238601bb @@ -1231,7 +1231,7 @@ Als nächstes klonen wir ein Projekt, welches ein Submodul verwendet. Wenn man e -Das Verzeichnis `rack` wurde zwar erzeugt, aber es ist leer. Deshalb musst Du zwei Dinge ausführen: `git submodule init`, damit wird die Datei für die lokale Konfiguration initiailisiert. Und `git submodule update`, welches die gesamten Daten des Projekts von der im `.gitmodules` angegebenen Quelle holt und den entsprechenden Commit, welcher im Superprojekt hinterlegt ist, auscheckt: +Das Verzeichnis `rack` wurde zwar erzeugt, aber es ist leer. Deshalb musst Du zwei Dinge ausführen: `git submodule init`, damit wird die Datei für die lokale Konfiguration initialisiert. Und `git submodule update`, welches die gesamten Daten des Projekts von der im `.gitmodules` angegebenen Quelle holt und den entsprechenden Commit, welcher im Superprojekt hinterlegt ist, auscheckt: $ git submodule init Submodule 'rack' (git://github.com/chneukirchen/rack.git) registered for path 'rack' @@ -1246,7 +1246,7 @@ Das Verzeichnis `rack` wurde zwar erzeugt, aber es ist leer. Deshalb musst Du zw -Nach Ausführung der beiden Befehle befindet sich das Verzeichnis `rack` in genau dem gleichen Zustand, wie wir es ursprünglich eingecheckt haben. Wenn ein anderer Entwickler Änderungen am Rack Code durchführt, diese eincheckt und Du diese dann pullst und mergst, erhält man einen etwas seltsamen Zustand: +Nach Ausführung der beiden Befehle befindet sich das Verzeichnis `rack` in genau dem gleichen Zustand, wie wir es ursprünglich eingecheckt haben. Wenn ein anderer Entwickler Änderungen am Rack-Code durchführt, diese eincheckt und Du diese dann pullst und mergst, erhält man einen etwas seltsamen Zustand: $ git merge origin/master Updating 0550271..85a3eee @@ -1324,14 +1324,14 @@ In manchen großen Projekten möchten die Entwickler die Arbeit in verschiedenen -In Git kann man diese Vorgehensweise gut abbilden, indem man für jedes Unterverzeichnis ein neues Git Repository erzeugt. Zusätzlich kann man dann ein Superprojekt erzeugen und die ganzen Git Repositorys als Submodul hinzufügen. Ein Vorteil dabei ist, dass man mit Hilfe von Tags und Branches im Superprojekt das Verhältnis der einzelnen Submodule zueinander festhalten kann. +In Git kann man diese Vorgehensweise gut abbilden, indem man für jedes Unterverzeichnis ein neues Git-Repository erzeugt. Zusätzlich kann man dann ein Superprojekt erzeugen und die ganzen Git-Repositorys als Submodul hinzufügen. Ein Vorteil dabei ist, dass man mit Hilfe von Tags und Branches im Superprojekt das Verhältnis der einzelnen Submodule zueinander festhalten kann. ### Häufige Probleme mit Submodulen ### -Die Arbeit mit Submodulen verläuft jedoch nicht immer reibungslos. Man muss verhältnismäßig gut aufpassen, wenn man in einem Submodul-Verzeichnis arbeitet. Wenn man nämlich den Befehl `git submodule update` ausführt, checkt Git den entsprechenden Zustand des Commits aus, aber checkt dabei keinen Branch aus. Diesen Zustand nennt man auch `detached HEAD`. Das bedeutet, dass die Datei HEAD direkt auf einen Commit zeigt und nicht wie sonst üblich auf eine symbolische Referenz, also zum Beispiel auf einen Branch. Das Problem dabei ist, dass man normalerweise in einem solchen Zustand nicht weiterarbeiten möchte, weil es sehr leicht vorkommen kann, dass Änderungen verloren gehen. Wenn man also den Befehl `git submodule update` aufruft, dann einen Commit in dem entsprechenden Submodul-Verzeichnis ausführt, ohne davor einen Branch auszuchecken, und dann noch einmal `git submodule update` im Superprojekt aufruft, ohne dass man die Änderungen im Submodul im Superprojekt eingecheckt hat, verliert man die ganzen Änderungen, ohne dass Git einen darauf vorher hinweist. Tatsächlich ist es so, dass die Änderungen nicht verloren gehen, aber es gibt keinen Branch, der auf die entsprechenden Commits hinzeigt, und damit kann es schwierig werden, die entsprechenden Commits wiederherzustellen beziehungsweise sichtbar zu machen. +Die Arbeit mit Submodulen verläuft jedoch nicht immer reibungslos. Man muss verhältnismäßig gut aufpassen, wenn man in einem Submodul-Verzeichnis arbeitet. Wenn man nämlich den Befehl `git submodule update` ausführt, checkt Git den entsprechenden Zustand des Commits aus, aber checkt dabei keinen Branch aus. Diesen Zustand nennt man auch `detached HEAD`. Das bedeutet, dass die Datei HEAD direkt auf einen Commit zeigt und nicht, wie sonst üblich, auf eine symbolische Referenz, also zum Beispiel auf einen Branch. Das Problem dabei ist, dass man normalerweise in einem solchen Zustand nicht weiterarbeiten möchte, weil es sehr leicht vorkommen kann, dass Änderungen verloren gehen. Wenn man also den Befehl `git submodule update` aufruft, dann einen Commit in dem entsprechenden Submodul-Verzeichnis ausführt, ohne davor einen Branch auszuchecken, und dann noch einmal `git submodule update` im Superprojekt aufruft, ohne dass man die Änderungen im Submodul im Superprojekt eingecheckt hat, verliert man die ganzen Änderungen, ohne dass Git einen darauf vorher hinweist. Tatsächlich ist es so, dass die Änderungen nicht verloren gehen, aber es gibt keinen Branch, der auf die entsprechenden Commits hinzeigt, und damit kann es schwierig werden, die entsprechenden Commits wiederherzustellen beziehungsweise sichtbar zu machen. @@ -1368,7 +1368,7 @@ In diesem Fall muss man das Verzeichnis entweder an einen anderen Ort verschiebe -Die letzte Falle, in die viele Leute tappen, tritt auf, wenn man bereits vorhandene Verzeichnisse in Submodule umwandeln will. Wenn man also Dateien, die bereits von Git verwaltet werden, entfernen und in ein entsprechendes Submodul verschieben möchte, muss man vorsichtig sein. Ansonsten können schwer zu behebende Probleme mit Git auftreten. Nehmen wir zum Beispiel an, dass Du die Dateien vom Rack Projekt in ein Unterverzeichnis Deines Projekts abgelegt hast und diese jetzt aber in ein Submodul verschieben möchtest. Wenn Du das Unterverzeichnis einfach löschst und dann den Befehl `submodule add` ausführst, zeigt Dir Git folgende Fehlermeldung an: +Die letzte Falle, in die viele Leute tappen, tritt auf, wenn man bereits vorhandene Verzeichnisse in Submodule umwandeln will. Wenn man also Dateien, die bereits von Git verwaltet werden, entfernen und in ein entsprechendes Submodul verschieben möchte, muss man vorsichtig sein. Ansonsten können schwer zu behebende Probleme mit Git auftreten. Nehmen wir zum Beispiel an, dass Du die Dateien vom Rack-Projekt in ein Unterverzeichnis Deines Projekts abgelegt hast und diese jetzt aber in ein Submodul verschieben möchtest. Wenn Du das Unterverzeichnis einfach löschst und dann den Befehl `submodule add` ausführst, zeigt Dir Git folgende Fehlermeldung an: $ rm -Rf rack/ $ git submodule add git@github.com:schacon/rack.git rack @@ -1376,7 +1376,7 @@ Die letzte Falle, in die viele Leute tappen, tritt auf, wenn man bereits vorhand -Man muss dann das Verzeichnis `rack` erst aus der Staging Area entfernen. Danach kann man dann das Submodul erzeugen: +Man muss dann das Verzeichnis `rack` erst aus der Staging-Area entfernen. Danach kann man dann das Submodul erzeugen: $ git rm -r rack $ git submodule add git@github.com:schacon/rack.git rack @@ -1413,11 +1413,11 @@ Wenn man dann wieder in den Zweig mit dem Submodul zurückwechseln will, erhält -Nachdem wir neben den Vor- und Nachteilen beim Arbeiten mit Submodulen kennengelernt haben, möchte ich jetzt noch eine alternative Lösung zeigen, wie man ähnliche Probleme lösen kann. Wenn Git etwas zusammenführt, also mergt, analysiert es die Teile, die es mergen muss. Auf Basis dieser Analyse entscheidet Git sich für eine geeignete Merging-Methode. Wenn man zwei Branches mergt, dann verwendet Git automatisch, die sogenannte Recursive-Strategie. Wenn man mehr als zwei Branches mergt, verwendet Git die sogenannte Octopus-Strategie. Diese Strategien werden automatisch für Dich gewählt, weil die Recursive-Strategie normalerweise sehr gut geeignet ist, um einen Drei-Wege-Merge (engl. three-way merge) durchzuführen — zum Beispiel, wenn es mehr als einen gemeinsamen Vorgänger-Commit gibt — aber der Drei-Wege-Merge ist nur für das Mergen von zwei Branches geeignet. Die Octopus-Merge-Strategie kann mehrere Branches zusammenführen, aber es wird dabei vorsichtiger vorgegangen, um schwierig aufzulösende Konflikte zu vermeiden. Aus diesem Grund wird diese Strategie standardmäßig verwendet, wenn man mehr als zwei Branches zusammenführen möchte. +Nachdem wir neben den Vor- und Nachteilen beim Arbeiten mit Submodulen kennengelernt haben, möchte ich jetzt noch eine alternative Lösung zeigen, wie man ähnliche Probleme lösen kann. Wenn Git etwas zusammenführt, also mergt, analysiert es die Teile, die es mergen muss. Auf Basis dieser Analyse entscheidet Git sich für eine geeignete Merging-Methode. Wenn man zwei Branches mergt, dann verwendet Git automatisch die sogenannte Recursive-Strategie. Wenn man mehr als zwei Branches mergt, verwendet Git die sogenannte Octopus-Strategie. Diese Strategien werden automatisch für Dich gewählt, weil die Recursive-Strategie normalerweise sehr gut geeignet ist, um einen Drei-Wege-Merge (engl. three-way merge) durchzuführen — zum Beispiel, wenn es mehr als einen gemeinsamen Vorgänger-Commit gibt — aber der Drei-Wege-Merge ist nur für das Mergen von zwei Branches geeignet. Die Octopus-Merge-Strategie kann mehrere Branches zusammenführen, aber es wird dabei vorsichtiger vorgegangen, um schwierig aufzulösende Konflikte zu vermeiden. Aus diesem Grund wird diese Strategie standardmäßig verwendet, wenn man mehr als zwei Branches zusammenführen möchte. -Es gibt jedoch noch weitere Strategien, die man verwenden kann. Einer dieser Strategien ist der sogenannte Subtree-Merge. Dies kann verwendet werden, um unser Problem mit Unterprojekten zu lösen. Ich möchte Dir im folgenden aufzeigen, wie man das Rack-Projekt aus dem letzten Kapitel einbindet und dabei den Subree-Merge anstatt der Submodule verwendet. +Es gibt jedoch noch weitere Strategien, die man verwenden kann. Einer dieser Strategien ist der sogenannte Subtree-Merge. Dies kann verwendet werden, um unser Problem mit Unterprojekten zu lösen. Ich möchte Dir im Folgenden aufzeigen, wie man das Rack-Projekt aus dem letzten Kapitel einbindet und dabei den Subtree-Merge anstatt der Submodule verwendet. @@ -1425,7 +1425,7 @@ Das Prinzip, das hinter einem Subtree-Merge steckt, ist, dass man zwei Projekte -Als erstes musst Du dazu die Rack-Applikation zu Deinem Projekt hinzufügen. Dazu fügst Du das Rack-Projekt als neues Remote Repository in Deinem Projekt hinzu und checkst dieses in einem separaten Branch aus: +Als erstes musst Du dazu die Rack-Applikation zu Deinem Projekt hinzufügen. Dazu fügst Du das Rack-Projekt als neues Remote-Repository in Deinem Projekt hinzu und checkst dieses in einem separaten Branch aus: $ git remote add rack_remote git@github.com:schacon/rack.git $ git fetch rack_remote @@ -1446,7 +1446,7 @@ Als erstes musst Du dazu die Rack-Applikation zu Deinem Projekt hinzufügen. Daz -Nach der Ausführung der drei Befehle befindet sich das Rack Projekt in Deinem Branch `rack_branch` und Dein eigenes Projekt liegt weiterhin im Branch `master`. Wenn man jetzt den jeweiligen Zweig auscheckt, sieht man die unterschiedlichen Inhalte im Wurzelverzeichnis: +Nach der Ausführung der drei Befehle befindet sich das Rack-Projekt in Deinem Branch `rack_branch` und Dein eigenes Projekt liegt weiterhin im Branch `master`. Wenn man jetzt den jeweiligen Zweig auscheckt, sieht man die unterschiedlichen Inhalte im Wurzelverzeichnis: $ ls AUTHORS KNOWN-ISSUES Rakefile contrib lib @@ -1458,20 +1458,20 @@ Nach der Ausführung der drei Befehle befindet sich das Rack Projekt in Deinem B -Jetzt möchten wir das Rack Projekt in Deinen Branch `master` als Unterverzeichnis hinzufügen. Dies kann man in Git mit dem Befehl `git read-tree` durchführen. In Kapitel 9 werde ich den Befehl `read-tree` und dessen verwandte Befehle näher erläutern. Hier möchte ich nur erklären, dass der Befehl das Wurzelverzeichnis eines Branches in die aktuelle Staging Area und in das Arbeitsverzeichnis packt. Damit hast Du jetzt zu Deinem Branch `master` zurückgewechselt, den Inhalt des Branches `rack` in das Unterverzeichnis `rack` im Branch `master` Deines Projekts hinterlegt: +Jetzt möchten wir das Rack-Projekt in Deinen Branch `master` als Unterverzeichnis hinzufügen. Dies kann man in Git mit dem Befehl `git read-tree` durchführen. In Kapitel 9 werde ich den Befehl `read-tree` und dessen verwandte Befehle näher erläutern. Hier möchte ich nur erklären, dass der Befehl das Wurzelverzeichnis eines Branches in die aktuelle Staging-Area und in das Arbeitsverzeichnis packt. Damit hast Du jetzt zu Deinem Branch `master` zurückgewechselt, den Inhalt des Branches `rack` in das Unterverzeichnis `rack` im Branch `master` Deines Projekts hinterlegt: $ git read-tree --prefix=rack/ -u rack_branch -Wenn Du jetzt einen Commit ausführst, erscheint es einem so, als ob die ganzen Dateien aus dem Rack Projekt in diesem Unterverzeichnis liegen — als ob man das Projekt aus einem Tarball-Container hineinkopiert hätte. Das Besondere ist jetzt aber, dass man Änderungen zwischen den verschiedenen Branches jetzt einfach zusammenführen kann. Das bedeutet, wenn das Rack Projekt aktualisiert wird, kann man sich diese Änderungen einfach holen, indem man in diesen Branch wechselt und dort einen Pull durchführt: +Wenn Du jetzt einen Commit ausführst, erscheint es einem so, als ob die ganzen Dateien aus dem Rack-Projekt in diesem Unterverzeichnis liegen — als ob man das Projekt aus einem Tarball-Container hineinkopiert hätte. Das Besondere ist jetzt aber, dass man Änderungen zwischen den verschiedenen Branches jetzt einfach zusammenführen kann. Das bedeutet, wenn das Rack-Projekt aktualisiert wird, kann man sich diese Änderungen einfach holen, indem man in diesen Branch wechselt und dort einen Pull durchführt: $ git checkout rack_branch $ git pull -Danach kann man diese Änderungen wieder in den master Branch mergen. Wenn man den Befehl `git merge -s subtree` verwendet, sollte dies einwandfrei funktionieren. Allerdings wird Git bei Ausführen dieses Befehl auch die jeweilige Historie mergen, was Du wahrscheinlich nicht haben möchtest. Um nun die Änderungen zu holen und eine entsprechende Commit Nachricht vorzubereiten, hängt man einfach `--squash`, `--no-commit` und natürlich `-s subtree` als Option an: +Danach kann man diese Änderungen wieder in den master-Branch mergen. Wenn man den Befehl `git merge -s subtree` verwendet, sollte dies einwandfrei funktionieren. Allerdings wird Git bei Ausführen dieses Befehls auch die jeweilige Historie mergen, was Du wahrscheinlich nicht haben möchtest. Um nun die Änderungen zu holen und eine entsprechende Commit-Nachricht vorzubereiten, hängt man einfach `--squash`, `--no-commit` und natürlich `-s subtree` als Option an: $ git checkout master $ git merge --squash -s subtree --no-commit rack_branch @@ -1480,7 +1480,7 @@ Danach kann man diese Änderungen wieder in den master Branch mergen. Wenn man d -Die ganzen Änderungen des Rack Projekts wurden nun zusammengeführt, Du musst jetzt nur noch einen entsprechenden Commit durchführen. Man kann aber auch genau das Gegenteil machen: Man führt Änderungen im Unterverzeichnis `rack` des master Branches aus und mergt diese dann später in den Zweig `rack_branch`. Diesen kann man dann den Entwicklern des Rack Projekts zur Verfügung stellen. +Die ganzen Änderungen des Rack-Projekts wurden nun zusammengeführt, Du musst jetzt nur noch einen entsprechenden Commit durchführen. Man kann aber auch genau das Gegenteil machen: Man führt Änderungen im Unterverzeichnis `rack` des master-Branches aus und mergt diese dann später in den Zweig `rack_branch`. Diesen kann man dann den Entwicklern des Rack-Projekts zur Verfügung stellen. @@ -1499,4 +1499,4 @@ Um Dein Verzeichnis `rack` mit dem letzten Stand des Branches `master` auf dem S -In diesem Kapitel hast Du viele ausgeklügelte Werzeuge kennengelernt, die es Dir ermöglichen Commits und die Staging Area nach Deinen Vorstellungen zu beeinflussen. Wenn ein Problem in Deinem Projekt auftaucht, solltest Du jetzt leicht bestimmen können, welcher Commit den Fehler verursacht hat, sowie wann und von wem der Fehler begangen wurde. Wenn Du andere Projekte in Deinem Projekt verwenden möchtest, hast Du jetzt mehrere Möglichkeiten kennengelernt, wie Du dies handhaben kannst. An dieser Stelle solltest Du jetzt in der Lage sein, die meisten Dinge, die Du bei der täglichen Arbeit benötigst, in der Kommandozeile durchzuführen, ohne dass Dir dabei Schweißperlen auf der Stirn stehen. +In diesem Kapitel hast Du viele ausgeklügelte Werzeuge kennengelernt, die es Dir ermöglichen, Commits und die Staging-Area nach Deinen Vorstellungen zu beeinflussen. Wenn ein Problem in Deinem Projekt auftaucht, solltest Du jetzt leicht bestimmen können, welcher Commit den Fehler verursacht hat, sowie wann und von wem der Fehler begangen wurde. Wenn Du andere Projekte in Deinem Projekt verwenden möchtest, hast Du jetzt mehrere Möglichkeiten kennengelernt, wie Du dies handhaben kannst. An dieser Stelle solltest Du jetzt in der Lage sein, die meisten Dinge, die Du bei der täglichen Arbeit benötigst, in der Kommandozeile durchzuführen, ohne dass Dir dabei Schweißperlen auf der Stirn stehen. From 7cb2c85cb8492c85107af0f2b91c961136e17637 Mon Sep 17 00:00:00 2001 From: Cor Date: Thu, 16 Jan 2014 12:12:07 +0100 Subject: [PATCH 109/690] [nl] Language and wording corrections. Introducing characters from ASCII extended. --- nl/04-git-server/01-chapter4.markdown | 133 +++++++++++++------------- 1 file changed, 66 insertions(+), 67 deletions(-) diff --git a/nl/04-git-server/01-chapter4.markdown b/nl/04-git-server/01-chapter4.markdown index f2bd2ae65..1d4757358 100644 --- a/nl/04-git-server/01-chapter4.markdown +++ b/nl/04-git-server/01-chapter4.markdown @@ -1,22 +1,22 @@ # Git op de Server # -Op dit punt zou je alledaagse taken waarvoor je Git zult gebruiken kunnen doen. Maar, om samen te kunnen werken in Git, zul je een remote repository moeten hebben. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden, omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers bij het repository kunnen, zelfs als jouw computer van het netwerk is – het hebben van een betrouwbaar gezamenlijk repository is vaak handig. Daarom heeft het hebben van een tussenliggend repository waarin je met iemand anders samenwerkt de voorkeur, en daaruit kun je dan pushen en pullen. We zullen dit repository de `Git server` noemen, maar je zult zien dat het over het algemeen maar een klein beetje systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. +Op dit punt zou je alledaagse taken waarvoor je Git zult gebruiken kunnen doen. Maar, om samen te kunnen werken in Git zul je een remote repository moeten hebben. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden, omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers de repository kunnen bereiken, zelfs als jouw computer van het netwerk is – het hebben van een betrouwbare gezamenlijke repository is vaak handig. Daarom heeft het hebben van een tussenliggende repository waarin je met iemand anders samenwerkt de voorkeur, en daaruit pushen en pullen. We zullen deze repository de `Git server` noemen, maar je zult zien dat het over het algemeen maar een klein beetje systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. -Een Git server draaien is eenvoudig. Als eerste kies je met welke protocollen je je server wilt laten communiceren. Het eerste gedeelte van dit hoofdstuk zullen we de beschikbare protocollen bespreken met de voor- en nadelen van elk. De volgende secties zullen veel voorkomende opstellingen bespreken, die van die protocollen gebruik maken hoe je je server ermee kunt opzetten. Als laatste laten we een paar servers van derden zien, als je het niet erg vindt om je code op iemands server te zetten en niet het gedoe wilt hebben van het opzetten en onderhouden van je eigen server. +Een Git server draaien is eenvoudig. Als eerste kies je met welke protocollen je de server wilt laten communiceren. Het eerste gedeelte van dit hoofdstuk zullen we de beschikbare protocollen bespreken met de voor- en nadelen van elk. De volgende paragrafen zullen we veel voorkomende opstellingen bespreken, die van die protocollen gebruik maken en hoe je je server ermee kunt opzetten. Als laatste laten we een paar servers van derden zien, als je het niet erg vindt om je code op de server van een ander te zetten en niet het gedoe wilt hebben van het opzetten en onderhouden van je eigen server. -Als je geen interesse hebt om je eigen server te draaien, dan kun je de rest overslaan en direct naar het laatste gedeelte van het hoofdstuk gaan om wat mogelijkheden van online accounts te zien en dan door te gaan naar het volgende hoofdstuk, waar we alle zaken bespreken die komen kijken bij het werken met een gedistribueerde versie beheer omgeving. +Als je geen interesse hebt om je eigen server te draaien, dan kun je de direct naar de laatste paragraaf van dit hoofdstuk gaan om wat mogelijkheden van online accounts te zien en dan door te gaan naar het volgende hoofdstuk, waar we alle zaken bespreken die komen kijken bij het werken met een gedistribueerde versiebeheer omgeving. -Een remote repository is over het algemeen een _bare repository_ (kale repository) – een Git repository dat geen werkmap heeft. Omdat het repository alleen gebruikt wordt als een samenwerkingspunt, is er geen reden om een snapshot op de schijf te hebben; alleen de Git data. Een kale repository is eenvoudigweg de inhoud van de `.git` map in je project, en niets anders. +Een remote repository is over het algemeen een _bare repository_ (kale repository) – een Git repository dat geen werkmap heeft. Omdat de repository alleen gebruikt wordt als een samenwerkingspunt, is er geen reden om een snapshot op de schijf te hebben; alleen de Git data. Een kale repository is eenvoudigweg de inhoud van de `.git` map in je project, en niets meer. ## De Protocollen ## -Git kan vier veel voorkomende netwerk protocollen gebruiken om data te transporteren: Lokaal, Beveiligde Shell (SSH), Git en HTTP. Hier laten we zien wat het zijn, en in welke omstandigheden je ze wilt gebruiken (of juist niet). +Git kan vier veel voorkomende netwerk protocollen gebruiken om data te transporteren: Lokaal, Beveiligde Shell (SSH), Git en HTTP. Hier laten we zien wat deze zijn, en in welke omstandigheden je ze wilt gebruiken (of juist niet). -Het is belangrijk om te zien dat, met uitzondering van de HTTP protocollen, ze allemaal een werkende Git versie op de server geinstalleerd moeten hebben. +Het is belangrijk om op te merken dat, met uitzondering van de HTTP protocollen, ze allemaal een werkende Git versie op de server geïnstalleerd moeten hebben. ### Lokaal Protocol ### -Het meest basale is het _lokale protocol_, waarbij het remote repository in een andere map op de schijf is. Dit wordt vaak gebruikt als iedereen in je team toegang heeft op een gedeeld bestandssyteem zoals een NFS map, of in het weinig voorkomende geval dat iedereen in dezelfde computer werkt. Het laatste zou niet ideaal zijn, want dan zouden alle repositories zich op dezelfde computer bevinden, zodat de kans op een fataal verlies veel groter wordt. +Het meest basale is het _lokale protocol_, waarbij het remote repository in een andere map op de schijf staat. Deze opzet wordt vaak gebruikt als iedereen in het team toegang heeft op een gedeeld bestandssyteem 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 op dezelfde computer staan, zodat de kans op een fataal verlies veel groter wordt. Als je een gedeeld bestandssyteem 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: @@ -26,29 +26,29 @@ Of je kunt dit doen: $ git clone file:///opt/git/project.git -Git werkt iets anders als je explicite `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gebruikt om data te transporteren over een netwerk, wat over het algemeen een stuk minder efficiente methode is om data te transporteren. De reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de extra referenties of objecten eruit gelaten – over het algemeen na een import van een ander versie beheer systeem of iets dergelijks (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. +Git werkt iets anders als je explicite `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gesproken gebruikt om data te transporteren over een netwerk, wat over het algemeen een minder efficiënte methode is om data te transporteren. De reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de extra referenties of objecten eruit gelaten – over het algemeen na een import van een ander versiebeheer systeem of iets dergelijks (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. -Om een lokaal repository aan een bestaand Git project toe te voegen, kun je zoiets als dit uitvoeren: +Om een lokale repository aan een bestaand Git project toe te voegen, kun je zoiets als het volgende uitvoeren: $ git remote add local_proj /opt/git/project.git -Daarna kun je pushen en pullen van dat remote alsof je over een netwerk werkt. +Daarna kun je pushen en pullen van die remote alsof je over een netwerk werkt. #### De Voordelen #### -De voordelen van bestands-gebaseerde repositories zijn dat ze eenvoudig zijn en ze maken gebruik van bestaande bestandspermissies en netwerk toegang. Als je al een gedeeld bestandssysteem hebt, waar je hele team al toegang tot heeft, dan is een repository opzetten heel gemakkelijk. Je stopt de kale repository ergens waar iedereen gedeelde toegang tot heeft, en stelt de lees- en schrijfrechten in zoals je dat bij iedere andere gedeelde map zou doen. In de volgende sectie "Git op een Server krijgen" bespreken we hoe je een kopie van een kale repository kunt exporteren voor dit doeleind. +De voordelen van bestands-gebaseerde repositories zijn dat ze eenvoudig zijn en ze maken gebruik van bestaande bestandspermissies en netwerk toegang. Als je al een gedeeld bestandssysteem hebt, waar je hele team al toegang tot heeft, dan is een repository opzetten heel gemakkelijk. Je stopt de kale repository ergens waar iedereen gedeelde toegang tot heeft, en stelt de lees- en schrijfrechten in zoals je dat bij iedere andere gedeelde map zou doen. In de volgende paragraaf "Git op een Server Krijgen" bespreken we hoe je een kopie van een kale repository kunt exporteren voor dit doeleinde. -Dit is ook een fijne optie om snel werk van een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project aan het werk zijn, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan dat hij naar een remote server moet pushen, en jij er van moet pullen. +Dit is ook een prettige optie om snel werk van een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project werken, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan dat hij naar een remote server moet pushen, en jij er van moet pullen. #### De Nadelen #### Een van de nadelen van deze methode is dat gedeelde toegang over het algemeen moeilijker op te zetten en te bereiken is vanaf meerdere lokaties dan basaal netwerk toegang. Als je wilt pushen van je laptop als je thuis bent, dan moet je de remote schijf aankoppelen, wat moeilijk en langzaam kan zijn in vergelijking tot netwerk gebaseerde toegang. -Het is ook belangrijk om te melden dat het niet noodzakelijk de snelste optie is, als je een gedeeld koppelpunt of iets dergelijks gebruikt. Een lokale repository is alleen snel als je snelle toegang tot de data hebt. Een repository op NFS is vaak langzamer dan het repository via SSH op dezelfde server, wat Git toelaat om vanaf lokale schijven te werken op ieder systeem. +Het is ook belangrijk om te vermelden dat het niet altijd de snelste optie is, als je een gedeeld koppelpunt (mount) of iets dergelijks gebruikt. Een lokale repository is alleen snel als je snelle toegang tot de data hebt. Een repository op NFS is vaak langzamer dan een repository via SSH op dezelfde server omdat dit Git in staat stelt om op lokale schijven te werken vanaf ieder systeem. ### Het SSH Protocol ### -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 ongeinitieerden, 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. +Waarschijnlijk het meest voorkomende protocol voor Git is SSH. Met als reden dat toegang met SSH tot servers in veel plaatsen al geconfigureerd is – en als dat niet het geval is, dan is het eenvoudig 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 ongeïnitieerden, dan heb je nog steeds SSH nodig voor je eigen schrijftoegang. SSH is ook een geauthenticieerd 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: @@ -58,32 +58,32 @@ Of je geeft geen protocol op – Git gaat uit van SSH als je niet expliciet bent $ git clone user@server:project.git -Je kunt ook de gebruiker niet opgeven, en Git neemt aan dat je de gebruiker bedoelt waarmee je op het moment bent ingelogged. +Je kunt ook de gebruiker niet opgeven, en Git neemt aan dat je de gebruiker bedoelt waarmee je op het moment bent ingelogd. #### De Voordelen #### -Er zijn vele voordelen om SSH te gebruiken. De eerste is dat je het eigenlijk wel moet gebruiken als je geverifieerde schrijftoegang op je repository via een netwerk wilt. Het tweede is dat het relatief eenvoudig in te stellen is – SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig – alle data transporten zijn versleuteld en geverifieerd. En als laatste is SSH efficient, zoals het Git en lokale protocol, waarbij de data zo compact mogelijk wordt gemaakt voordat het getransporteerd wordt. +Er zijn vele voordelen om SSH te gebruiken. De eerste is dat je het eigenlijk wel moet gebruiken als je geauthenticeerde schrijftoegang op je repository via een netwerk wilt. Het tweede is dat het relatief eenvoudig in te stellen is – SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig – alle data transporten zijn versleuteld en geauthenticeerd. En als laatste is SSH efficiënt, net zoals het Git en lokale protocol, de data wordt zo compact mogelijk gemaakt voordat het getransporteerd wordt. #### De Nadelen #### -Het negatieve aspect van SSH is dat je er geen anonieme toegang over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken, zelfs als het alleen lezen is, zodat SSH toegang niet bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, dan kan SSH misschien het enige protocol zijn waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. +Het negatieve aspect van SSH is dat je er geen anonieme toegang over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken, zelfs als het alleen lezen is, zodat SSH toegang niet bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, dan is SSH misschien het enige protocol waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. ### 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 verificatie. 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 is er om gecloned te kunnen worden door iedereen, of het is er 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 verificatie 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 met Git meegeleverd wordt; het luistert op een toegewezen poort (9418), en verleent een vergelijkbare dienst als het SSH protocol, maar dan zonder enige authenticatie. Om een repository beschikbaar te stellen over het Git protocol, moet je het `git-export-daemon-ok` bestand aanmaken – de daemon zal een repository zonder dit bestand erin niet verspreiden – maar buiten dat is er geen beveiliging. Oftewel: de Git repository is er om gecloned te kunnen worden door iedereen, of het is er 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 authenticatie kan, als je de push toegang aan zet, 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 #### -Het Git protocol is het snelste dat beschikbaar is. Als je veel verkeer serveert voor een publiek project, of een zeer groot project dat geen gebruikersverificatie nodig heeft voor leestoegang, dan is het waarschijnlijk dat je een Git daemon wilt instellen om je project te serveren. Het maakt van hetzelfde data-transport mechanisme gebruik als het SSH protocol, maar dan zonder de extra belasting van versleuteling en verificatie. +Het Git protocol is het snelste dat beschikbaar is. Als je veel verkeer verwerkt voor een publiek project, of een zeer groot project dat geen gebruikersauthenticatie nodig heeft voor leestoegang, dan is het waarschijnlijk dat je een Git daemon wilt inrichten om je project te verspreiden. Het maakt van hetzelfde data-transport mechanisme gebruik als het SSH protocol, maar dan zonder de extra belasting van versleuteling en authenticatie. #### De Nadelen #### -Het nadeel van het Git protocol is het gebrek van verificatie. Het is over het algemeen onwenselijk dat het Git protocol de enige toegang tot je project is. Over het algemeen zul je het samen met SSH toegang gebruiken voor de paar ontwikkelaars die push (schrijf-)toegang hebben en de rest laat je `git://` voor alleen leestoegang gebruiken. -Het is waarschijnlijk ook het meest ingewikkelde protocol om in te stellen. Het moet een eigen daemon hebben, die speciaal ontworpen is – we zullen er een instellen in het "Gitosis" gedeelte van dit hoofdstuk – het gebruikt `xinetd` configuratie of iets dergelijks, wat niet altijd eenvoudig is. Het heeft ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat bedrijfsfirewalls altijd toestaan. Achter grote bedrijfsfirewalls, is deze obscure poort meestal geblokkeerd. +Het nadeel van het Git protocol is het gebrek aan authenticatie. Het is over het algemeen onwenselijk dat het Git protocol de enige toegang tot je project is. Meestal zul je het samen met SSH toegang gebruiken voor de paar ontwikkelaars die push (schrijf-)toegang hebben en de rest laat je `git://` voor alleen leestoegang gebruiken. +Het is waarschijnlijk ook het meest ingewikkelde protocol om in te stellen. Het moet een eigen daemon hebben, die speciaal voor die situatie ingericht is – we zullen er een instellen in het "Gitosis" gedeelte van dit hoofdstuk – het gebruikt `xinetd` configuratie of iets dergelijks, wat ook niet altijd eenvoudig is op te zetten. Het heeft ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat in bedrijfsfirewalls is opengezet. Bij firewalls van grote bedrijven, is deze obscure poort meestal geblokkeerd. ### 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 waar je de repository op gezet hebt ook je repository clonen. 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 @@ -95,25 +95,25 @@ Dat is alles. De `post-update` hook, die standaard bij Git zit, voert het noodza $ git clone http://example.com/gitproject.git -In dit geval, gebruiken we het `/var/www/htdocs` pad wat gebruikelijk is voor Apache opstellingen, maar je kunt iedere statische webserver gebruiken – stop de kale repository in haar pad. De Git data wordt geserveerd als standaard statische bestanden (zie hoofdstuk 9 voor details over hoe het precies geserveerd wordt). +In dit specifieke geval gebruiken we het `/var/www/htdocs` pad wat gebruikelijk is voor Apache opstellingen, maar je kunt iedere statische webserver gebruiken – stop de kale repository in haar pad. De Git data wordt geserveerd als standaard statische bestanden (zie hoofdstuk 9 voor details over hoe het precies geserveerd wordt). -Het ook is mogelijk om Git over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en erom vraagt dat je complexe WebDAV vereisten insteld. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek beschrijven. Als je geinteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Een fijn ding aan Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken, zonder specifieke Git eigenschappen; dus je kunt deze functionaliteit gebruiken als je web-hosting provider WebDAV ondersteunt voor schrijf vernieuwingen aan je webpagina. +Het ook is mogelijk om Git over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en het vraagt dat je complexe WebDAV instellingen opzet. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek beschrijven. Als je geïnteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Een fijn ding aan Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken, zonder specifieke Git funtionaliteit; dus je kunt deze functionaliteit gebruiken als je web-hosting provider WebDAV ondersteunt voor het maken van wijzigingen aan je webpagina. #### De Voordelen #### -Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren zorgt voor een eenvoudige manier om de wereld leestoegang te geven aan je Git repository. Het kost slechts een paar minuten om te doen. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te serveren, een normale Apache server kan gemiddeld duizenden bestanden serveren per seconde – is het moeilijk om zelfs een kleine server te overbelasten. +Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren zorgt voor een eenvoudige manier om de wereld leestoegang te geven tot je Git repository. Het kost slechts een paar minuten om te doen. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te verspreiden - een normale Apache server kan gemiddeld duizenden bestanden zenden per seconde - is het moeilijk om zelfs een kleine server te overbelasten. -Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat betekend dat je het transport kunt versleutelen; of je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat moeten gebruiken. Als je over het algemeen zo ver gaat, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan een betere oplossing in jouw specifieke geval om gesigneerde SSL certificaten of andere HTTP-gebaseerde verificatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. +Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat inhoudt dat je het transport kunt versleutelen; je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat laat gebruiken. Normaal gesproken als je je deze moeite wilt getroosten, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan een betere oplossing in jouw specifieke geval zijn om gesigneerde SSL certificaten of andere HTTP-gebaseerde authenticatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. -Een ander fijn ding is dat HTTP zo'n veel voorkomend protocol is dat bedrijfsfirewalls vaak zo ingesteld zijn dat ze verkeerd via deze poort toelaten. +Een andere prettige bijkomstigheid is dat HTTP een dusdanig veel voorkomend protocol is dat bedrijfsfirewalls vaak zo ingesteld zijn dat ze verkeer via deze poort toestaan. #### De Nadelen #### -Het nadeel van je repository serveren via HTTP is dat het relatief inefficient 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 ingewikkeld 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 efficientie tussen het HTTP protocol en andere protocollen, zie Hoofdstuk 9. +Het nadeel van je repository verspreiden 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 veel hogere netwerk belasting en transport volume via HTTP dan met elk van de andere netwerk protocollen. Omdat het niet zo ingewikkeld 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 initiele 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 een initiële Git server op te zetten, moet je een bestaande repository naar 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: $ git clone --bare my_project my_project.git @@ -125,11 +125,11 @@ Dit is ongeveer gelijk aan $ cp -Rf my_project/.git my_project.git -Er zijn een paar kleine verschillen in het configuratie bestand; maar voor jouw doeleinde ligt dit dicht bij hetzelfde. Het neemt de Git repository zelf, zonder een werkmap, en maakt een map aan specifiek alleen voor dat ding. +Er zijn een paar kleine verschillen in het configuratie bestand, maar het komt op hetzelfde neer. Het neemt de Git repository zelf, zonder een werkmap, en maakt een map aan specifiek hiervoor. ### Het Bare Repository op een Server Zetten ### -Nu dat je een kale kopie van je repository hebt, is het enige dat je moet doen het op een server zetten en je protocollen instellen. Stel dat je een server ingesteld hebt, die `git.example.com` heet, waar je SSH toegang op hebt, en waar je al je Git repositories wilt opslaan onder de `/opt/git` map. Je kunt je nieuwe repository instellen door je kale repository ernaartoe te kopieeren: +Nu je een kale kopie van je repository hebt, is het enige dat je moet doen het op een server zetten en je protocollen instellen. Stel dat je een server ingesteld hebt, die `git.example.com` heet, waar je SSH toegang op hebt, en waar je al je Git repositories wilt opslaan onder de `/opt/git` map. Je kunt je nieuwe repository beschikbaar stellen door je kale repository ernaartoe te kopieeren: $ scp -r my_project.git user@git.example.com:/opt/git @@ -137,7 +137,7 @@ Op dit punt kunnen andere gebruikers, die SSH toegang hebben tot dezelfde server $ git clone user@git.example.com:/opt/git/my_project.git -Als een gebruiker in een server SSH-ed en schrijftoegang heeft tot de `/opt/git/my_project.git` map, dan hebben ze automatisch ook push toegang. Git zal automatisch correcte groep schrijfrechten aan een repository toevoegen als je het `git init` commando met de `--shared` optie uitvoert. +Als een gebruiker met SSH op een server inlogt en schrijftoegang heeft tot de `/opt/git/my_project.git` map, dan hebben ze automatisch ook push toegang. Git zal automatisch de correcte groep schrijfrechten aan een repository toekennen als je het `git init` commando met de `--shared` optie uitvoert. $ ssh user@git.example.com $ cd /opt/git/my_project.git @@ -145,9 +145,9 @@ Als een gebruiker in een server SSH-ed en schrijftoegang heeft tot de `/opt/git/ Je ziet hoe eenvoudig het is om een Git repository te nemen, een kale versie aan te maken, en het op een server plaatsen waar jij en je medewerkers SSH toegang tot hebben. Nu ben je klaar om aan hetzelfde project samen te werken. -Het is belangrijk om te zien dat dit letterlijk alles is wat je moet doen om een bruikbare Git server te draaien waarop meerdere mensen toegang hebben – voeg alleen een paar SSH accounts toe op een server, en stop een kale repository ergens waar al die gebruikers lees- en schrijftoegang tot hebben. Je bent er klaar voor – je hebt niets anders nodig. +Het is belangrijk om op te merken dat dit letterlijk alles is wat je moet doen om een bruikbare Git server te draaien waarop meerdere mensen toegang hebben – voeg alleen een paar SSH accounts toe op een server, en stop een kale repository ergens waar al die gebruikers lees- en schrijftoegang toe hebben. Je bent er klaar voor – je hebt niets anders nodig. -In de volgende secties zul je zien hoe je meer ingewikkelde opstellingen kunt maken. Deze bespreking zal het niet hoeven aanmaken van gebruikers accounts voor elke gebruiker, publieke leestoegang tot repositories, grafische web interfaces, de Gitosis applicatie gebruiken en meer omvatten. Maar, hou in gedachten dat om samen te kunnen werken met mensen op een prive project, alles wat je _nodig_ hebt is een SSH server en een kale repository. +In de volgende paragrafen zul je zien hoe je meer ingewikkelde opstellingen kunt maken. Deze bespreking zal het niet hoeven aanmaken van gebruikers accounts voor elke gebruiker, publieke leestoegang tot repositories, grafische web interfaces, de Gitosis applicatie gebruiken en meer omvatten. Maar, hou in gedachten dat om samen te kunnen werken met mensen op een privé project, alles wat je _nodig_ hebt is een SSH server en een kale repository. ### Kleine Opstellingen ### @@ -155,20 +155,20 @@ Als je met een kleine groep bent of net begint met Git in je organisatie en slec #### SSH Toegang #### -Als je reeds een server hebt waar al je ontwikkelaars SSH toegang op hebben, dan is het over het algemeen het gemakkelijkst om je eerste repository daar in te stellen, omdat je dan bijna niets hoeft te doen (zoals beschreven in de vorige sectie). Als je meer complexe toegangscontrole wilt op je repositories, dan kun je ze instellen met de normale bestandssysteem permissies van het operating systeem dat op je server draait. +Als je reeds een server hebt waar al je ontwikkelaars SSH toegang op hebben, dan is het over het algemeen het eenvoudigste om je eerste repository daar in te stellen, omdat je dan bijna niets hoeft te doen (zoals beschreven in de vorige paragraaf). Als je meer complexe toegangscontrole wilt op je repositories, dan kun je ze instellen met de normale bestandssysteem permissies van het operating systeem dat op je server draait. -Als je je repositories op een server wilt zetten, die geen accounts heeft voor iedereen in je team die je schrijftoegang wilt geven, dan moet je SSH toegang voor ze instellen. We gaan er vanuit dat je een server hebt waarmee je dit kunt doen, je reeds een SSH server geinstalleerd hebt, en dat de manier is waarop je toegang hebt tot de server. +Als je je repositories op een server wilt zetten, die geen accounts heeft voor iedereen in je team die je schrijftoegang wilt geven, dan moet je SSH toegang voor ze instellen. We gaan er vanuit dat je een server hebt waarmee je dit kunt doen, dat je reeds een SSH server geïnstalleerd hebt, en dat de manier is waarop je toegang hebt tot de server. -Er zijn een paar manieren waarop je iedereen in je team toegang kunt geven. De eerste is voor iedereen accounts aanmaken, wat rechttoe rechtaan is maar omslachtig kan zijn. Je wilt misschien niet `adduser` uitvoeren en tijdelijke wachtwoorden voor iedere gebruiker instellen. +Er zijn een paar manieren waarop je iedereen in je team toegang kunt geven. De eerste is voor iedereen accounts aanmaken, wat rechttoe rechtaan is maar bewerkelijk kan zijn. Je wilt vermoedelijk niet `adduser` uitvoeren en tijdelijke wachtwoorden instellen voor iedere gebruiker. -Een tweede methode is een 'git' gebruiker aanmaken op de machine, aan iedere gebruiker die schijftoegang moet hebben vragen of ze je een publieke SSH sleutel sturen, en die sleutel toevoegen aan het `~/.ssh/authorized_keys` bestand van je nieuwe 'git' gebruiker. Vanaf dat punt zal iedereen toegang hebben op die machine via de 'git' gebruiker. Dit tast de commit data op geen enkele manier aan – de SSH gebruiker waarmee je inlogged zal de commits die je opgeslagen hebt niet beinvloeden. +Een tweede methode is een 'git' gebruiker aan te maken op de machine, aan iedere gebruiker die schijftoegang moet hebben vragen of ze je een publieke SSH sleutel sturen, en die sleutel toevoegen aan het `~/.ssh/authorized_keys` bestand van je nieuwe 'git' gebruiker. Vanaf dat moment zal iedereen toegang hebben op die machine via de 'git' gebruiker. Dit tast de commit data op geen enkele manier aan – de SSH gebruiker waarmee je inlogt zal de commits die je opgeslagen hebt niet beïnvloeden. -Een andere manier waarop je het kunt doen is je SSH server laten verifieren vanaf een LDAP server of een andere gecentraliseerde verificatie bron, die je misschien al ingesteld hebt. Zolang iedere gebruiker een shell toegang heeft op de machine, zou ieder SSH verificatie mechanisme dat je kunt bedenken moeten werken. +Een andere manier waarop je het kunt doen is je SSH server laten authenticeren middels een LDAP server of een andere gecentraliseerde authenticatie bron, die je misschien al ingesteld hebt. Zolang iedere gebruiker shell toegang kan krijgen op de machine, zou ieder SSH authenticatie mechanisme dat je kunt bedenken moeten werken. ## Je Publieke SSH Sleutel Genereren ## -Dat gezegd hebbende, zijn er vele Git servers die verifieren met een publieke SSH sleutel. Om een publieke sleutel te hebben, zal iedere gebruiker in je systeem er een moeten genereren als ze er nog geen hebben. Dit proces is bij alle operating systemen vergelijkbaar. -Als eerste moet je controleren dat je er niet al een hebt. Standaard staan de SSH sleutels van de gebruikers in hun eigen `~/.ssh` map. Je kunt makkelijk nagaan of je al een sleutel hebt door naar die map te gaan en de inhoud te tonen: +Dat gezegd hebbende, zijn er vele Git servers die authenticeren met een publieke SSH sleutel. Om een publieke sleutel te hebben, zal iedere gebruiker in je systeem er een moeten genereren als ze er nog geen hebben. Dit proces is bij alle operating systemen vergelijkbaar. +Als eerste moet je controleren dat je er niet al een hebt. Standaard staan de SSH sleutels van de gebruikers in hun eigen `~/.ssh` map. Je kunt makkelijk nagaan of je al een sleutel hebt door naar die map te gaan en de inhoud te bekijken: $ cd ~/.ssh $ ls @@ -187,9 +187,9 @@ Je bent op zoek naar een aantal bestanden genaamd iets en iets.pub, waarbij het The key fingerprint is: 43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local -Eerst bevestigt het de lokatie waar je de sleutel wilt opslaan (`.ssh/id_rsa`), en vervolgens vraagt het tweemaal om een wachtzin, die je leeg kunt laten als je geen wachtwoord wilt intypen op het moment dat je de sleutel gebruikt. +Eerst bevestigt het de lokatie waar je de sleutel wilt opslaan (`.ssh/id_rsa`), en vervolgens vraagt het tweemaal om een wachtwoord, die je leeg kunt laten als je geen wachtwoord wilt intypen op het moment dat je de sleutel gebruikt. -Iedere gebruiker die dit doet, moet zijn sleutel sturen naar jou of degene die de Git server beheert (aangenomen dat je een SSH server gebruikt die publieke sleutels vereist). Het enige dat ze hoeven doen is de inhoud van het `.pub` bestand kopieeren en e-mailen. De publieke sleutel ziet er ongeveer zo uit: +Iedere gebruiker die dit doet, moet zijn sleutel sturen naar jou of degene die de Git server beheert (aangenomen dat je een SSH server gebruikt die publieke sleutels vereist). Het enige dat ze hoeven doen is de inhoud van het `.pub` bestand kopiëren en e-mailen. De publieke sleutel ziet er ongeveer zo uit: $ cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU @@ -203,7 +203,7 @@ Voor een uitgebreide tutorial over het aanmaken van een SSH sleutel op meerdere ## De Server Instellen ## -Laten we het instellen van SSH toegang aan de server kant eens doorlopen. In dit voorbeeld zul je de `authorized_keys` methode gebruiken om je gebruikers te verifieren. We gaan er ook vanuit dat je een standaard Linux distributie gebruikt zoals Ubuntu. Als eerste creeer je een 'git' gebruiker een een `.ssh` map voor die gebruiker. +Laten we het instellen van SSH toegang aan de server kant eens doorlopen. In dit voorbeeld zul je de `authorized_keys` methode gebruiken om je gebruikers te authenticeren. We gaan er ook vanuit dat je een standaard Linux distributie gebruikt zoals Ubuntu. Als eerste maak je een 'git' gebruiker aan en een `.ssh` map voor die gebruiker. $ sudo adduser git $ su git @@ -220,20 +220,20 @@ Daarna moet je een aantal publieke SSH sleutels van ontwikkelaars aan het `autho O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq dAv8JggJICUvax2T9va5 gsg-keypair -Je voegt ze slechts toe aan je `authorized_keys` bestand: +Je voegt ze eenvoudigweg toe aan je `authorized_keys` bestand: $ 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 -Nu kun je een leeg repository voor ze instellen door `git init` uit te voeren met de `--bare` optie, wat het repository initialiseert zonder een werkmap: +Nu kun je een lege repository voor ze instellen door `git init` uit te voeren met de `--bare` optie, wat de repository initialiseert zonder een werkmap: $ cd /opt/git $ mkdir project.git $ cd project.git $ git --bare init -Daarna kunnen John, Josie of Jessica de eerste versie van hun project in de repository pushen door het als een remote toe te voegen en naar een branch te pushen. Let op dat iemand met een shell op de machine zal moeten inloggen en een kale repository moet creeeren, iedere keer als je een project wilt toevoegen. Laten we `gitserver` als hostnaam gebruiken voor de server waar je je 'git' gebruiker en repository hebt ingesteld. Als je het intern gaat draaien, en je de DNS instelt zodat `gitserver` naar die server wijst, dan kun je de commando's vrijwel ongewijzigd gebruiken: +Daarna kunnen John, Josie of Jessica de eerste versie van hun project in de repository pushen door het als een remote toe te voegen en naar een branch te pushen. Let op dat iemand met een shell op de machine zal moeten inloggen en een kale repository moet creëren, iedere keer als je een project wilt toevoegen. Laten we `gitserver` als hostnaam gebruiken voor de server waar je de 'git' gebruiker en repository hebt ingesteld. Als je het binnenshuis draait, en je de DNS instelt zodat `gitserver` naar die server wijst, dan kun je de commando's vrijwel ongewijzigd gebruiken: # op Johns computer $ cd myproject @@ -243,14 +243,14 @@ 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: +Vanaf dat moment kunnen de anderen het clonen en wijzigingen even gemakkelijk terug pushen: $ git clone git@gitserver:/opt/git/project.git $ vim README $ git commit -am 'fix for the README file' $ git push origin master -Met deze methode kun je snel een lees/schrijf Git server draaiend krijgen voor een handvol ontwikkelaars. +Met deze methode kun je snel een lees/schrijf Git server draaiend krijgen voor een handjevol ontwikkelaars. Als een extra voorzorgsmaatregel kun je de 'git' gebruiker makkelijk beperken tot het doen van alleen Git activiteiten, met een gelimiteerde shell applicatie genaamd `git-shell` die bij Git geleverd wordt. Als je dit als login shell voor je 'git' gebruiker instelt, dan kan de 'git' gebruiker geen normale shell toegang hebben op je server. Specificeer `git-shell` in plaats van bash of csh voor je gebruikers login shell om dit te gebruiken. Om dit te doen zul je waarschijnlijk het `/etc/passwd` bestand aan moeten passen: @@ -261,7 +261,7 @@ Aan het einde zou je een regel moeten vinden die er ongeveer zo uit ziet: git:x:1000:1000::/home/git:/bin/sh -Verander `/bin/sh` in `/usr/bin/git-shell` (of voer `which git-shell` uit om te zien waar het geinstalleerd is). De regel moet er ongeveer zo uit zien: +Verander `/bin/sh` in `/usr/bin/git-shell` (of voer `which git-shell` uit om te zien waar het geïnstalleerd is). De regel moet er ongeveer zo uit zien: git:x:1000:1000::/home/git:/usr/bin/git-shell @@ -273,9 +273,9 @@ Nu kan de 'git' gebruiker de SSH connectie alleen gebruiken om Git repositories ## Publieke Toegang ## -Wat als je anonieme leestoegang op je project wil? Misschien wil je geen intern prive project serveren, maar een open source project. Of misschien heb je een serie geautomatiseerde bouwservers of continue integratie servers die vaak wijzigen, en wil je niet doorlopend SSH sleutels hoeven genereren – je wil gewoon eenvoudige leestoegang toevoegen. +Wat als je anonieme leestoegang op je project wil? Misschien wil je geen intern privé project beheren, maar een open source project. Of misschien heb je een aantal geautomatiseerde bouwservers of continue integratie servers die vaak wijzigen, en wil je niet doorlopend SSH sleutels hoeven genereren – je wil gewoon eenvoudige leestoegang toevoegen. -Waarschijnlijk is de eenvoudigste manier voor kleinschalige opstellingen om een statische webserver in te stellen, waarbij de document root naar de plaats van je Git repositories wijst, en dan die `post-update` haak aanzetten waar we het in de eerste sectie van dit hoofdstuk over gehad hebben. Laten we eens uitgaan van het vorige voorbeeld. Stel dat je je repositories in de `/opt/git` map hebt staan, en er draait een Apache server op je machine. Nogmaals, je kunt hiervoor iedere web server gebruiken: maar als voorbeeld zullen we wat basis Apache configuraties laten zien, die je een idee kunnen geven van wat je nodig hebt. +Waarschijnlijk is de eenvoudigste manier voor kleinschalige opstellingen om een statische webserver in te stellen, waarbij de document root naar de plaats van je Git repositories wijst, en dan de `post-update` haak aanzetten waar we het in de eerste paragraaf van dit hoofdstuk over gehad hebben. Laten we eens uitgaan van het voorgaande voorbeeld. Stel dat je je repositories in de `/opt/git` map hebt staan, en er draait een Apache server op je machine. Nogmaals, je kunt hiervoor iedere web server gebruiken: maar als voorbeeld zullen we wat basis Apache configuraties laten zien, die je een idee kunnen geven van wat je nodig hebt. Eerst moet je de haak aanzetten: @@ -293,7 +293,7 @@ Wat doet deze `post-update` haak? Het ziet er ongeveer zo uit: Dit betekent dat wanneer je naar de server via SSH pushed, 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: +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 wildcard DNS ingesteld hebt om `*.gitserver` door te sturen naar waar je dit alles draait: ServerName git.gitserver @@ -304,7 +304,7 @@ Vervolgens moet je een VirtualHost toevoeging in je Apache configuratie aanmaken -Je zult ook de Unix gebruikers groep van de `/opt/git` mappen moeten instellen op `www-data` zodat je web server leestoegang heeft op de repositories, omdat de Apache instantie die het CGI script uitvoert (standaard) als die gebruiker draait: +Je zult ook de Unix gebruikers groep van de `/opt/git` mappen moeten instellen op `www-data` zodat je web server leestoegang hebt op de repositories, omdat de Apache instantie die het CGI script uitvoert (standaard) als die gebruiker draait: $ chgrp -R www-data /opt/git @@ -312,11 +312,11 @@ Als je Apache herstart, dan zou je je repositories onder die map moeten kunnen c $ git clone http://git.gitserver/project.git -Op deze manier kun je HTTP-gebaseerde toegang voor ieder van je projecten voor een groot aantal gebruikers in slechts een paar minuten instellen. Een andere eenvoudige optie om publieke ongeverifieerde toegang in te stellen is een Git daemon starten, alhoewel dat vereist dat je het proces als daemon uitvoert – we beschrijven deze optie in de volgende sectie als je een voorkeur hebt voor die route. +Op deze manier kun je HTTP-gebaseerde toegang voor elk van je projecten voor een groot aantal gebruikers in slechts een paar minuten instellen. Een andere eenvoudige optie om publieke ongeauthenticeerde toegang in te stellen is een Git daemon te starten, alhoewel dat vereist dat je het proces als daemon uitvoert – we beschrijven deze optie in de volgende paragraaf als je een voorkeur hebt voor deze variant. ## GitWeb ## -Nu dat je basis lees/schrijf en alleen-lezen toegang tot je project hebt, wil je misschien een eenvoudige web-gebaseerde visualiseerder instellen. Git levert een CGI script genaamd GitWeb mee, dat veelal voor hiervoor gebruikt wordt. Je kunt GitWeb in gebruik zien bij sites zoals `http://git.kernel.org` (zie Figuur 4-1). +Nu je basis lees/schrijf en alleen-lezen toegang tot je project hebt, wil je misschien een eenvoudige web-gebaseerde visualisatie instellen. Git levert een CGI script genaamd GitWeb mee, dat veelal voor hiervoor gebruikt wordt. Je kunt GitWeb in gebruik zien bij sites zoals `http://git.kernel.org` (zie Figuur 4-1). Insert 18333fig0401.png Figuur 4-1. De GitWeb web-gebaseerde gebruikers interface. @@ -327,11 +327,11 @@ Als je wil zien hoe GitWeb er op jouw project uitziet, dan heeft Git een command [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] -Dat start een HTTPD server op poort 1234 op en start automatisch een web browser op die met die pagina opent. Het is dus makkelijk voor jou. Als je klaar bent en de server wilt afsluiten, dan kun je hetzelfde commando uitvoeren met de `--stop` optie: +Dat start een HTTPD server op poort 1234 op en start automatisch een web browser op die met die pagina opent. Het is dus makkelijk voor je. Als je klaar bent en de server wilt afsluiten, dan kun je hetzelfde commando uitvoeren met de `--stop` optie: $ git instaweb --httpd=webrick --stop -Als je de web interface doorlopend op een server wilt draaien voor je team of voor een open source project dat je serveert, dan moet je het CGI script instellen zodat het door je normale web server geserveerd wordt. Sommige Linux distributies hebben een `gitweb` pakket dat je misschien kunt installeren via `apt` of `yum`, dus misschien wil je dat eerst proberen. We zullen zeer binnenkort door een handmatige GitWeb installatie heenlopen. Eerst moet je de Git broncode pakken, waar GitWeb bij zit, en het persoonlijke CGI script genereren: +Als je de web interface doorlopend op een server wilt draaien voor je team of voor een open source project dat je verspreid, dan moet je het CGI script instellen zodat het door je normale web server geserveerd wordt. Sommige Linux distributies hebben een `gitweb` pakket dat je misschien kunt installeren via `apt` of `yum`, dus misschien kan je dat eerst proberen. We zullen snel door een handmatige GitWeb installatie heenlopen. Eerst moet je de Git broncode pakken waar GitWeb bij zit, en het aangepaste CGI script genereren: $ git clone git://git.kernel.org/pub/scm/git/git.git $ cd git/ @@ -339,7 +339,7 @@ Als je de web interface doorlopend op een server wilt draaien voor je team of vo prefix=/usr gitweb/gitweb.cgi $ sudo cp -Rf gitweb /var/www/ -Let op dat je het commando moet vertellen waar het je Git repositories kan vinden met de `GITWEB_PROJECTROOT` variabele. Nu moet je zorgen dat de Apache server CGI gebruikt voor dat script, waarvoor je een VirtualHost kunt toevoegen: +Merk op dat je het commando moet vertellen waar het je Git repositories kan vinden met de `GITWEB_PROJECTROOT` variabele. Nu moet je zorgen dat de Apache server CGI gebruikt voor dat script, waarvoor je een VirtualHost kunt toevoegen: ServerName gitserver @@ -354,17 +354,17 @@ 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 web server die in staat is CGI te verwerken; 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. ## Gitosis ## -De publieke sleutels van alle gebruikers in een `authorized_keys` bestand bewaren voor toegang werkt slechts korte tijd 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. +De publieke sleutels van alle gebruikers in een `authorized_keys` bestand bewaren voor toegang werkt slechts korte tijd goed. Als je honderden gebruikers hebt, dan is het bewerkelijk om dat proces te volgen. 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 verzameling scripts die je helpen het `authorized_keys` bestand te beheren alsmede eenvoudig 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 beheert de informatie in dat project; en als je het pushed, dan herconfigureert Gitosis de server op basis van dat project, wat best wel 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. +Gitosis installeren is niet de makkelijkste taak ooit, maar het is ook niet te moeilijk. Het is het makkelijkste om er een Linux server voor te gebruiken – deze voorbeelden gebruiken een standaard Ubuntu 8.10 server. -Gitosis vereist wat Python applicaties, dus moet je eerst het Python setuptools pakket installeren, wat Ubuntu meelevert als python-setuptools: +Gitosis vereist enkele Python applicaties, dus moet je eerst het Python setuptools pakket installeren, wat Ubuntu beschikbaar stelt als python-setuptools: $ apt-get install python-setuptools @@ -378,7 +378,7 @@ Daarmee worden een aantal bestanden geinstalleerd, die Gitosis zal gebruiken. Da $ ln -s /opt/git /home/git/repositories -Gitosis zal je sleutels voor je beheren, dus je moet het huidige bestand verwijderen, de sleutels later opnieuw toevoegen en Gitosis het `authorized_keys` bestand automatisch laten beheren. Voor nu verplaatsen we het `authorized_keys` bestand: +Gitosis zal je sleutels voor je beheren, dus je moet het huidige bestand verwijderen, om de sleutels later opnieuw toe te voegen en Gitosis het `authorized_keys` bestand automatisch laten beheren. Voor nu verplaatsen we het `authorized_keys` bestand: $ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak @@ -396,8 +396,7 @@ Nu wordt het tijd om Gitosis te initialiseren. Je doet dit door het `gitosis-ini Initialized empty Git repository in /opt/git/gitosis-admin.git/ Reinitialized existing Git repository in /opt/git/gitosis-admin.git/ -Dit staat de gebruiker met die sleutel toe de hoofd Git repository, die de Gitosis installatie beheert, aan te passen. Daarna zul je met de hand het execute -bit op het `post-update` script moeten instellen voor je nieuwe beheer repository. +Dit staat de gebruiker met die sleutel toe de hoofd Git repository, die de Gitosis installatie beheert, aan te passen. Daarna zul je met de hand het execute bit op het `post-update` script moeten instellen voor je nieuwe beheer repository. $ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update From a5af517938a7cdda0032274960ec3af1f2d46552 Mon Sep 17 00:00:00 2001 From: Cor Date: Fri, 17 Jan 2014 15:03:53 +0100 Subject: [PATCH 110/690] [nl] added diacritical characters. Added (start of) gitolite translation. --- nl/04-git-server/01-chapter4.markdown | 352 +++++++++++++++++++------- 1 file changed, 264 insertions(+), 88 deletions(-) diff --git a/nl/04-git-server/01-chapter4.markdown b/nl/04-git-server/01-chapter4.markdown index 1d4757358..c6bdd3c65 100644 --- a/nl/04-git-server/01-chapter4.markdown +++ b/nl/04-git-server/01-chapter4.markdown @@ -1,24 +1,24 @@ # Git op de Server # -Op dit punt zou je alledaagse taken waarvoor je Git zult gebruiken kunnen doen. Maar, om samen te kunnen werken in Git zul je een remote repository moeten hebben. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden, omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers de repository kunnen bereiken, zelfs als jouw computer van het netwerk is – het hebben van een betrouwbare gezamenlijke repository is vaak handig. Daarom heeft het hebben van een tussenliggende repository waarin je met iemand anders samenwerkt de voorkeur, en daaruit pushen en pullen. We zullen deze repository de `Git server` noemen, maar je zult zien dat het over het algemeen maar een klein beetje systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. +Op dit punt zou je alledaagse taken waarvoor je Git zult gebruiken kunnen doen. Maar, om samen te kunnen werken in Git zul je een remote repository moeten hebben. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden, omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers de repository kunnen bereiken, zelfs als jouw computer van het netwerk is – het hebben van een betrouwbare gezamenlijke repository is vaak handig. De voorkeursmethode om met iemand samen te werken is om een tussenliggende repository in te richten waar beide partijen toegang to hebben en om daar naartoe te pushen en vandaan te pullen. We zullen deze repository de `Git server` noemen, maar je zult zien dat het over het algemeen maar een klein beetje systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. -Een Git server draaien is eenvoudig. Als eerste kies je met welke protocollen je de server wilt laten communiceren. Het eerste gedeelte van dit hoofdstuk zullen we de beschikbare protocollen bespreken met de voor- en nadelen van elk. De volgende paragrafen zullen we veel voorkomende opstellingen bespreken, die van die protocollen gebruik maken en hoe je je server ermee kunt opzetten. Als laatste laten we een paar servers van derden zien, als je het niet erg vindt om je code op de server van een ander te zetten en niet het gedoe wilt hebben van het opzetten en onderhouden van je eigen server. +Een Git server draaien is eenvoudig. Als eerste kies je met welke protocollen je de server wilt laten communiceren. Het eerste gedeelte van dit hoofdstuk zullen we de beschikbare protocollen bespreken met de voor- en nadelen van elk. De daarop volgende paragrafen zullen we een aantal veel voorkomende opstellingen bespreken die van die protocollen gebruik maken en hoe je je server ermee kunt opzetten. Als laatste laten we een paar servers van derden zien, als je het niet erg vindt om je code op de server van een ander te zetten en niet het gedoe wilt hebben van het opzetten en onderhouden van je eigen server. -Als je geen interesse hebt om je eigen server te draaien, dan kun je de direct naar de laatste paragraaf van dit hoofdstuk gaan om wat mogelijkheden van online accounts te zien en dan door te gaan naar het volgende hoofdstuk, waar we alle zaken bespreken die komen kijken bij het werken met een gedistribueerde versiebeheer omgeving. +Als je niet van plan bent om je eigen server te draaien, dan kun je de direct naar de laatste paragraaf van dit hoofdstuk gaan om wat mogelijkheden van online accounts te zien en dan door gaan naar het volgende hoofdstuk, waar we diverse zaken bespreken die komen kijken bij het werken met een gedistribueerde versiebeheer omgeving. -Een remote repository is over het algemeen een _bare repository_ (kale repository) – een Git repository dat geen werkmap heeft. Omdat de repository alleen gebruikt wordt als een samenwerkingspunt, is er geen reden om een snapshot op de schijf te hebben; alleen de Git data. Een kale repository is eenvoudigweg de inhoud van de `.git` map in je project, en niets meer. +Een remote repository is over het algemeen een _bare repository_ (kale repository) – een Git repository dat geen werkmap heeft. Omdat de repository alleen gebruikt wordt als een samenwerkingspunt, is er geen reden om een snapshot op de schijf te hebben; het is alleen de Git data. Een kale repository is eenvoudigweg de inhoud van de `.git` map in je project, en niets meer. ## De Protocollen ## -Git kan vier veel voorkomende netwerk protocollen gebruiken om data te transporteren: Lokaal, Beveiligde Shell (SSH), Git en HTTP. Hier laten we zien wat deze zijn, en in welke omstandigheden je ze wilt gebruiken (of juist niet). +Git kan vier veel voorkomende netwerk protocollen gebruiken om data te transporteren: Lokaal, Beveiligde Shell (Secure Shell, SSH), Git en HTTP. Hier bespreken we wat deze zijn, en in welke omstandigheden je ze zou willen gebruiken (of juist niet). Het is belangrijk om op te merken dat, met uitzondering van de HTTP protocollen, ze allemaal een werkende Git versie op de server geïnstalleerd moeten hebben. ### Lokaal Protocol ### -Het meest basale is het _lokale protocol_, waarbij het remote repository in een andere map op de schijf staat. Deze opzet wordt vaak gebruikt als iedereen in het team toegang heeft op een gedeeld bestandssyteem 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 op dezelfde computer staan, zodat de kans op een fataal verlies veel groter wordt. +Het simpelste is het _Lokale protocol_, waarbij de remote repository in een andere directory op de schijf staat. Deze opzet wordt vaak gebruikt als iedereen in het team toegang heeft op een gedeeld bestandssyteem zoals een NFS mount, of in het weinig voorkomende geval dat iedereen op dezelfde computer werkt. Het laatste zou niet ideaal zijn, want dan zouden alle repositories op dezelfde computer staan, zodat een fataal verlies van gegevens veel groter wordt. -Als je een gedeeld bestandssyteem 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 bestandssyteem hebt, dan kun je clonen, pushen en pullen van een op een lokaal bestand aanwezige 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 het volgende uitvoeren: $ git clone /opt/git/project.git @@ -26,29 +26,29 @@ Of je kunt dit doen: $ git clone file:///opt/git/project.git -Git werkt iets anders als je explicite `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gesproken gebruikt om data te transporteren over een netwerk, wat over het algemeen een minder efficiënte methode is om data te transporteren. De reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de extra referenties of objecten eruit gelaten – over het algemeen na een import van een ander versiebeheer systeem of iets dergelijks (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. +Git werkt iets anders als je explicite `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gesproken gebruikt om data te transporteren over een netwerk, wat over het algemeen een minder efficiënte methode is om gegevens over te dragen. De belangrijkste reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de vreemde refenties of objecten eruit gelaten – over het algemeen na een import uit een ander versiebeheer systeem of iets dergelijks (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. -Om een lokale repository aan een bestaand Git project toe te voegen, kun je zoiets als het volgende uitvoeren: +Om een lokale repository aan een bestaand Git project toe te voegen, kun je iets als het volgende uitvoeren: $ git remote add local_proj /opt/git/project.git -Daarna kun je pushen en pullen van die remote alsof je over een netwerk werkt. +Daarna kun je op gelijke wijze pushen naar, en pullen van die remote als je over een netwerk zou doen. #### De Voordelen #### -De voordelen van bestands-gebaseerde repositories zijn dat ze eenvoudig zijn en ze maken gebruik van bestaande bestandspermissies en netwerk toegang. Als je al een gedeeld bestandssysteem hebt, waar je hele team al toegang tot heeft, dan is een repository opzetten heel gemakkelijk. Je stopt de kale repository ergens waar iedereen gedeelde toegang tot heeft, en stelt de lees- en schrijfrechten in zoals je dat bij iedere andere gedeelde map zou doen. In de volgende paragraaf "Git op een Server Krijgen" bespreken we hoe je een kopie van een kale repository kunt exporteren voor dit doeleinde. +De voordelen van bestands-gebaseerde repositories zijn dat ze eenvoudig zijn en ze maken gebruik van bestaande bestandspermissies en netwerk toegang. Als je al een gedeeld bestandssysteem hebt, waar het hele team al toegang toe heeft, dan is een repository opzetten heel gemakkelijk. Je stopt de kale repository ergens waar iedereen gedeelde toegang tot heeft, en stelt de lees- en schrijfrechten in zoals je dat bij iedere andere gedeelde directory zou doen. In de volgende paragraaf "Git op een Server Krijgen" bespreken we hoe je een kopie van een kale repository kunt exporteren voor dit doeleinde. -Dit is ook een prettige optie om snel werk van een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project werken, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan dat hij naar een remote server moet pushen, en jij er van moet pullen. +Dit is ook een prettige optie om snel werk uit een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project werken, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan dat hij naar een remote server moet pushen, en jij er van moet pullen. #### De Nadelen #### -Een van de nadelen van deze methode is dat gedeelde toegang over het algemeen moeilijker op te zetten en te bereiken is vanaf meerdere lokaties dan basaal netwerk toegang. Als je wilt pushen van je laptop als je thuis bent, dan moet je de remote schijf aankoppelen, wat moeilijk en langzaam kan zijn in vergelijking tot netwerk gebaseerde toegang. +Een van de nadelen van deze methode is dat gedeelde toegang over het algemeen moeilijker op te zetten en te bereiken is vanaf meerdere lokaties dan simpele netwerk toegang. Als je wilt pushen van je laptop als je thuis bent, dan moet je de remote schijf aankoppelen, wat moeilijk en langzaam kan zijn als je het vergelijkt met netwerk gebaseerde toegang. -Het is ook belangrijk om te vermelden dat het niet altijd de snelste optie is, als je een gedeeld koppelpunt (mount) of iets dergelijks gebruikt. Een lokale repository is alleen snel als je snelle toegang tot de data hebt. Een repository op NFS is vaak langzamer dan een repository via SSH op dezelfde server omdat dit Git in staat stelt om op lokale schijven te werken vanaf ieder systeem. +Het is ook belangrijk om te vermelden dat het niet altijd de snelste optie is, als je een gedeeld koppelpunt (mount) of iets dergelijks gebruikt. Een lokale repository is alleen snel als je snelle toegang tot de data hebt. Een repository op NFS is vaak langzamer dan een repository via SSH op dezelfde server omdat dit Git in staat stelt om op lokale schijven te werken op elk van de betrokken systemen. ### Het SSH Protocol ### -Waarschijnlijk het meest voorkomende protocol voor Git is SSH. Met als reden dat toegang met SSH tot servers in veel plaatsen al geconfigureerd is – en als dat niet het geval is, dan is het eenvoudig 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 ongeïnitieerden, dan heb je nog steeds SSH nodig voor je eigen schrijftoegang. SSH is ook een geauthenticieerd protocol; en omdat het overal voorkomt, is het over het algemeen eenvoudig om in te stellen en te gebruiken. +Waarschijnlijk het meest voorkomende protocol voor Git is SSH. De reden hiervoor is dat toegang met SSH tot servers in veel plaatsen al geconfigureerd is – en als dat niet het geval is, dan is het eenvoudig 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 ongeïnitieerde massas, dan heb je nog steeds SSH nodig voor je eigen schrijfcommandos. SSH is ook een geauthenticieerd protocol; en omdat het alom aanwezig is, 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: @@ -58,19 +58,19 @@ Of je geeft geen protocol op – Git gaat uit van SSH als je niet expliciet bent $ git clone user@server:project.git -Je kunt ook de gebruiker niet opgeven, en Git neemt aan dat je de gebruiker bedoelt waarmee je op het moment bent ingelogd. +Je kunt ook de gebruiker weglaten, en Git gebruikt gegevens van de gebruiker waarmee je op dat moment bent ingelogd. #### De Voordelen #### -Er zijn vele voordelen om SSH te gebruiken. De eerste is dat je het eigenlijk wel moet gebruiken als je geauthenticeerde schrijftoegang op je repository via een netwerk wilt. Het tweede is dat het relatief eenvoudig in te stellen is – SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig – alle data transporten zijn versleuteld en geauthenticeerd. En als laatste is SSH efficiënt, net zoals het Git en lokale protocol, de data wordt zo compact mogelijk gemaakt voordat het getransporteerd wordt. +Er zijn vele voordelen om SSH te gebruiken. Ten eerste moet je het eigenlijk wel gebruiken als je geauthenticeerde schrijftoegang op je repository via een netwerk wilt. Ten tweede is het relatief eenvoudig in te stellen – SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig – alle data transporten zijn versleuteld en geauthenticeerd. En als laatste is SSH efficiënt, net zoals het Git en lokale protocol, de gegevens worden zo compact mogelijk gemaakt voordat het getransporteerd wordt. #### De Nadelen #### -Het negatieve aspect van SSH is dat je er geen anonieme toegang over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken, zelfs als het alleen lezen is, zodat SSH toegang niet bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, dan is SSH misschien het enige protocol waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. +Het negatieve aspect van SSH is dat je er geen anonieme toegang naar je repository over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken, zelfs als het alleen lezen is, zodat SSH toegang niet bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, dan is SSH misschien het enige protocol waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. ### Het Git Protocol ### -Het volgende is het Git protocol. Dit is een aparte daemon, die met Git meegeleverd wordt; het luistert op een toegewezen poort (9418), en verleent een vergelijkbare dienst als het SSH protocol, maar dan zonder enige authenticatie. Om een repository beschikbaar te stellen over het Git protocol, moet je het `git-export-daemon-ok` bestand aanmaken – de daemon zal een repository zonder dit bestand erin niet verspreiden – maar buiten dat is er geen beveiliging. Oftewel: de Git repository is er om gecloned te kunnen worden door iedereen, of het is er 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 authenticatie kan, als je de push toegang aan zet, 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 specifieke daemon, die met Git meegeleverd wordt; het luistert op een toegewezen poort (9418), en verleent een vergelijkbare dienst als het SSH protocol, maar dan zonder enige vorm van authenticatie. Om een repository beschikbaar te stellen over het Git protocol, moet je een `git-export-daemon-ok` bestand aanmaken – de daemon zal een repository zonder dit bestand erin niet verspreiden – maar daarbuiten is er geen beveiliging. De Git repository beschikbaar om gecloned te kunnen worden door iedereen, of het is het niet. Dit betekent dat er over het algemeen geen pushing is via dit protocol. Je kunt push toegang aanzetten, maar gegeven het gebrek aan authenticatie kan als je de push toegang aan zet iedereen die de URL van jouw project op het internet vindt, pushen naar jouw project. We volstaan met te zeggen dat dit zelden de bedoeling kan zijn. #### De Voordelen #### @@ -79,7 +79,7 @@ Het Git protocol is het snelste dat beschikbaar is. Als je veel verkeer verwerkt #### De Nadelen #### Het nadeel van het Git protocol is het gebrek aan authenticatie. Het is over het algemeen onwenselijk dat het Git protocol de enige toegang tot je project is. Meestal zul je het samen met SSH toegang gebruiken voor de paar ontwikkelaars die push (schrijf-)toegang hebben en de rest laat je `git://` voor alleen leestoegang gebruiken. -Het is waarschijnlijk ook het meest ingewikkelde protocol om in te stellen. Het moet een eigen daemon hebben, die speciaal voor die situatie ingericht is – we zullen er een instellen in het "Gitosis" gedeelte van dit hoofdstuk – het gebruikt `xinetd` configuratie of iets dergelijks, wat ook niet altijd eenvoudig is op te zetten. Het heeft ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat in bedrijfsfirewalls is opengezet. Bij firewalls van grote bedrijven, is deze obscure poort meestal geblokkeerd. +Het is waarschijnlijk ook het meest ingewikkelde protocol om in te richten. Het moet een eigen daemon hebben, die speciaal voor die situatie ingericht is – we zullen er een instellen in het "Gitosis" gedeelte van dit hoofdstuk – het gebruikt `xinetd` configuratie of iets vergelijkbaars, wat ook niet altijd eenvoudig is op te zetten. Daarbij is ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat in bedrijfsfirewalls is opengezet. Bij firewalls van grote bedrijven, is deze ongebruikelijke poort meestal dichtgezet. ### Het HTTP/S Protocol ### @@ -91,30 +91,30 @@ 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 geleverd wordt, voert het noodzakelijke commando uit (`git update-server-info`) om HTTP fetching en cloning goed werkend te krijgen en houden. Dit commando wordt uitgevoerd als je via SSH naar deze repository pushed; en andere mensen kunnen clonen met behulp van zoiets als $ git clone http://example.com/gitproject.git -In dit specifieke geval gebruiken we het `/var/www/htdocs` pad wat gebruikelijk is voor Apache opstellingen, maar je kunt iedere statische webserver gebruiken – stop de kale repository in haar pad. De Git data wordt geserveerd als standaard statische bestanden (zie hoofdstuk 9 voor details over hoe het precies geserveerd wordt). +In dit specifieke voorbeeld gebruiken we het `/var/www/htdocs` pad wat gebruikelijk is voor Apache opstellingen, maar je kunt iedere statische webserver gebruiken – stop de kale repository in het betreffende pad. De Git data wordt geserveerd als standaard statische bestanden (zie hoofdstuk 9 voor details over hoe het precies geserveerd wordt). -Het ook is mogelijk om Git over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en het vraagt dat je complexe WebDAV instellingen opzet. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek beschrijven. Als je geïnteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Een fijn ding aan Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken, zonder specifieke Git funtionaliteit; dus je kunt deze functionaliteit gebruiken als je web-hosting provider WebDAV ondersteunt voor het maken van wijzigingen aan je webpagina. +Het is mogelijk om Git ook over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en het vraagt dat je complexe WebDAV instellingen inricht. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek beschrijven. Als je geïnteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Het aardige van Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken, zonder specifieke Git funtionaliteit, dus je kunt deze functionaliteit gebruiken als je web-hosting provider WebDAV ondersteunt voor het maken van wijzigingen aan je webpagina. #### De Voordelen #### -Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren zorgt voor een eenvoudige manier om de wereld leestoegang te geven tot je Git repository. Het kost slechts een paar minuten om te doen. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te verspreiden - een normale Apache server kan gemiddeld duizenden bestanden zenden per seconde - is het moeilijk om zelfs een kleine server te overbelasten. +Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren is alles wat er moet gebeuren om de wereld leestoegang te geven tot je Git repository. Het neemt maar een paar minuten van je tijd. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te verspreiden - een normale Apache server kan gemiddeld duizenden bestanden zenden per seconde - is het moeilijk om zelfs een kleine server te overbelasten. -Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat inhoudt dat je het transport kunt versleutelen; je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat laat gebruiken. Normaal gesproken als je je deze moeite wilt getroosten, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan een betere oplossing in jouw specifieke geval zijn om gesigneerde SSL certificaten of andere HTTP-gebaseerde authenticatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. +Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat inhoudt dat je het transport kunt versleutelen; je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat laat gebruiken. Normaal gesproken als je je deze moeite wilt getroosten, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan in jouw specifieke geval een betere oplossing zijn om gesigneerde SSL certificaten of andere HTTP-gebaseerde authenticatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. Een andere prettige bijkomstigheid is dat HTTP een dusdanig veel voorkomend protocol is dat bedrijfsfirewalls vaak zo ingesteld zijn dat ze verkeer via deze poort toestaan. #### De Nadelen #### -Het nadeel van je repository verspreiden 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 veel hogere netwerk belasting en transport volume via HTTP dan met elk van de andere netwerk protocollen. Omdat het niet zo ingewikkeld 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 verspreiden 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 veel hogere netwerk belasting en transport volume via HTTP dan met elk van de andere netwerk protocollen. Omdat het niet zo ingewikkeld is om alleen de data te versturen die je nodig hebt – er wordt geen dynamisch werk door de server gedaan in deze uitwisselingen – 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 naar 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 een Git server initieel op te zetten, moet je een bestaande repository naar 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 conventie eindigen de namen van kale repository mappen met `.git`, zoals: $ git clone --bare my_project my_project.git Initialized empty Git repository in /opt/projects/my_project.git/ @@ -127,13 +127,13 @@ Dit is ongeveer gelijk aan Er zijn een paar kleine verschillen in het configuratie bestand, maar het komt op hetzelfde neer. Het neemt de Git repository zelf, zonder een werkmap, en maakt een map aan specifiek hiervoor. -### Het Bare Repository op een Server Zetten ### +### De Kale Repository op een Server Zetten ### -Nu je een kale kopie van je repository hebt, is het enige dat je moet doen het op een server zetten en je protocollen instellen. Stel dat je een server ingesteld hebt, die `git.example.com` heet, waar je SSH toegang op hebt, en waar je al je Git repositories wilt opslaan onder de `/opt/git` map. Je kunt je nieuwe repository beschikbaar stellen door je kale repository ernaartoe te kopieeren: +Nu je een kale kopie van je repository hebt, is het enige dat je moet doen het op een server zetten en je protocollen instellen. Laten we aannemen dat je een server ingericht hebt, die `git.example.com` heet, waar je SSH toegang op hebt, en waar je al je Git repositories wilt opslaan onder de `/opt/git` map. Je kunt je nieuwe repository beschikbaar stellen door je kale repository ernaartoe te kopiëren: $ 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: +Vanaf dat moment 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: $ git clone user@git.example.com:/opt/git/my_project.git @@ -143,11 +143,11 @@ Als een gebruiker met SSH op een server inlogt en schrijftoegang heeft tot de `/ $ cd /opt/git/my_project.git $ git init --bare --shared -Je ziet hoe eenvoudig het is om een Git repository te nemen, een kale versie aan te maken, en het op een server plaatsen waar jij en je medewerkers SSH toegang tot hebben. Nu ben je klaar om aan hetzelfde project samen te werken. +Je ziet hoe eenvoudig het is om een Git repository te nemen, een kale versie aan te maken, en het op een server plaatsen waar jij en je medewerkers SSH toegang tot hebben. Nu zijn jullie klaar om aan hetzelfde project samen te werken. -Het is belangrijk om op te merken dat dit letterlijk alles is wat je moet doen om een bruikbare Git server te draaien waarop meerdere mensen toegang hebben – voeg alleen een paar SSH accounts toe op een server, en stop een kale repository ergens waar al die gebruikers lees- en schrijftoegang toe hebben. Je bent er klaar voor – je hebt niets anders nodig. +Het is belangrijk om op te merken dat dit letterlijk alles is wat je moet doen om een bruikbare Git server te draaien waarop meerdere mensen toegang hebben – maak alleen een paar accounts met SSH toegang aan op een server, en stop een kale repository ergens waar al die gebruikers lees- en schrijftoegang toe hebben. Je bent er klaar voor – je hebt niets anders nodig. -In de volgende paragrafen zul je zien hoe je meer ingewikkelde opstellingen kunt maken. Deze bespreking zal het niet hoeven aanmaken van gebruikers accounts voor elke gebruiker, publieke leestoegang tot repositories, grafische web interfaces, de Gitosis applicatie gebruiken en meer omvatten. Maar, hou in gedachten dat om samen te kunnen werken met mensen op een privé project, alles wat je _nodig_ hebt is een SSH server en een kale repository. +In de volgende paragrafen zul je zien hoe je meer ingewikkelde opstellingen kunt maken. Deze bespreking zal het niet hoeven aanmaken van gebruikers accounts voor elke gebruiker, publieke leestoegang tot repositories, grafische web interfaces, het gebruik van de Gitosis applicatie en meer omvatten. Maar, hou in gedachten dat om samen te kunnen werken met mensen op een privé project, alles wat je _nodig_ hebt een SSH server is en een kale repository. ### Kleine Opstellingen ### @@ -155,27 +155,26 @@ Als je met een kleine groep bent of net begint met Git in je organisatie en slec #### SSH Toegang #### -Als je reeds een server hebt waar al je ontwikkelaars SSH toegang op hebben, dan is het over het algemeen het eenvoudigste om je eerste repository daar in te stellen, omdat je dan bijna niets hoeft te doen (zoals beschreven in de vorige paragraaf). Als je meer complexe toegangscontrole wilt op je repositories, dan kun je ze instellen met de normale bestandssysteem permissies van het operating systeem dat op je server draait. +Als je al een server hebt waar al je ontwikkelaars SSH toegang op hebben, dan is het over het algemeen het eenvoudigste om je eerste repository daar op te zetten, omdat je dan bijna niets hoeft te doen (zoals beschreven in de vorige paragraaf). Als je meer complexe toegangscontrole wilt op je repositories, dan kun je ze instellen met de normale bestandssysteem permissies van het operating systeem dat op je server draait. -Als je je repositories op een server wilt zetten, die geen accounts heeft voor iedereen in je team die je schrijftoegang wilt geven, dan moet je SSH toegang voor ze instellen. We gaan er vanuit dat je een server hebt waarmee je dit kunt doen, dat je reeds een SSH server geïnstalleerd hebt, en dat de manier is waarop je toegang hebt tot de server. +Als je je repositories op een server wilt zetten, die geen accounts heeft voor iedereen in je team die je schrijftoegang wilt geven, dan moet je SSH toegang voor ze opzetten. We gaan er vanuit dat je een server hebt waarmee je dit kunt doen, dat je reeds een SSH server geïnstalleerd hebt, en dat de manier is waarop je toegang hebt tot de server. Er zijn een paar manieren waarop je iedereen in je team toegang kunt geven. De eerste is voor iedereen accounts aanmaken, wat rechttoe rechtaan is maar bewerkelijk kan zijn. Je wilt vermoedelijk niet `adduser` uitvoeren en tijdelijke wachtwoorden instellen voor iedere gebruiker. -Een tweede methode is een 'git' gebruiker aan te maken op de machine, aan iedere gebruiker die schijftoegang moet hebben vragen of ze je een publieke SSH sleutel sturen, en die sleutel toevoegen aan het `~/.ssh/authorized_keys` bestand van je nieuwe 'git' gebruiker. Vanaf dat moment zal iedereen toegang hebben op die machine via de 'git' gebruiker. Dit tast de commit data op geen enkele manier aan – de SSH gebruiker waarmee je inlogt zal de commits die je opgeslagen hebt niet beïnvloeden. +Een tweede methode is een generieke 'git' gebruiker aan te maken op de machine, aan iedere gebruiker die schijftoegang moet hebben vragen of ze je een publieke SSH sleutel sturen, en die sleutel toevoegen aan het `~/.ssh/authorized_keys` bestand van die nieuwe 'git' gebruiker. Vanaf dat moment zal iedereen toegang hebben op die machine via de 'git' gebruiker. Dit tast de commit data op geen enkele manier aan – de SSH gebruiker waarmee je inlogt zal de commits die je opgeslagen hebt niet beïnvloeden. -Een andere manier waarop je het kunt doen is je SSH server laten authenticeren middels een LDAP server of een andere gecentraliseerde authenticatie bron, die je misschien al ingesteld hebt. Zolang iedere gebruiker shell toegang kan krijgen op de machine, zou ieder SSH authenticatie mechanisme dat je kunt bedenken moeten werken. +Een andere manier waarop je het kunt doen is je SSH server laten authenticeren middels een LDAP server of een andere gecentraliseerde authenticatie bron, die misschien al ingericht is. Zolang iedere gebruiker shell toegang kan krijgen op de machine, zou ieder SSH authenticatie mechanisme dat je kunt bedenken moeten werken. ## Je Publieke SSH Sleutel Genereren ## -Dat gezegd hebbende, zijn er vele Git servers die authenticeren met een publieke SSH sleutel. Om een publieke sleutel te hebben, zal iedere gebruiker in je systeem er een moeten genereren als ze er nog geen hebben. Dit proces is bij alle operating systemen vergelijkbaar. -Als eerste moet je controleren dat je er niet al een hebt. Standaard staan de SSH sleutels van de gebruikers in hun eigen `~/.ssh` map. Je kunt makkelijk nagaan of je al een sleutel hebt door naar die map te gaan en de inhoud te bekijken: +Dat gezegd hebbende, zijn er vele Git servers die authenticeren met een publieke SSH sleutel. Om een publieke sleutel te hebben, zal iedere gebruiker in je systeem er een moeten genereren als ze er nog geen hebben. Dit proces is bij alle operating systemen vergelijkbaar. Als eerste moet je controleren of je er niet al een hebt. Standaard staan de SSH sleutels van de gebruikers in hun eigen `~/.ssh` map. Je kunt makkelijk nagaan of je al een sleutel hebt door naar die map te gaan en de inhoud te bekijken: $ cd ~/.ssh $ ls authorized_keys2 id_dsa known_hosts config id_dsa.pub -Je bent op zoek naar een aantal bestanden genaamd iets en iets.pub, waarbij het `iets` meestal zoiets is als `id_dsa` of `id_rsa`. Het `.pub` bestand is je publieke sleutel en het andere bestand is je private sleutel. Als je deze bestanden niet hebt (of als je zelfs geen `.ssh` map hebt), dan kun je ze aanmaken door een applicatie genaamd `ssh-keygen` uit te voeren, wat meegeleverd wordt met het SSH pakket op Linux/Mac systemen en meegeleverd wordt met het MSysGit pakket op Windows: +Je bent op zoek naar een aantal bestanden genaamd iets en iets.pub, waarbij het `iets` meestal zoiets is als `id_dsa` of `id_rsa`. Het `.pub` bestand is je publieke sleutel en het andere bestand is je private sleutel. Als je deze bestanden niet hebt (of als je zelfs geen `.ssh` map hebt), dan kun je ze aanmaken door een applicatie genaamd `ssh-keygen` uit te voeren, deze wordt met het SSH pakket op Linux/Mac systemen meegeleverd en met het MSysGit pakket op Windows: $ ssh-keygen Generating public/private rsa key pair. @@ -187,7 +186,7 @@ Je bent op zoek naar een aantal bestanden genaamd iets en iets.pub, waarbij het The key fingerprint is: 43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local -Eerst bevestigt het de lokatie waar je de sleutel wilt opslaan (`.ssh/id_rsa`), en vervolgens vraagt het tweemaal om een wachtwoord, die je leeg kunt laten als je geen wachtwoord wilt intypen op het moment dat je de sleutel gebruikt. +Eerst wordt de lokatie waar je de sleutel wordt opgeslagen (`.ssh/id_rsa`) aangegeven, en vervolgens vraagt het tweemaal om een wachtwoord, die je leeg kunt laten als je geen wachtwoord wilt intypen op het moment dat je de sleutel gebruikt. Iedere gebruiker die dit doet, moet zijn sleutel sturen naar jou of degene die de Git server beheert (aangenomen dat je een SSH server gebruikt die publieke sleutels vereist). Het enige dat ze hoeven doen is de inhoud van het `.pub` bestand kopiëren en e-mailen. De publieke sleutel ziet er ongeveer zo uit: @@ -199,18 +198,18 @@ Iedere gebruiker die dit doet, moet zijn sleutel sturen naar jou of degene die d mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx NrRFi9wrf+M7Q== schacon@agadorlaptop.local -Voor een uitgebreide tutorial over het aanmaken van een SSH sleutel op meerdere operating systemen, zie de GitHub handleiding over SSH sleutels op `http://github.com/guides/providing-your-ssh-key`. +Voor een uitgebreide tutorial over het aanmaken van een SSH sleutel op meerdere operating systemen, verwijzen ze je naar de GitHub handleiding over SSH sleutels op `http://github.com/guides/providing-your-ssh-key`. -## De Server Instellen ## +## De Server Opzetten ## -Laten we het instellen van SSH toegang aan de server kant eens doorlopen. In dit voorbeeld zul je de `authorized_keys` methode gebruiken om je gebruikers te authenticeren. We gaan er ook vanuit dat je een standaard Linux distributie gebruikt zoals Ubuntu. Als eerste maak je een 'git' gebruiker aan en een `.ssh` map voor die gebruiker. +Laten we het opzetten van SSH toegang aan de server kant eens doorlopen. In dit voorbeeld zul je de `authorized_keys` methode gebruiken om je gebruikers te authenticeren. We gaan er ook vanuit dat je een standaard Linux distributie gebruikt zoals Ubuntu. Als eerste maak je een 'git' gebruiker aan en een `.ssh` map voor die gebruiker. $ sudo adduser git $ su git $ cd $ mkdir .ssh -Daarna moet je een aantal publieke SSH sleutels van ontwikkelaars aan het `authorized_keys` bestand toevoegen voor die gebruiker. Laten we aannemen dat je een aantal sleutels per e-mail ontvangen hebt en ze hebt opgeslagen in tijdelijke bestanden. Nogmaals, de sleutels zien er ongeveer zo uit: +Vervolgens moet je een aantal publieke SSH sleutels van ontwikkelaars aan het `authorized_keys` bestand toevoegen voor die gebruiker. Laten we aannemen dat je een aantal sleutels per e-mail ontvangen hebt en ze hebt opgeslagen in tijdelijke bestanden. Nogmaals, de sleutels zien er ongeveer zo uit: $ cat /tmp/id_rsa.john.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4L @@ -233,7 +232,7 @@ Nu kun je een lege repository voor ze instellen door `git init` uit te voeren me $ cd project.git $ git --bare init -Daarna kunnen John, Josie of Jessica de eerste versie van hun project in de repository pushen door het als een remote toe te voegen en naar een branch te pushen. Let op dat iemand met een shell op de machine zal moeten inloggen en een kale repository moet creëren, iedere keer als je een project wilt toevoegen. Laten we `gitserver` als hostnaam gebruiken voor de server waar je de 'git' gebruiker en repository hebt ingesteld. Als je het binnenshuis draait, en je de DNS instelt zodat `gitserver` naar die server wijst, dan kun je de commando's vrijwel ongewijzigd gebruiken: +Daarna kunnen John, Josie of Jessica de eerste versie van hun project in de repository pushen door het als een remote toe te voegen en een branch te pushen. Merk op dat iemand met een shell op de machine zal moeten inloggen en een kale repository moet creëren voor elke keer dat je een project wilt toevoegen. Laten we `gitserver` als hostnaam gebruiken voor de server waar je de 'git' gebruiker en repository hebt aangemaakt. Als je het binnenshuis draait, en je de DNS instelt zodat `gitserver` naar die server wijst, dan kun je de commando's vrijwel ongewijzigd gebruiken: # op Johns computer $ cd myproject @@ -250,7 +249,7 @@ Vanaf dat moment kunnen de anderen het clonen en wijzigingen even gemakkelijk te $ git commit -am 'fix for the README file' $ git push origin master -Met deze methode kun je snel een lees/schrijf Git server draaiend krijgen voor een handjevol ontwikkelaars. +Op deze manier kun je snel een lees/schrijf Git server draaiend krijgen voor een handjevol ontwikkelaars. Als een extra voorzorgsmaatregel kun je de 'git' gebruiker makkelijk beperken tot het doen van alleen Git activiteiten, met een gelimiteerde shell applicatie genaamd `git-shell` die bij Git geleverd wordt. Als je dit als login shell voor je 'git' gebruiker instelt, dan kan de 'git' gebruiker geen normale shell toegang hebben op je server. Specificeer `git-shell` in plaats van bash of csh voor je gebruikers login shell om dit te gebruiken. Om dit te doen zul je waarschijnlijk het `/etc/passwd` bestand aan moeten passen: @@ -273,11 +272,11 @@ Nu kan de 'git' gebruiker de SSH connectie alleen gebruiken om Git repositories ## Publieke Toegang ## -Wat als je anonieme leestoegang op je project wil? Misschien wil je geen intern privé project beheren, maar een open source project. Of misschien heb je een aantal geautomatiseerde bouwservers of continue integratie servers die vaak wijzigen, en wil je niet doorlopend SSH sleutels hoeven genereren – je wil gewoon eenvoudige leestoegang toevoegen. +Wat als je anonieme leestoegang op je project wil? Misschien wil je geen intern privé project beheren, maar een open source project. Of misschien heb je een aantal geautomatiseerde bouwservers of continue integratie servers die vaak wisselen, en wil je niet doorlopend SSH sleutels hoeven genereren – je wil gewoon eenvoudige anonieme leestoegang toevoegen. -Waarschijnlijk is de eenvoudigste manier voor kleinschalige opstellingen om een statische webserver in te stellen, waarbij de document root naar de plaats van je Git repositories wijst, en dan de `post-update` haak aanzetten waar we het in de eerste paragraaf van dit hoofdstuk over gehad hebben. Laten we eens uitgaan van het voorgaande voorbeeld. Stel dat je je repositories in de `/opt/git` map hebt staan, en er draait een Apache server op je machine. Nogmaals, je kunt hiervoor iedere web server gebruiken: maar als voorbeeld zullen we wat basis Apache configuraties laten zien, die je een idee kunnen geven van wat je nodig hebt. +Waarschijnlijk is de eenvoudigste manier voor kleinschalige opstellingen om een statische webserver in te stellen, waarbij de document root naar de plaats van je Git repositories wijst, en dan de `post-update` haak aanzetten waar we het in de eerste paragraaf van dit hoofdstuk over gehad hebben. Laten we eens uitgaan van het voorgaande voorbeeld. Stel dat je je repositories in de `/opt/git` map hebt staan, en er draait een Apache server op je machine. Nogmaals, je kunt hiervoor iedere web server gebruiken: maar als voorbeeld zullen we wat simpele Apache configuraties laten zien, die je het idee weergeven van wat je nodig hebt. -Eerst moet je de haak aanzetten: +Eerst moet je de haak inschakelen: $ cd project.git $ mv hooks/post-update.sample hooks/post-update @@ -285,7 +284,7 @@ Eerst moet je de haak aanzetten: Als je een lagere versie dan 1.6 van Git gebruikt, dan is het `mv` commando niet nodig – Git is recentelijk pas begonnen met de namen van de haak voorbeelden op .sample te laten eindigen. -Wat doet deze `post-update` haak? Het ziet er ongeveer zo uit: +Wat doet deze `post-update` haak? Het ziet er eigenlijk als volgt uit: $ cat .git/hooks/post-update #!/bin/sh @@ -293,7 +292,7 @@ Wat doet deze `post-update` haak? Het ziet er ongeveer zo uit: Dit betekent dat wanneer je naar de server via SSH pushed, 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 wildcard DNS ingesteld hebt om `*.gitserver` door te sturen naar waar je dit alles draait: +Vervolgens moet je een VirtualHost regel in je Apache configuratie aanmaken, met de document root als de hoofdmap van je Git projecten. Hier nemen we aan dat je wildcard DNS ingesteld hebt om `*.gitserver` door te sturen naar waar je dit alles draait: ServerName git.gitserver @@ -304,7 +303,7 @@ Vervolgens moet je een VirtualHost toevoeging in je Apache configuratie aanmaken -Je zult ook de Unix gebruikers groep van de `/opt/git` mappen moeten instellen op `www-data` zodat je web server leestoegang hebt op de repositories, omdat de Apache instantie die het CGI script uitvoert (standaard) als die gebruiker draait: +Je zult ook de Unix gebruikers groep van de `/opt/git` mappen moeten zetten op `www-data` zodat je web server leestoegang hebt op de repositories, omdat de Apache instantie het CGI script (standaard) uitvoert als die gebruiker draait: $ chgrp -R www-data /opt/git @@ -312,26 +311,26 @@ Als je Apache herstart, dan zou je je repositories onder die map moeten kunnen c $ git clone http://git.gitserver/project.git -Op deze manier kun je HTTP-gebaseerde toegang voor elk van je projecten voor een groot aantal gebruikers in slechts een paar minuten instellen. Een andere eenvoudige optie om publieke ongeauthenticeerde toegang in te stellen is een Git daemon te starten, alhoewel dat vereist dat je het proces als daemon uitvoert – we beschrijven deze optie in de volgende paragraaf als je een voorkeur hebt voor deze variant. +Op deze manier kun je HTTP-gebaseerde toegang voor elk van je projecten voor een groot aantal gebruikers in slechts een paar minuten regelen. Een andere eenvoudige optie om publieke ongeauthenticeerde toegang in te stellen is een Git daemon te starten, alhoewel dat vereist dat je het proces als daemon uitvoert – we beschrijven deze optie in de volgende paragraaf als je een voorkeur hebt voor deze variant. ## GitWeb ## -Nu je basis lees/schrijf en alleen-lezen toegang tot je project hebt, wil je misschien een eenvoudige web-gebaseerde visualisatie instellen. Git levert een CGI script genaamd GitWeb mee, dat veelal voor hiervoor gebruikt wordt. Je kunt GitWeb in gebruik zien bij sites zoals `http://git.kernel.org` (zie Figuur 4-1). +Nu je gewone lees/schrijf en alleen-lezen toegang tot je project hebt, wil je misschien een eenvoudige web-gebaseerde visualisatie instellen. Git levert een CGI script genaamd GitWeb mee, dat normaalgesproken hiervoor gebruikt wordt. Je kunt GitWeb in actie zien bij sites zoals `http://git.kernel.org` (zie Figuur 4-1). Insert 18333fig0401.png Figuur 4-1. De GitWeb web-gebaseerde gebruikers interface. -Als je wil zien hoe GitWeb er op jouw project uitziet, dan heeft Git een commando waarmee je een tijdelijke instantie op kunt starten als je een lichtgewicht server op je systeem hebt zoals `lighttpd` of `webrick`. Op Linux machines is `lighttpd` vaak geinstalleerd, dus je kunt het misschien draaiend krijgen door `git instaweb` in te typen in je project map. Als je op een Mac werkt: Leopard heeft Ruby voorgeinstalleerd, dus `webrick` zou je beste gok kunnen zijn. Om `instaweb` met een server anders dan lighttpd te starten, kun je het uitvoeren met de `--httpd` optie. +Als je wil zien hoe GitWeb er voor jouw project uitziet, dan heeft Git een commando waarmee je een tijdelijke instantie op kunt starten als je een lichtgewicht server op je systeem hebt zoals `lighttpd` of `webrick`. Op Linux machines is `lighttpd` vaak geïnstalleerd, dus je kunt het misschien draaiend krijgen door `git instaweb` in te typen in je project map. Als je op een Mac werkt: Leopard heeft Ruby voorgeïnstalleerd, dus `webrick` zou je de meeste kans geven. Om `instaweb` met een server anders dan lighttpd te starten, moet je het uitvoeren met de `--httpd` optie. $ 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] -Dat start een HTTPD server op poort 1234 op en start automatisch een web browser op die met die pagina opent. Het is dus makkelijk voor je. Als je klaar bent en de server wilt afsluiten, dan kun je hetzelfde commando uitvoeren met de `--stop` optie: +Dat start een HTTPD server op poort 1234 op en start automatisch een web browser die op die pagina opent. Het is dus makkelijk voor je. Als je klaar bent en de server wilt afsluiten, dan kun je hetzelfde commando uitvoeren met de `--stop` optie: $ git instaweb --httpd=webrick --stop -Als je de web interface doorlopend op een server wilt draaien voor je team of voor een open source project dat je verspreid, dan moet je het CGI script instellen zodat het door je normale web server geserveerd wordt. Sommige Linux distributies hebben een `gitweb` pakket dat je misschien kunt installeren via `apt` of `yum`, dus misschien kan je dat eerst proberen. We zullen snel door een handmatige GitWeb installatie heenlopen. Eerst moet je de Git broncode pakken waar GitWeb bij zit, en het aangepaste CGI script genereren: +Als je de web interface doorlopend op een server wilt draaien voor je team of voor een open source project dat je verspreid, dan moet je het CGI script instellen zodat het door je normale web server geserveerd wordt. Sommige Linux distributies hebben een `gitweb` pakket dat je zou kunnen installeren via `apt` of `yum`, dus wellicht kan je dat eerst proberen. We zullen snel door een handmatige GitWeb installatie heen lopen. Eerst moet je de Git broncode pakken waar GitWeb bij zit, en het aangepaste CGI script genereren: $ git clone git://git.kernel.org/pub/scm/git/git.git $ cd git/ @@ -354,17 +353,17 @@ Merk op dat je het commando moet vertellen waar het je Git repositories kan vind -Nogmaals, GitWeb kan geserveerd worden met iedere web server die in staat is CGI te verwerken; 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 web server die in staat is CGI te verwerken. Als je iets anders prefereert zou het niet moeilijk moeten zijn dit in te stellen. Vanaf dit moment 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. ## Gitosis ## -De publieke sleutels van alle gebruikers in een `authorized_keys` bestand bewaren voor toegang werkt slechts korte tijd goed. Als je honderden gebruikers hebt, dan is het bewerkelijk om dat proces te volgen. Je moet iedere keer in de server inloggen, en er is geen toegangscontrole – iedereen in het bestand heeft lees- en schrijftoegang op ieder project. +De publieke sleutels van alle gebruikers in een `authorized_keys` bestand bewaren voor toegang werkt slechts korte tijd goed. Als je honderden gebruikers hebt, dan is het te bewerkelijk om dat proces te blijven volgen. 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 verzameling scripts die je helpen het `authorized_keys` bestand te beheren alsmede eenvoudig 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 beheert de informatie in dat project; en als je het pushed, dan herconfigureert Gitosis de server op basis van dat project, wat best wel stoer is. +Op dat moment zou je kunnen overwegen een veelgebruikt software project genaamd Gitosis te gaan gebruiken. Gitosis is in feite een verzameling scripts die je helpen het `authorized_keys` bestand te beheren alsmede eenvoudig toegangscontrole te implementeren. Het interessante hieraan 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 beheert de informatie in dat project en als je het pushed, dan herconfigureert Gitosis de server op basis van dat project, wat best wel slim bedacht is. -Gitosis installeren is niet de makkelijkste taak ooit, maar het is ook niet te moeilijk. Het is het makkelijkste om er een Linux server voor te gebruiken – deze voorbeelden gebruiken een standaard Ubuntu 8.10 server. +Gitosis installeren is niet de makkelijkste taak ooit, maar het is ook niet al te moeilijk. Het is het makkelijkste om er een Linux server voor te gebruiken – deze voorbeelden gebruiken een standaard Ubuntu 8.10 server. -Gitosis vereist enkele Python applicaties, dus moet je eerst het Python setuptools pakket installeren, wat Ubuntu beschikbaar stelt als python-setuptools: +Gitosis vereist enkele Python tools, dus moet je eerst het Python setuptools pakket installeren, wat Ubuntu beschikbaar stelt als python-setuptools: $ apt-get install python-setuptools @@ -374,15 +373,15 @@ Vervolgens clone en installeer je Gitosis van de hoofdpagina van het project: $ cd gitosis $ sudo python setup.py install -Daarmee worden een aantal bestanden geinstalleerd, die Gitosis zal gebruiken. Daarna wil Gitosis zijn repositories onder `/home/git` stoppen, wat prima is. Maar je hebt je repositories al in `/opt/git` geconfigureerd, dus in plaats van alles te herconfigureren maken we een symbolische link aan: +Daarmee worden een aantal bestanden geïnstalleerd, die Gitosis zal gebruiken. Daarna wil Gitosis zijn repositories onder `/home/git` stoppen, wat prima is. Maar je hebt je repositories al in `/opt/git` geconfigureerd, dus in plaats van alles te herconfigureren maken we een symbolische link aan: $ ln -s /opt/git /home/git/repositories -Gitosis zal je sleutels voor je beheren, dus je moet het huidige bestand verwijderen, om de sleutels later opnieuw toe te voegen en Gitosis het `authorized_keys` bestand automatisch laten beheren. Voor nu verplaatsen we het `authorized_keys` bestand: +Gitosis zal de sleutels voor je beheren, dus je moet het huidige bestand verwijderen, om de sleutels later opnieuw toe te voegen en Gitosis het `authorized_keys` bestand automatisch laten beheren. Voor nu verplaatsen we het `authorized_keys` bestand: $ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak -Nu moet je je shell terugzetten voor de 'git' gebruiker, als je het veranderd hebt naar het `git-shell` commando. Mensen zullen nog steeds niet in staat zijn in te loggen, maar Gitosis zal dat voor je beheren. Dus, laten we deze regel veranderen in je `/etc/passwd` bestand +Nu moet je de shell terugzetten voor de 'git' gebruiker, als je het veranderd hebt naar het `git-shell` commando. Mensen zullen nog steeds niet in staat zijn in te loggen, Gitosis zal dat voor je beheren. Dus, laten we deze regel veranderen in je `/etc/passwd` bestand git:x:1000:1000::/home/git:/usr/bin/git-shell @@ -390,17 +389,17 @@ terug naar dit: git:x:1000:1000::/home/git:/bin/sh -Nu wordt het tijd om Gitosis te initialiseren. Je doet dit door het `gitosis-init` commando met je eigen publieke sleutel uit te voeren. Als je publieke sleutel niet op de server staat zul je het daar naartoe moeten kopieeren: +Nu wordt het tijd om Gitosis te initialiseren. Je doet dit door het `gitosis-init` commando met je eigen publieke sleutel uit te voeren. Als je publieke sleutel niet op de server staat zul je het daar naartoe moeten kopiëren: $ 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/ -Dit staat de gebruiker met die sleutel toe de hoofd Git repository, die de Gitosis installatie beheert, aan te passen. Daarna zul je met de hand het execute bit op het `post-update` script moeten instellen voor je nieuwe beheer repository. +Dit staat de gebruiker met die sleutel toe de hoofd Git repository, die de Gitosis setup regelt, aan te passen. Daarna zul je met de hand het execute bit op het `post-update` script moeten aanzetten voor je nieuwe beheer repository. $ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update -Je bent nu klaar om te gaan. Als je alles juist hebt ingesteld, kun je nu met SSH in je server loggen als de gebruiker waarvoor je de publieke sleutel hebt toegevoegd om Gitosis te initialiseren. Je zou dan zoiets als dit moeten zien: +Je bent nu klaar voor de start. Als je alles juist hebt ingesteld, kun je nu met SSH in je server loggen als de gebruiker waarvoor je de publieke sleutel hebt toegevoegd om Gitosis te initialiseren. Je zou dan zoiets als dit moeten zien: $ ssh git@gitserver PTY allocation request failed on channel 0 @@ -420,7 +419,7 @@ Nu heb je een map genaamd `gitosis-admin`, die twee gedeeltes heeft: ./keydir ./keydir/scott.pub -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 geimporteerd met het `gitosis-init` script. +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 de repositories hebben – één bestand per gebruiker. De naam van het bestand in `keydir` (in het vorige voorbeeld, `scott.pub`) zal anders zijn in jouw geval – 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: @@ -431,15 +430,15 @@ Als je naar het `gitosis.conf` bestand kijkt, zou het alleen informatie over het writable = gitosis-admin members = scott -Het laat je zien dat de gebruiker 'scott' – de gebruiker met wiens publieke sleutel je Gitosis geinitialiseerd hebt – de enige is die toegang heeft tot het `gitosis-admin project. +Het laat je zien dat de gebruiker 'scott' – de gebruiker met wiens publieke sleutel je Gitosis geïnitialiseerd hebt – de enige is die toegang heeft tot het `gitosis-admin` project. -Laten we een nieuw project voor je toevoegen. Je voegt een nieuwe sectie genaamd `mobile` toe, waar je de ontwikkelaars in je mobile team neerzet, en de projecten waar deze ontwikkelaars toegang tot moeten hebben. Omdat 'scott' op het moment de enige gebruiker in het systeem is, zul je hem als enig lid toevoegen en zul je een nieuw project genaamd `iphone_project` toevoegen om mee te beginnen: +Laten we nu een nieuw project voor je toevoegen. Je voegt een nieuwe sectie genaamd `mobile` toe, waar je de ontwikkelaars in het mobile team neerzet, en de projecten waar deze ontwikkelaars toegang tot moeten hebben. Omdat 'scott' op het moment de enige gebruiker in het systeem is, zul je hem als enig lid toevoegen en voeg je een nieuw project genaamd `iphone_project` toe om mee te beginnen: [group mobile] writable = iphone_project members = scott -Wanneer je wijzigingen aan het `gitosis-admin` project moet maken, moet je de veranderingen committen en terug pushen naar de server voordat ze effect hebben: +Wanneer je wijzigingen aan het `gitosis-admin` project maakt, moet je de veranderingen committen en terug pushen naar de server voordat ze effect hebben: $ git commit -am 'add iphone_project and mobile group' [master]: created 8962da8: "changed name" @@ -465,7 +464,7 @@ Je kunt je eerste push naar het nieuwe `iphone_project` doen door je server als Merk op dat je geen pad hoeft te specificeren (sterker nog, het wel doen zal niet werken), alleen een dubbele punt en dan de naam van het project – Gitosis zal het voor je vinden. -Je wil samen met je vrienden aan dit project werken, dus je zult hun publieke sleutels weer toe moeten voegen. Maar in plaats van ze handmatig aan het `~/.ssh/authorized_keys` bestand op je server toe te voegen, voeg je ze, één sleutel per bestand, aan de `keydir` map toe. Hoe je de sleutels noemt bepaalt hoe je aan de gebruikers refereert in het `gitosis.conf` bestand. Laten we de publieke sleutels voor John, Josie en Jessica toevoegen: +Je wil samen met je vrienden aan dit project werken, dus je zult hun publieke sleutels weer toe moeten voegen. Maar in plaats van ze handmatig aan het `~/.ssh/authorized_keys` bestand op je server toe te voegen, voeg je ze één sleutel per bestand, aan de `keydir` map toe. Hoe je de sleutels noemt bepaalt hoe je aan de gebruikers refereert in het `gitosis.conf` bestand. Laten we de publieke sleutels voor John, Josie en Jessica toevoegen: $ cp /tmp/id_rsa.john.pub keydir/john.pub $ cp /tmp/id_rsa.josie.pub keydir/josie.pub @@ -489,7 +488,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 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 alle verschillende gebruikers en projecten mogen bevatten. Je kunt ook een andere groep als een van de leden specificeren (met @ als voorvoegsel), waarmee de groepsleden automatisch worden overerfd: [group mobile_committers] members = scott josie jessica @@ -502,21 +501,198 @@ 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 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. + +## Gitolite ## + +Merk op: de laatste versie van deze paragraaf in het ProGit boek is altijd beschikbaar binnen de [gitolite documentation][gldpg]. De auteur geeft ook nederig aan dat, hoewel deze paragraaf accuraat is, het *kan* (en vaak ook *is*) gebruikt om gitolie te installeren zonder enige andere documentatie te lezen, dat het niet gegarandeerd compleet is, en het zeker niet de gehele enorme hoeveelheid documentatie kan vervangen dat meegeleverd wordt met gitolite. + +[gldpg]: http://github.com/sitaramc/gitolite/blob/pu/doc/progit-article.mkd + +Git begint erg populair te worden in het bedrijfsleven, die de neiging hebben nog wat additionele eisen te hebben op het gebied van toegangscontrole. Gitolite was oorspronkelijk gemaakt om bij het vervullen van deze eisen te helpen, maar het blijkt dat het even bruikbaar is in de wereld van de open source: het Fedora Project beheert toegang tot hun package beheer repositories (meer dan 10.000 daarvan!) met gitolite, en het is waarschijnlijk daarbij ook nog eens de grootste gitolite installatie waar dan ook. + +Gitolite stelt je in staat de permissies niet alleen per repository, maar ook per branch of tag naam binnen elke repository. Dus, je kunt aangeven dat bepaalde mensen (of groepen van mensen) alleen maar bepaalde "refs" (branches of tags) kunnen pushen maar niet andere. + +### Installatie ### + +Het installeren van Gitolite is zeer eenvoudig, zelfs als je de uitgebreide documentatie, dat erbij geleverd wordt, niet leest. Je hebt een account op een Unix(achtige) server hebben; verschillende Linux smaken en Solaris 10 zijn getest. Je hebt geen root toegang nodig, aangenomen dat git, perl, en een openssh compatible ssh server al zijn geïnstalleerd. In de onderstaand voorbeelden zullen we het `gitolite` account gebruiken op een host genaamd `gitserver`. + +Gitolite is nogal ongebruikelijk in de zin van "server" software -- toegang gaat via ssh, en elke userid op de server is in potentie een "gitolite host". Het resultaat is, dat er een idee is van "installeren" van de software zelf, en dan het "opzetten" van een gebruiker als een "gitolist host". + +Mensen zonder root toegang kunnen het installeren binnen hun eigen user id. Als laatste: gitlite kan geïnstalleerd worden door een script te starten *op het werkstation*, vanuit een bash-shell. (Zelfs de bash die meegeleverd wordt met msysgit volstaat, voor het geval je je dat afvroeg.) + +We zullen dit laatste in dit stuk beschrijven, voor de overige methoden verwijzen we je naar de documentatie. + +Je begint met het verkrijgen van toegang op basis van een publieke sleutel, zodat je vanaf je werkstation op de server kan inloggen zonder het intypen van je wachtwoord. De volgende methode werkt op Linux; voor andere werkstation besturingssystemen moet je dit wellicht handmatig doen. We gaan er vanuit dat je al een sleutelpaar hebt gegenereerd met `ssh-keygen`. + + $ ssh-copy-id -i ~/.ssh/id_rsa gitolite@gitserver + +Dit zal je vragen naar een wachtwoord naar het gitolite account, en dan de publieke sleutel toegang opzetten. Dit is **absoluut noodzakelijk** voor het installatiescript, dus controleer dit om er zeker van te zijn dat je een commando kan laten lopen zonder een wachtwoord te hoeven in typen. + + $ ssh gitolite@gitserver pwd + /home/gitolite + +Vervolgens, clone je Gitolite van de hoofdsite van het project en roept de "easy install" script aan (het derde argument is jouw naam zoals je deze in de resulterende gitolite-admin repository wilt laten verschijnen): + + $ git clone git://github.com/sitaramc/gitolite + $ cd gitolite/src + $ ./gl-easy-install -q gitolite gitserver sitaram + +En dat is het! Gitolite is nu geïnstalleerdop je server, en je hebt nu een gloednieuwe repository genaamd `gitolite-admin` in de home directory van jouw werkstation. Je beheert je gitolite setup door een wijziging aan te brengen in deze reporitory en deze te pushen. + +Dat laatste commando produceert nogal een hoeveelheid uitvoer dat wellicht interessant is om te lezen. Ook wordt er, de eerste keer dat je het laat lopen, er een nieuwe sleutelpaar gemaakt; je moet een wachtwoord kiezen of Enter als je er geen wilt. Waarom een tweede sleutelpaar nodig is, en hoe deze wordt gebruikt, wordt uitgelegd in het "ssh troubleshooting" document dat bij Gitolite wordt meegeleverd. (Hey, de documentatie moet *ergens* goed voor zijn!) + +Repositories genaamd `gitolite-admin` en `testing` worden standaard op de server aangemaakt. Als je een van beide lokaal wilt clonen (van een account die SSA console toegang heeft naar het gitolite account via *authorized_keys*) type je: + + $ git clone gitolite:gitolite-admin + $ git clone gitolite:testing + +Om deze zelfde repositories te clonen van een willekeurige ander account: + + $ git clone gitolite@servername:gitolite-admin + $ git clone gitolite@servername:testing + +### De Installatie Aanpassen ### + +Hoewel de standaard, snelle, installatie werkt voor de meeste mensen, zijn er een aantal manieren om de installatie aan te passen als dat nodig is. Als je het `-q` argument weg laat, krijg je een "verbose" installatie wijze -- gedetaileerde informatie over wat de installatie aan het doen is bij elke stap. De verbose wijze staat je ook toe om bepaalde server-side parameters aan te passen, zoals de locatie van de eigenlijke repositories, door het wijzigen van een "rc" bestand dat de server gebruikt. Dit "rc" bestand is ruimhartig van commentaar voorzien dus je zou in staat moeten zijn om elke wijziging die je nodig vindt vrij snel te maken, op te slaan en door te gaan. Dit bestand bevat ook enkele instellingen die je kunt aanpassen om de meer geavanceerde functies van gitolite aan of uit te zetten. + +### Config bestand en Beheer van Toegangsregels ### + +Op het moment dat de installatie afgerond is, schakel je over naar de `gitolite-admin` repository (staat in je HOME directory) en begin je rond te snuffelen om te zien wat je daar hebt: + + $ cd ~/gitolite-admin/ + $ ls + conf/ keydir/ + $ find conf keydir -type f + conf/gitolite.conf + keydir/sitaram.pub + $ cat conf/gitolite.conf + #gitolite conf + # please see conf/example.conf for details on syntax and features + + repo gitolite-admin + RW+ = sitaram + + repo testing + RW+ = @all + +Merk op dat "sitaram" (het laatste argument in het `gl-easy-install` commando dat je eerder gegeven hebt) lees en schrijf rechten heeft op de `gitolite-admin` repository en een publiek sleutelbestand met dezelfde naam. + +De syntax van het config bestand voor gitolite is ruimhartig van documentatie voorzien in `conf/example.conf`, dus we zullen alleen wat hoofdpunten benoemen. + +Je kunt voor het gemak gebruikers of repositories groeperen. De groepnamen zijn vergelijkbaar met macros; als je ze definieert maakt het niet uit of het projecten of gebruikers zijn, dat onderscheid wordt pas gemaakt als je de "macro" gaat *gebruiken*. + + @oss_repos = linux perl rakudo git gitolite + @secret_repos = fenestra pear + + @admins = scott # Adams, not Chacon, sorry :) + @interns = ashok # get the spelling right, Scott! + @engineers = sitaram dilbert wally alice + @staff = @admins @engineers @interns + +Je kunt de permissies beheren op het "ref" niveau. In het volgende voorbeeld kunnen stagieres (interns) alleen maar naar de "int" branch pushen. Techneuten (engineers) kunnen naar elke branch pushen waarvan de naam begint met "eng-", en tags die beginnen met "rc" gevolgd door een getal. En de admins kunnen alles (inclusief terugdraaien) naar elke ref. + + repo @oss_repos + RW int$ = @interns + RW eng- = @engineers + RW refs/tags/rc[0-9] = @engineers + RW+ = @admins + +De expressie achter de `RW` of `RW+` is een zgn. regular expression (regex) waartegen de refname (ref) die wordt gepushed wordt vergeleken. Dus we noemen het natuurlijk een "refex"! En natuurlijk kan een refex veel krachtiger zijn dan hier wordt getoond, dus ga het niet overdrijven als je niet al te goed in de perl regexen zit. + +Zoals je wellicht al geraden hebt, prefixed Gitolite `refs/heads/` als een syntactische handigheid als de refex niet begint met `refs/`. + +Een belangrijke eigenschap van de syntax van het config bestand is dat alle regels van een repository niet op één plek hoeft te staan. Je kunt al het generieke spul bij elkaar houden, zoals de regels voor alle `oss_repos` zoals ze hier boven staan, en dan op een latere plaats specifieke regels voor specifieke gevallen, zoals hier: + + repo gitolite + RW+ = sitaram + +Deze regel wordt gewoon toegevoegd aan de set met regels voor de `gitolite` repository. + +Je zou je op dit punt kunnen afvragen hoe de toegangsregels eigenlijk worden toegepast, laten we dat kort behandelen. + +Er zijn twee niveaus van toegangsbeheer in gitolite. De eerste is op repository niveau. Als je lees (of schrijf)rechten hebt tot *enige* ref in de repository, dan heb je lees (of schrijf) rechten tot de repository. + +Het tweede niveau, alleen van toepassing voor "schrijf" toegang, is per branch of tag binnen een repository. De gebruikersnaam, het type toegang wat wordt gevraagd (`W` of '+'), en de refname dat wordt gewijzigd (update) zijn bekend. De toegangsregels worden gecontroleerd in volgorde van voorkomst in het config bestand, en er wordt gekeken naar een treffer voor deze combinatie (maar onthoudt dat de refname middels een regex wordt vergeleken, niet een simpele string-vergelijking). Als er een treffer is, dan slaagt de push. Als er geen treffer wordt gevonden (fallthrough) dan wordt toegang geweigerd. + +### Geavanceerde Toegangs Controle met "deny" regels ### + +Tot zover hebben we alleen permissies gezien uit het rijtje `R`, `RW` of `RW+`. Echter, gitolite kent een andere permissie: `-`, wat staat voor "deny" (ontken). Dit geeft je veel meer macht, tegen kosten van wat hogere complexiteit omdat een fallthrough nu niet de *enige* manier is waarop toegang kan worden geweigerd, wordt *de volgorde van regels belangrijk*! + +Stel dat, in de onderstaande situatie, we de techneuten in staat willen stellen elke branch te laten terugdraaien *behalve* master en integ. Dit is de manier om dat te doen: + + RW master integ = @engineers + - master integ = @engineers + RW+ = @engineers + +Nogmaals, je hoeft slechts de regels van boven naar beneden af te lopen tot je een treffer hebt voor je gevraagde toegangswijze, of een afwijzing. Een push die niets terugdraait naar master of integ wordt door de eerste regel toegestaan. Een terugdraai-push naar deze refs geeft geen treffer op de eerste regel en valt door naar de tweede regel en wordt daarom geweigerd. Elke push (terugdraaiend of niet) naar refs anders dan master of integ zullen op de eerste twee regels zowiezo niet treffen en de derde regel staat dit toe. + +### Beperken van pushes bij gewijzigde bestanden ### + +Bovenop het beperken van gebruikersrechten op branches voor een gebruiker, kan je ook de rechten van gebruikers beperken op bestanden. Als voorbeeld, misschien is de Makefile (of een ander programma) niet echt bedoeld om te worden gewijzigd door iedereen, omdat een groot aantal dingen afhankelijk ervan zijn of omdat het stuk loopt als de wijzigingen niet *precies goed* gebeuren. Je kunt het gitolite duidelijk maken: + + repo foo + RW = @junior_devs @senior_devs + + RW NAME/ = @senior_devs + - NAME/Makefile = @junior_devs + RW NAME/ = @junior_devs + +Deze krachtige eigenschap is gedocumenteerd in `conf/example.conf`. + +### Persoonlijke branches ### + +Gitolite heeft ook een mogelijkheid van "persoonlijke branches" (of liever gezegd "persoonlijke branch namespace") wat erg nuttig kan zijn in een bedrijfssituatie. + +Veel van de code-uitwisselingen in de git-wereld verlopen via zgn. "please pull" aanvragen. In een bedrijfsomgeving echter is ongeauthoriseerde toegang taboe, en het werkstation van een ontwikkelaar kan geen authenticatie doen, dus je moet naar de centrale server pushen en iemand vragen daarvandaan te pullen. + +Dit zou normaalgesproken een gelijksoortige branch-brij veroorzaken als in een gecentraliseerde versiebeheersysteem, en daarbij wordt het opzetten van permissies een vervelende klus voor de administrator. + +Gitolite stelt je in staat een "personal" of "scratch" namespace prefix voor elke ontwikkelaar te definiëren (bijvoorbeeld `refs/personal//*`); zie ook de "personal branches" paragraaf in `doc/3-faq-tips-etc.mkd` voor details. + +### "Wildcard" repositores ### + +Gitolite laat je repositories specificeren met wildcards (eigenlijk perl regex expressies), zoals bijvoorbeeld `assignments/s[0-9][0-9]/a[0-9][0-9]`, om maar een willekeurig voorbeeld te nemen. Dit is een *heel* krachtige eigenschap die wordt aangezet door de regel `$GL_WILDREPOS = 1;` in het rc bestand. Het laat je een nieuwe permissiewijze ("C") toe te wijzen welke gebruikers in staat stelt repositories aan te maken die voldoen aan zulke wildcards, automatisch eigenaarsschap toe te wijzen aan de gebruiker die hem heeft aangemaakt, staat deze gebruiker toe om "R" en "RW" permissies aan anderen toe te wijzen om samen te werken, etc. Deze eigenschap is beschreven in `doc/4-wildcard-repositories.mkd`. + +### Andere eigenschappen ### + +We ronden deze uiteenzetting af met een passe partout van andere eigenschappen, welke alle (en nog vele andere) tot in de kleinste detail zijn beschreven in de "faqs, tips, etc" en andere documenten. + +**Logging**: Gitolite logt alle succesvolle toegangspogingen. Als je wat te los bent geweest in het toekennen van terugdraai permissies (`RW+`) en een of andere nozem heeft "master" vernaggelt, is de log-file een redder in de nood in de zin van snel en eenvoudig achterhalen van de SHA die verdwenen is. + +**Git buiten reguliere PATH**: Een ontzettend handige eigenschap in gitolite is het ondersteunen van git buiten het regulier `$PATH` (dit komt vaker voor dan je zou denken, sommige bedrijfs omgevingen of zelfs sommige hosting providers weigeren dingen systeem-breed te installeren en je eindigt ermee dat je ze in je eigen directories zet). Normaalgesproken ben je gedwongen git aan de *client-side* op de een of andere manier te vertellen van deze niet-standaard locatie van de git binaries. Met gitolite hoe je alleen een verbose installatie te kiezen en `$GIT_PATH` in de "rc" bestanden in te vullen. Hierna geen wijzigingen aan de kant van de clients nodig :-) + +**Rapportage van toegangsrechten**: Nog zo'n handige eigenschap is wat er gebeurt als je gewoon met ssh naar de server gaat. Gitolite laat zien welke repositories je toegang toe hebt en welke soort toegang dat dan wel is. Hier is een voorbeeld: + + hello sitaram, the gitolite version here is v1.5.4-19-ga3397d4 + the gitolite config gives you the following access: + R anu-wsd + R entrans + R W git-notes + R W gitolite + R W gitolite-admin + R indic_web_input + R shreelipi_converter + + +**Delegeringen**: Voor extreem grote installaties kan je de verantwoordelijkheid voor groepen van repositories delegeren aan verschilllende mensen en hen het beheer van die delen onafhankelijk laten regelen. Dit vermindert de werkdruk van de hoofd-beheerder, en maakt van hem minder een faalpunt. Deze eigenschap heeft zijn eigen docuentatie bestand in de `doc/` directory. + +**Gitweb ondersteuning**: Gitolite ondersteunt gitweb op verschillende manieren. Je kunt aangeven welke repositories zichtbaar zijn via gitweb. Je kunt de "owner" (eigenaar) en "description" (omschrijving) voor gitweb vanuit de gitolite configuratie bestanden definiëren. Gitweb heeft een mechanisme beschikbaar waarmee toegang via HTTP wordt geïmplementeerd, deze kan je het "gecompileerde" config bestand van de gitolite config file laten gebruiken, wat inhoudt dat gitweb en gitolite dezelfde toegangsregels gebruikt (voor lees toegang). + ## Git Daemon ## -Voor publieke ongeverifieerde leestoegang tot je projecten zul je het HTTP protocol achter je willen laten, en overstappen op het Git protocol. De hoofdreden is snelheid. Het Git protocol is veel efficienter en daarmee sneller dan het HTTP protocol, dus het zal je gebruikers tijd besparen. +Voor publieke ongeauthenticeerde leestoegang tot je projecten zul je het HTTP protocol achter je willen laten, en overstappen op het Git protocol. De belangrijkste reden is snelheid. Het Git protocol is veel efficiënter en daarmee sneller dan het HTTP protocol, dus het zal je gebruikstijd besparen. -Nogmaals, dit is voor ongeverifieerde alleen-lezen toegang. Als je dit op een server buiten je firewall draait, zul je het alleen moeten gebruiken voor projecten die voor de hele wereld toegankelijk moeten zijn. Als de server waarop je het draait binnen je firewall staat, zou je het kunnen gebruiken voor projecten waarbij een groot aantal mensen of computers (continue integratie of bouwservers) alleen-lezen toegang moeten hebben, waarbij je niet voor iedereen een SSH sleutel wilt toevoegen. +Nogmaals, dit is voor ongeauthenticeerde alleen-lezen toegang. Als je dit op een server buiten je firewall draait, zul je het alleen moeten gebruiken voor projecten die voor de hele wereld toegankelijk moeten zijn. Als de server waarop je het draait binnen je firewall staat, zou je het kunnen gebruiken voor projecten waarbij een groot aantal mensen of computers (continue integratie of bouwservers) alleen-lezen toegang moeten hebben, waarbij je niet voor iedereen een SSH sleutel wilt toevoegen. In ieder geval is het Git protocol relatief eenvoudig in te stellen. Eigenlijk is het enige dat je moet doen dit commando een daemon uitvoeren: 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 in 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 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 poort 9418 open moeten zetten op de machine waar je dit op gaat doen. -Je kunt dit proces op een aantal manieren daemonisern, afhankelijk van het besturingssystem waarop je draait. Op een Ubuntu machine, zul je een Upstart script gebruiken. Dus in het volgende bestand +Je kunt dit proces op een aantal manieren daemoniseren, afhankelijk van het besturingssystem waarop je draait. Op een Ubuntu machine, zul je een Upstart script gebruiken. Dus in het volgende bestand /etc/event.d/local-git-daemon @@ -533,18 +709,18 @@ stop je dit script: Omwille van veiligheidsredenen, wordt sterk aangeraden om deze daemon uit te voeren als gebruiker met alleen-lezen toegang op de repositories – je kunt dit makkelijk doen door een gebruiker 'git-ro' aan te maken en de daemon als deze uit te voeren. Om het eenvoudig te houden voeren we het als dezelfde 'git' gebruiker uit, als waarin Gitosis draait. -Als je je machine herstart, zal je Git daemon automatisch opstarten en herstarten als hij onderuit gaat. Om het te laten draaien zonder te herstarten, kun je dit uitvoeren: +Als je de machine herstart, zal de Git daemon automatisch opstarten en herstarten als de server onderuit gaat. Om het te laten draaien zonder te herstarten, kun je dit uitvoeren: initctl start local-git-daemon -Op andere systemen zul je misschien `xinetd` willen gebruiken, een script in je `sysvinit` systeem, of iets anders – zolang je dat commando maar ge-daemoniseerd krijgt en op een of andere manier in de gaten gehouden wordt. +Op andere systemen zul je misschien `xinetd` willen gebruiken, een script in je `sysvinit` systeem, of iets anders – zolang je dat commando maar ge-daemoniseerd krijgt en deze op een of andere manier in de gaten gehouden wordt. -Vervolgens zul je je Gitosis server moeten vertellen welke repositories je ongeverifieerde Gitserver gebaseerde toegang toestaat. Als je een sectie toevoegt voor iedere repository, dan kun je die repositories specificeren waarop je je Git daemon wilt laten lezen. Als je Git protocol toegang tot je iphone project wilt toestaan, dan voeg je dit toe aan het eind van het `gitosis.conf` bestand: +Vervolgens zul je je Gitosis server moeten vertellen welke repositories je onauthenticeerde Gitserver gebaseerde toegang toestaat. Als je een sectie toevoegt voor iedere repository, dan kun je die repositories specificeren waarop je je Git daemon wilt laten lezen. Als je Git protocol toegang tot je iphone project wilt toestaan, dan voeg je dit toe aan het eind van het `gitosis.conf` bestand: [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 gepushed is, dan zou de 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: @@ -570,15 +746,15 @@ Als je nu het project commit en pushed, start GitWeb automatisch met het tonen v ## Hosted Git ## -Als je niet door al het werk heen wilt om je eigen Git server op te zetten, heb je meerdere opties om je Git project op een externe speciale hosting pagina te laten beheren. Dit biedt een aantal voordelen: een ge-hoste pagina is over het algemeen snel in te stellen, en eenvoudig om projecten op te starten, en er komt geen server beheer en onderhoud bij kijken. Zelfs als je je eigen server intern ingesteld hebt, zul je misschien een publieke host pagina voor je open source broncode willen – dat is over het algemeen makkelijker voor de open source commune te vinden en je er mee te helpen. +Als je niet al het werk wilt doen om je eigen Git server op te zetten, heb je meerdere opties om je Git project op een externe speciale hosting pagina te laten beheren. Dit biedt een aantal voordelen: een ge-hoste pagina is over het algemeen snel in te stellen, eenvoudig om projecten mee op te starten, en er komt geen serverbeheer en -onderhoud bij kijken. Zelfs als je je eigen server intern ingesteld hebt, zul je misschien een publieke host pagina voor je open source broncode willen – dat is over het algemeen makkelijker voor de open source commune te vinden en je er mee te helpen. Vandaag de dag heb je een enorm aantal beheer opties om uit te kiezen, elk met verschillende voor- en nadelen. Om een bijgewerkte lijst te zien, ga dan kijken op de GitHosting pagina op de hoofd Git wiki: http://git.or.cz/gitwiki/GitHosting -Omdat we ze niet allemaal kunnen behandelen, en ik toevalllig bij een ervan werk, zullen we deze sectie gebruiken om door het instellen van een account en het opzetten van een project op GitHub lopen. Dit geeft je een idee van het benodigde werk. +Omdat we ze niet allemaal kunnen behandelen, en ik toevallig bij een ervan werk, zullen we deze paragraaf gebruiken het instellen van een account en het opzetten van een project op GitHub te doorlopen. Dit geeft je een idee van het benodigde werk. -GitHub is veruit de grootste open source Git beheer pagina en het is ook een van de weinige die zowel publieke als privé beheer opties biedt, zodat je je open source en commerciele privé code in dezelfde plaats kunt bewaren. Sterker nog, we hebben GitHub gebruikt om privé samen te werken aan dit boek. +GitHub is veruit de grootste open source Git beheer pagina en het is ook een van de weinige die zowel publieke als privé beheer opties biedt, zodat je je open source en commerciele privé code op dezelfde plaats kunt bewaren. Sterker nog, we hebben GitHub gebruikt om privé samen te werken aan dit boek. ### GitHub ### From 3c88842bacda30ab45b03d31468b922283ddc3c9 Mon Sep 17 00:00:00 2001 From: Gabor Maghera Date: Fri, 17 Jan 2014 10:29:39 -0800 Subject: [PATCH 111/690] Update 01-chapter1.markdown --- hu/01-introduction/01-chapter1.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hu/01-introduction/01-chapter1.markdown b/hu/01-introduction/01-chapter1.markdown index d05aca1fc..8bb5f20d7 100644 --- a/hu/01-introduction/01-chapter1.markdown +++ b/hu/01-introduction/01-chapter1.markdown @@ -8,7 +8,7 @@ Mi az a verziókövetés, és miért kellene vele törődnünk? A verziókövet Ha grafikus vagy webdizájner vagy és meg akarod tartani az összes verzióját egy képnek vagy egy weboldal tervezetnek (amit mindenképp szeretnél), egy Verziókövető Rendszer (VR) legalkalmasabb dolog a feladatra. Lehetővé teszi fájlok visszaálítást egy előző verzióra, a teljes projekt visszaállítását egy előző verzióra, változatok összehasonlítását bármely idő intervalimra, rájöhetsz miért okoz az utolsó módsításod problémát, hogyan keletkezik egy esemény és miért és így tovább. A VR használata az is jelenti ha elrontasz valamit vagy elveszne egy fájl könnyedén visszavonhatod minimális erőforrás ráfordítással. -### Egyéni verziókövető rendszerk ### +### Egyéni verziókövető rendszerek ### Sok ember választja verziókövető megoldásnak a fájlok különböző mappákba másolását (mappák neve egy időbélyeg ha értelmesen csinálják). Ez a legkönnyebben befogadható megoldás mert egyszerű, de hihetetlenül könnyű hibázni. Elfelejtik hogy melyik mappában vannak rossz fájlt írnak vagy írnakfelül olyat amit nem kellett volna. From 870cfed1f03ebc08b3ec874a0d4ae93c99d47f5f Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Fri, 17 Jan 2014 19:53:43 -0600 Subject: [PATCH 112/690] Fixed "Hosted Git" Title In italiano usiamo "hosting" o "host" --- it/04-git-server/01-chapter4.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/04-git-server/01-chapter4.markdown b/it/04-git-server/01-chapter4.markdown index af62c8b8a..7855e5c8e 100644 --- a/it/04-git-server/01-chapter4.markdown +++ b/it/04-git-server/01-chapter4.markdown @@ -716,7 +716,7 @@ Puoi controllare quali progetti GitWeb lascia sfogliare agli utenti via browser Ora, se fai il commit ed il push del progetto, GitWeb automaticamente inizierà a mostrare il progetto iphone. -## Hosted Git ## +## Hosting Git ## Se non vuoi svolgere tutto il lavoro di configurazione di un tuo server Git, hai varie opzioni per ospitare i tuoi progetti Git su un sito esterno e dedicato. Fare questo offre un numero di vantaggi: un sito di hosting è generalmente veloce da configurare ed è facile avviare un progetto su questo, e non sono necessari spese di mantenimento o controllo del server. Se imposti e avvi il tuo server interno, puoi comunque voler utilizzare un hosting pubblico per i progetti a codice aperto — è generalmente più facile per una comunità open source trovarti ed aiutarti. From 314c389e402c0a0bb952f40f7a0f99987f8939b3 Mon Sep 17 00:00:00 2001 From: "Ann + J.M" Date: Wed, 15 Jan 2014 21:59:51 +0100 Subject: [PATCH 113/690] [de] Enhance section 9 --- de/09-git-internals/01-chapter9.markdown | 302 +++++++++++------------ 1 file changed, 151 insertions(+), 151 deletions(-) diff --git a/de/09-git-internals/01-chapter9.markdown b/de/09-git-internals/01-chapter9.markdown index dbbaa1196..d17dafdbc 100644 --- a/de/09-git-internals/01-chapter9.markdown +++ b/de/09-git-internals/01-chapter9.markdown @@ -1,36 +1,36 @@ -# Git Internas # +# Git Interna # -Möglicherweise hast Du dieses Kapitel hier direkt aufgeschlagen, vorherige Kapitel ausgelassen, oder bist hierher gelangt, nachdem Du alle vorherigen Kapitel gelesen hast. Wie auch immer, in diesem Kapitel wirst Du mit mit den internen (xxx) und der Implementation von Git befassen. Meine eigene Erfahrung damit, diese Dinge zu lernen, war dass sie unerlässlich ist, um zu verstehen, wie unheimlich mächtig und flexibel Git ist. Allerdings gibt es Leute, die der Ansicht sind, dass sie auch verwirrend und unnötig komplex für Anfänger sein könne. Deshalb habe ich mich entschieden, dieses Kapitel an das Ende des Buches zu verlegen. Du kannst es, ganz wie es Dir beliebt, früher oder später einschieben. +Möglicherweise hast Du dieses Kapitel hier direkt aufgeschlagen, vorherige Kapitel ausgelassen, oder bist hierher gelangt, nachdem Du alle vorherigen Kapitel gelesen hast. Wie auch immer, in diesem Kapitel wirst Du mit mit der internen Funktionsweise und der Implementierung von Git befassen. Meine eigene Erfahrung ist, dass das Lernen dieser Dinge unerlässlich ist, um zu verstehen, wie unheimlich mächtig und flexibel Git ist. Allerdings gibt es Leute, die der Ansicht sind, dass sie auch verwirrend und unnötig komplex für Anfänger sein können. Deshalb habe ich mich entschieden, dieses Kapitel an das Ende des Buches zu verlegen. Du kannst es, ganz wie es Dir beliebt, früher oder später einschieben. -Lass uns also loslegen. Zunächst will ich betonen, falls das bisher noch nicht klargeworden ist, dass Git im seinen Grundzügen ein Dateisystem ist, dessen Inhalte addressierbar sind (xxx content-addressable filesystem ??? xxx) und auf dem ein VCS Interface sitzt. Wir werden gleich genauer darauf eingehen, was das heißt. +Lass uns also loslegen. Zunächst will ich betonen, falls das bisher noch nicht klargeworden ist, dass Git im seinen Grundzügen ein Dateisystem ist, dessen Inhalte addressierbar sind und auf dem ein VCS-Interface aufgesetzt ist. Wir werden gleich genauer darauf eingehen, was das heißt. -In den frühen Tagen von Git (d.h. vor der Version 1.5.) war das Interface sehr viel komplexer, weil es diese Dateisystem Eigenschaften stark betonte – im Gegensatz zu einem ausgearbeiteten VCS. In den letzten Jahren wurde das Interface dann stückweise verbessert und verfeinert, sodass es heute so einfach verständlich und einfach zu verwenden ist, wie alle möglichen vergleichbaren Systeme, die es gibt. Allerdings besteht scheinbar weiterhin das Vorurteil, dass das Git Interface komplex und schwer zu erlernen sei. +In den frühen Tagen von Git (d.h. vor Version 1.5) war das Interface sehr viel komplexer, weil es diese Dateisystem-Eigenschaften stark betonte – im Gegensatz zu einem ausgearbeiteten VCS. In den letzten Jahren wurde das Interface dann stückweise verbessert und verfeinert, sodass es heute so einfach verständlich und einfach zu verwenden ist, wie alle möglichen vergleichbaren Systeme, die es gibt. Allerdings besteht scheinbar weiterhin das Vorurteil, das Git-Interface sei komplex und schwer zu erlernen. -Die Dateisystem Ebene ist erstaunlich cool, weshalb ich in diesem Kapitel zuerst darauf eingehen werde. Als nächstes lernst Du etwas über die Transport Mechanismen und Repository Wartungsaufgaben, mit denen Du möglicherweise irgendwann zu tun bekommen wirst. +Die inhaltsbasiert adressierbare Dateisystem-Ebene ist erstaunlich cool, weshalb ich in diesem Kapitel zuerst darauf eingehen werde. Als Nächstes lernst Du etwas über die Transport-Mechanismen und Repository-Wartungsaufgaben, mit denen Du möglicherweise irgendwann zu tun bekommen wirst. ## Plumbing und Porcelain ## -In diesem Buch haben wir Git besprochen, indem wir vielleicht 30 Befehle wie `checkout`, `branch`, `remote` und so weiter verwendet haben. Weil Git aber ursprünglich als ein Werkzeugkasten konzipiert war, un nicht so sehr als ein komplettes, anwenderfreundliches VCS, gibt es auch eine Reihe von Befehlen, die ihre Arbeit auf einer sehr viel grundlegenderen Ebene verrichten. Viele davon sind ursprünglich entwickelt worden, um als UNIX Befehle miteinander verkettet zu werden oder aus Scripten heraus aufgerufen zu werden. Diese Befehle werden oft als „plumbing“ (xxx) Befehle zusammengefasst, während die eher anwenderfreundlichen Befehle „porcelain“ (d.h. Porzellan) genannt werden. +In diesem Buch haben wir Git besprochen, indem wir vielleicht 30 Befehle wie `checkout`, `branch`, `remote` und so weiter verwendet haben. Weil Git aber ursprünglich als ein Werkzeugkasten konzipiert war und nicht so sehr als ein komplettes, anwenderfreundliches VCS, gibt es auch eine Reihe von Befehlen, die ihre Arbeit auf einer sehr viel grundlegenderen Ebene verrichten. Viele davon sind ursprünglich entwickelt worden, um als UNIX-Befehle miteinander verkettet zu werden oder aus Skripten heraus aufgerufen zu werden. Diese Befehle werden oft als „plumbing“-Befehle (Klempner-Befehle) zusammengefasst, während die eher anwenderfreundlichen Befehle „porcelain“ (d.h. Porzellan) genannt werden. -Die ersten acht Kapitel dieses Buches haben sich fast ausschließlich mit „porcelain“ Befehlen befasst. In diesem Kapitel gehen wir dagegen auf die zugrundeliegenden „plumbing“ Befehle ein, u.a. weil sie Dir den Zugriff auf Gits innere Abläufe ermöglichen, und weil sie dabei helfen, zu verstehen, warum Git tut, was es tut. Diese Befehle sind nicht unbedingt dazu bestimmt direkt (xxx on the command line xxx) ausgeführt zu werden, sondern sind als Bausteine für Werkzeuge und Scripts gemeint. +Die ersten acht Kapitel dieses Buches haben sich fast ausschließlich mit „Porcelain“-Befehlen befasst. In diesem Kapitel gehen wir dagegen auf die zugrundeliegenden „Plumbing“-Befehle ein, u.a. weil sie Dir den Zugriff auf die inneren Abläufe von Git ermöglichen, und weil sie dabei helfen, zu verstehen, warum Git tut, was es tut. Diese Befehle sind nicht dazu gedacht, manuell in der Eingabeaufforderung ausgeführt zu werden, sondern sind als Bausteine für Werkzeuge und Skripts gemeint. -Wenn Du `git init` in einem neuen oder bereits bestehenden Verzeichnis ausführst, erzeugt Git das `.git` Verzeichnis, das fast alle Dateien enthält, die Git intern speichert und ändert. Wenn Du eine Sicherheitskopie Deines Repositories anlegen oder es duplizieren willst, dann reicht aus, dieses Verzeichnis zu kopieren. Dieses ganze Kapitel handelt praktisch nur von den Inhalten dieses Verzeichnisses – die so aussehen: +Wenn Du `git init` in einem neuen oder bereits bestehenden Verzeichnis ausführst, erzeugt Git das `.git`-Verzeichnis, das fast alle Dateien enthält, die Git intern speichert und ändert. Wenn Du eine Sicherheitskopie Deines Repositorys anlegen oder es duplizieren willst, dann reicht aus, dieses Verzeichnis zu kopieren. Dieses ganze Kapitel handelt praktisch nur von den Inhalten dieses Verzeichnisses – die so aussehen: $ ls HEAD @@ -45,11 +45,11 @@ Wenn Du `git init` in einem neuen oder bereits bestehenden Verzeichnis ausführs -Möglicherweise findest Du darin weitere Dateien. Obiges stammt aus einem mit `git init` neuangelegten Repository – das sind also die Standardinhalte. Der Ordner `branches` wird von neueren Git Versionen nicht mehr verwendet, und die Datei `descriptions` wird nur vom Programm GitWeb benötigt. Du kannst sie also ignorieren. Die Datei `config` enthält Deine Projekt-spezifischen Konfigurationsoptionen, und im Ordner `info` befindet sich eine Datei, die globale Dateiausschlusspatterns (xxx) enthält, die Du nicht in jeder .gitignore Datei neu spezifizieren willst. Das `hooks` Verzeichnis enthält die client- oder serverseitigen Hook Scripte, die wir in Kapitel 7 besprochen haben. +Möglicherweise findest Du darin weitere Dateien. Obiges stammt aus einem mit `git init` neu angelegten Repository – das sind also die Standardinhalte. Der Ordner `branches` wird von neueren Git-Versionen nicht mehr verwendet, und die Datei `descriptions` wird nur vom Programm GitWeb benötigt. Du kannst sie also ignorieren. Die Datei `config` enthält Deine projekt-spezifischen Konfigurationsoptionen, und im Ordner `info` befindet sich eine Datei, die globale Dateiausschlussmuster enthält, die Du nicht in jeder .gitignore-Datei neu spezifizieren willst. Das `hooks`-Verzeichnis enthält die client- oder serverseitigen Hook-Skripte, die wir in Kapitel 7 besprochen haben. -Damit bleiben vier wichtige Einträge übrig: die Dateien `HEAD` und `index` und die Verzeichnisse `objects` und `refs`. Dies sind die Kernkomponenten eines Git Repositories: Im `objects` Verzeichnis befinden sich die Inhalte der Datenbank. Das `refs` Verzeichnis enthält Referenzen auf Commit Objekte (Branches) in dieser Datenbank. Die Datei `HEAD` zeigt auf denjeningen Branch, den Du gegenwärtig ausgecheckt hast, und in der Datei `index` verwaltet Git die Informationen der Staging Area. Wir werden auf diese Elemente jetzt im einzelnen darauf eingehen, sodass Du nachvollziehen kannst, wie Git intern arbeitet. +Damit bleiben vier wichtige Einträge übrig: die Dateien `HEAD` und `index` und die Verzeichnisse `objects` und `refs`. Dies sind die Kernkomponenten eines Git-Repositorys: Im `objects`-Verzeichnis befinden sich die Inhalte der Datenbank. Das `refs`-Verzeichnis enthält Referenzen auf Commit-Objekte (Branches) in dieser Datenbank. Die Datei `HEAD` zeigt auf denjeningen Branch, den Du gegenwärtig ausgecheckt hast, und in der Datei `index` verwaltet Git die Informationen der Staging-Area. Wir werden auf diese Elemente jetzt im einzelnen darauf eingehen, sodass Du nachvollziehen kannst, wie Git intern arbeitet. ## Git Objekte ## @@ -57,7 +57,7 @@ Damit bleiben vier wichtige Einträge übrig: die Dateien `HEAD` und `index` und -Git ist ein Dateisystem, das Inhalte addressieren kann. Prima. Aber was heißt das? Es bedeutet, dass Git im Kern nichts anderes ist als ein einfacher Key-Value-Store („Schlüssel-Wert-Speicher“). Du kannst darin jede Art von Inhalt ablegen und Git wird einen Schlüssel dafür zurückgeben, den Du dann verwenden kannst, um diesen Inhalt jederzeit nachzuschlagen. Um das auszuprobieren, kannst Du den Plumbing Befehl `hash-object` verwenden. Dieser nimmt einen Inhalt an, speichert ihn in Deinem `.git` Verzeichnis und gibt Dir den Schlüssel zurück, unter dem der Inhalt gespeichert wurde. Dazu initialisierst Du als erstes ein neues Git Repository und verifizierst, dass das `objects` Verzeichnis leer ist: +Git ist ein Dateisystem, das Inhalte addressieren kann. Prima. Aber was heißt das? Es bedeutet, dass Git im Kern nichts anderes ist als ein einfacher Key-Value-Store („Schlüssel-Wert-Speicher“). Du kannst darin jede Art von Inhalt ablegen und Git wird einen Schlüssel dafür zurückgeben, den Du dann verwenden kannst, um diesen Inhalt jederzeit nachzuschlagen. Um das auszuprobieren, kannst Du den Plumbing-Befehl `hash-object` verwenden. Dieser nimmt einen Inhalt an, speichert ihn in Deinem `.git`-Verzeichnis und gibt Dir den Schlüssel zurück, unter dem der Inhalt gespeichert wurde. Dazu initialisierst Du als erstes ein neues Git-Repository und verifizierst, dass das `objects`-Verzeichnis leer ist: $ mkdir test $ cd test @@ -72,32 +72,32 @@ Git ist ein Dateisystem, das Inhalte addressieren kann. Prima. Aber was heißt d -Git hat also ein Verzeichnis `objects` und darin die `pack` und `info` Unterverzeichnisse angelegt, bisher aber keine weiteren Dateien. Als nächsten speichern wir einen Text in dieser Git Datenbank: +Git hat also ein Verzeichnis `objects` und darin die Unterverzeichnisse `pack` und `info` angelegt, bisher aber keine weiteren Dateien. Als nächsten speichern wir einen Text in dieser Git-Datenbank: $ echo 'test content' | git hash-object -w --stdin d670460b4b4aece5915caf5c68d12f560a9fe3e4 -Die Option `-w` weist `git hash-object` an, das Objekt zu speichern. Andernfalls würde Dir der Befehl lediglich den Schlüssel mitteilen. `--stdin` weist den Befehl an, den Inhalt von aus der Standardeingabe zu lesen. Wenn Du diese Option weglässt, erwartet der Befehl zusätzlich einen Dateipfad. Die Ausgabe ist eine 40 Zeichen langer SHA-1 Hash, der eine Prüfsumme des gespeicherten Inhaltes darstellt (wir gehen auf diese Hashes gleich noch genauer ein). Git hat jetzt außerdem eine neue Datei in der Datenbank angelegt: +Die Option `-w` weist `git hash-object` an, das Objekt zu speichern. Andernfalls würde Dir der Befehl lediglich den Schlüssel mitteilen. `--stdin` weist den Befehl an, den Inhalt von aus der Standardeingabe zu lesen. Wenn Du diese Option weglässt, erwartet der Befehl zusätzlich einen Dateipfad. Die Ausgabe ist eine 40 Zeichen langer SHA-1-Hash, der eine Prüfsumme des gespeicherten Inhaltes darstellt (wir gehen auf diese Hashes gleich noch genauer ein). Git hat jetzt außerdem eine neue Datei in der Datenbank angelegt: $ find .git/objects -type f .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 -D.h., im `objects` Verzeichnis befindet sich genau eine Datei. Auf diese Weise Git speichert Inhalte (xxx wieso initially? xxx): in jeweils einer Datei pro Inhalt, referenziert durch den SHA-1 Hash des Inhaltes und seines Headers (xxx Kopfdaten? xxx). Der Name des Unterverzeichnis `d6` sind die ersten zwei Zeichen des SHA-1 Hashes und der Dateiname die verbleibenden 38 Zeichen. +Du siehst im `objects` Verzeichnis genau eine Datei. Auf diese Weise Git speichert Inhalte anfänglich: in jeweils einer Datei pro Inhalt, referenziert durch den SHA-1-Hash des Inhaltes und seiner Kopfzeile. Der Name des Unterverzeichnis `d6` sind die ersten zwei Zeichen des SHA-1-Hashes und der Dateiname die verbleibenden 38 Zeichen. -Mit dem Befehl `git cat-file` kannst Du den jeweiligen Inhalt nachschlagen. Dieser Befehl ist so etwas wie ein Schweizer Taschenmesser, wenn es um Objekte in der Git Datenbank geht. Wenn Du die Option `-p` übergibst, versucht `git cat-file`, die Art des Inhaltes (z.B. den Dateitypen xxx) herauszufinden und die Anzeige entsprechend lesbar zu formatieren: +Mit dem Befehl `git cat-file` kannst Du den jeweiligen Inhalt nachschlagen. Dieser Befehl ist so etwas wie ein Schweizer Taschenmesser, wenn es um Objekte in der Git-Datenbank geht. Wenn Du die Option `-p` übergibst, versucht `git cat-file`, die Art des Inhaltes herauszufinden und die Anzeige entsprechend lesbar zu formatieren: $ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4 test content -Auf diese Weise kannst Du also Inhalte zur Datenbank hinzufügen und von dort wieder nachschlagen. Wenn Du beispielsweise eine einzelne Datei versionskontrollieren willst, kannst Du zunächst die Datei anlegen und den Inhalt in der Datenbank speichern: +Auf diese Weise kannst Du also Inhalte zu Git hinzufügen und von dort wieder nachschlagen. Das klappt auch mit Dateiinhalten. Wenn Du beispielsweise eine einzelne Datei versionskontrollieren willst, lege die Datei zunächst an und speichere ihren Inhalt in der Datenbank: $ echo 'version 1' > test.txt $ git hash-object -w test.txt @@ -113,7 +113,7 @@ Dann kannst Du Änderungen vornehmen und die Datei erneut speichern: -Die Datenbank enthält jetzt zwei weitere Versionen der Datei neben dem ursprünglich gespeicherten Inhalt (xxx): +Die Datenbank enthält jetzt zwei weitere Versionen der Datei neben dem ursprünglich gespeicherten Inhalt: $ find .git/objects -type f .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a @@ -138,17 +138,17 @@ Oder die zweite Version: -Sich den SHA-1 Hash für jede Version merken zu müssen, ist allerdings nicht sonderlich praktisch. Außerdem speicherst Du nicht den Dateinamen in der Datenbank, sondern lediglich den Inhalt der Datei. Ein solcher Objekttyp wird als „Blob“ bezeichnet. Mit `git cat-file -t` kannst Du Git nach dem Typ eines Objektes in der Datenbank fragen: +Sich den SHA-1-Hash für jede Version merken zu müssen, ist allerdings nicht sonderlich praktisch. Außerdem speicherst Du nicht den Dateinamen in der Datenbank, sondern lediglich den Inhalt der Datei. Ein solcher Objekttyp wird als „Blob“ bezeichnet. Mit `git cat-file -t` kannst Du Git nach dem Typ eines Objektes in der Datenbank fragen: $ git cat-file -t 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a blob -### Baum Objekte ### +### Baum-Objekte ### -Als nächstes schauen wir uns den Objekttyp „Tree“ (Baum) an, der es ermöglicht, Dateinamen zu speichern und Dateien zu gruppieren. Git speichert Inhalte in einer ähnlichen Weise wie das UNIX Dateisystem, allerdings ein bisschen vereinfacht. Sie werden als Tree und Blob Objekte abgelegt, wobei die Trees mit UNIX Verzeichnis Einträgen korrespondieren und Blobs mehr oder weniger mit den inode Einträgen bzw. Datei Inhalten. Ein einzelnes Baum Objekt enthält einen oder mehrere Einträge, von denen jeder ein SHA-1 Hash ist, der wiederum einen Blob oder einen Untertree referenziert. Jeder dieser Einträge verfügt außerdem über einen Modus, Typ und Dateinamen. Beispielsweise sieht das aktuelle Tree Objekt im simplegit Projekt möglicherweise so aus: +Als Nächstes schauen wir uns den Objekttyp „Tree“ (Baum) an, der es ermöglicht, Dateinamen zu speichern und Dateien zu gruppieren. Git speichert Inhalte in einer ähnlichen Weise wie das UNIX-Dateisystem, allerdings ein bisschen vereinfacht. Sie werden als Tree- und Blob-Objekte abgelegt, wobei die Trees mit UNIX-Verzeichnis-Einträgen korrespondieren und Blobs mehr oder weniger mit den inode-Einträgen bzw. Datei-Inhalten. Ein einzelnes Baum-Objekt enthält einen oder mehrere Einträge, von denen jeder ein SHA-1-Hash ist, der wiederum einen Blob oder einen Untertree referenziert. Jeder dieser Einträge verfügt außerdem über einen Modus, Typ und Dateinamen. Beispielsweise sieht das aktuelle Tree-Objekt im simplegit-Projekt möglicherweise so aus: $ git cat-file -p master^{tree} 100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README @@ -157,7 +157,7 @@ Als nächstes schauen wir uns den Objekttyp „Tree“ (Baum) an, der es ermögl -Die `master^{tree}` Syntax spezifiziert, dass wir an dem Tree Objekt interessiert sind, auf das der letzte Commit des `master` Branches zeigt. Beachte, dass das `lib` Unterverzeichnis nicht auf ein Blob, sondern wiederum auf einen weiteren Baum zeigt. +Die `master^{tree}`-Syntax spezifiziert, dass wir an dem Tree-Objekt interessiert sind, auf das der letzte Commit des `master`-Branches zeigt. Beachte, dass das Unterverzeichnis `lib` nicht auf ein Blob, sondern wiederum auf einen weiteren Baum zeigt. $ git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 100644 blob 47c6340d6459e05787f644c2447d2595f5d3a54b simplegit.rb @@ -169,22 +169,22 @@ Git speichert Daten also, konzeptuell gesehen, in etwa wie in Bild 9-1 dargestel Insert 18333fig0901.png -Bild 9-1. Vereinfachte Darstellung des Git Datenmodels. +Bild 9-1. Vereinfachte Darstellung des Git-Datenmodels. -Du kannst auch Deine eigenen Tree Objekte anlegen. Git erzeugt Trees normalerweise, indem es die Inhalte der Staging Area nimmt und als ein Tree Objekt speichert. D.h., um ein Tree Objekt anzulegen, musst Du zunächst einen Index (d.h. eine Staging Area) erzeugen, indem Du einige Dateien hinzufügst. Um einen einzelnen Eintrag in den Index zu schreiben – z.B. die erste version der test.txt Datei – kannst Du den Plumbing Befehl `git update-index` verwenden, der eine frühere Version dieser Datei künstlich zu einer neuen Staging Area hinzufügt. Du musst ihm die `--add` Option übergeben, weil die Datei bisher noch nicht in der Staging Area enthalten ist (Du hast ja bisher noch überhaupt keine Staging Area aufgesetzt), und die `--cacheinfo` Option, weil Du eine Datei hinzufügst, die sich nicht in Deinem Arbeitsverzeichnis befindet (xxx hu? xxx), sondern in der Datenbank. Du gibst außerdem den Modus, SHA-1 Hash und den Dateinamen an: +Du kannst auch Deine eigenen Tree-Objekte anlegen. Git erzeugt Trees normalerweise, indem es die Inhalte der Staging-Area nimmt und als ein Tree-Objekt speichert. D.h., um ein Tree-Objekt anzulegen, musst Du zunächst einen Index (d.h. eine Staging-Area) erzeugen, indem Du einige Dateien hinzufügst. Um einen einzelnen Eintrag in den Index zu schreiben – z.B. die erste version der Datei test.txt – kannst Du den Plumbing-Befehl `git update-index` verwenden, der eine frühere Version dieser Datei künstlich zu einer neuen Staging-Area hinzufügt. Du musst ihm die Option `--add` übergeben, weil die Datei bisher noch nicht in der Staging-Area enthalten ist (Du hast ja bisher noch überhaupt keine Staging-Area aufgesetzt), und die Option `--cacheinfo`, weil Du eine Datei hinzufügst, die sich nicht in Deinem Verzeichnis befindet, sondern in der Datenbank. Du gibst außerdem den Modus, SHA-1-Hash und den Dateinamen an: $ git update-index --add --cacheinfo 100644 \ 83baae61804e65cc73a7201a7252750c76066a30 test.txt -In diesem Fall gibst Du als Modus `100644` an, was bedeutet, dass es sich um eine normale Date handelt. Eine ausführbare Datei wäre dagegen `100755` und ein symbolischer Link `120000`. Der Modus entspricht normalen UNIX Datei Modi, ist aber weniger flexibel. Die drei genannten Modi sind die einzigen, die in in Git für Dateien (blobs) verwendet werden (es gibt allerdings noch weitere Modi für Verzeichnisse und Submodule xxx). +In diesem Fall gibst Du als Modus `100644` an, was bedeutet, dass es sich um eine normale Datei handelt. Eine ausführbare Datei wäre dagegen `100755` und ein symbolischer Link `120000`. Der Modus entspricht normalen UNIX-Datei-Modi, ist aber weniger flexibel. Die drei genannten Modi sind die einzigen, die in Git für Dateien (Blobs) verwendet werden (es gibt allerdings noch weitere Modi für Verzeichnisse und Submodule). -Jetzt kannst Du den Befehl `git write-tree` verwenden, um die Staging Area als Tree Objekt zu schreiben. Dazu brauchst Du die `-w` Option nicht angeben – `git write-tree` schreibt automatisch ein Tree Objekt für Einträge der Staging Area, für die es noch keinen Tree gibt: +Jetzt kannst Du den Befehl `git write-tree` verwenden, um die Staging-Area als Tree-Objekt zu schreiben. Dazu brauchst Du die `-w` Option nicht angeben – `git write-tree` schreibt automatisch ein Tree-Objekt für Einträge der Staging-Area, für die es noch keinen Tree gibt: $ git write-tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579 @@ -193,14 +193,14 @@ Jetzt kannst Du den Befehl `git write-tree` verwenden, um die Staging Area als T -Um zu überprüfen, dass es wirklich ein Tree Objekt gibt: +Um zu überprüfen, dass es wirklich ein Tree-Objekt gibt: $ git cat-file -t d8329fc1cc938780ffdd9f94e0d364e0ea74f579 tree -Jetzt erzeugen wir einen neuen Tree mit der zweiten Version der test.txt Datei sowie eine neue Datei: +Jetzt erzeugen wir einen neuen Tree mit der zweiten Version der Datei test.txt sowie eine neue Datei: $ echo 'new file' > new.txt $ git update-index test.txt @@ -208,7 +208,7 @@ Jetzt erzeugen wir einen neuen Tree mit der zweiten Version der test.txt Datei s -Die Staging Area enthält jetzt eine neue Version der test.txt Datei sowie die neue Datei new.txt. Speichern wir diesen Tree (d.h. den gegenwärtigen Status der Staging Area bzw. des Index als Tree Objekt) und schauen ihn uns an: +Die Staging-Area enthält jetzt eine neue Version der Datei test.txt sowie die neue Datei new.txt. Speichern wir diesen Tree (d.h. den gegenwärtigen Status der Staging-Area bzw. des Index als Tree-Objekt) und schauen ihn uns an: $ git write-tree 0155eb4229851634a0f03eb265b69f5a2d56f341 @@ -218,7 +218,7 @@ Die Staging Area enthält jetzt eine neue Version der test.txt Datei sowie die n -Beachte, dass das Tree Objekt zwei Datei Einträge hat und dass der SHA-1 Hash der test.txt Datei noch derselbe „Version 2“ Hash ist wie zuvor (`1f7a7a`). Fügen wir jetzt den ersten Tree als ein Unterverzeichnis is diesem hier ein. Du kannst einen Tree mit `git read-tree` in die Staging Area einlesen. In diesem Fall können wir einen bereits existierenden Tree als einen Untertree zur Staging Area hinzufügen, indem wir die `--prefix` Option verwenden: +Beachte, dass das Tree-Objekt zwei Datei-Einträge hat und dass der SHA-1-Hash der Datei test.txt noch derselbe „Version 2“-Hash ist wie zuvor (`1f7a7a`). Fügen wir jetzt den ersten Tree als ein Unterverzeichnis in diesem hier ein. Du kannst einen Tree mit `git read-tree` in die Staging-Area einlesen. In diesem Fall können wir einen bereits existierenden Tree als einen Untertree zur Staging-Area hinzufügen, indem wir die Option `--prefix` verwenden: $ git read-tree --prefix=bak d8329fc1cc938780ffdd9f94e0d364e0ea74f579 $ git write-tree @@ -230,23 +230,23 @@ Beachte, dass das Tree Objekt zwei Datei Einträge hat und dass der SHA-1 Hash d -Wenn Du ein Arbeitsverzeichnis aus diesem neuen Tree Objekt auschecken würdest, würdest Du zwei Dateien im Hauptverzeichnis und ein Unterverzeichnis mit dem Namen `bak` erhalten, in dem sich die erste Version der Datei test.txt befindet. Du kannst Dir die Daten, die Git für diese Strukturen speichert, in etwa wie in Bild 9-2 vorstellen. +Wenn Du ein Arbeitsverzeichnis aus diesem neuen Tree-Objekt auschecken würdest, würdest Du zwei Dateien im Hauptverzeichnis und ein Unterverzeichnis mit dem Namen `bak` erhalten, in dem sich die erste Version der Datei test.txt befindet. Du kannst Dir die Daten, die Git für diese Strukturen speichert, in etwa wie in Bild 9-2 vorstellen. Insert 18333fig0902.png -Bild 9-2. Die Datenstruktur des gegenwärtigen Git Repositories. +Bild 9-2. Die Datenstruktur des gegenwärtigen Git-Repositorys. ### Objekte committen ### -Du hast jetzt drei Trees, die verschiedene Snapshots Deines Projektes spezifizieren (xxx), die Du nachverfolgen willst. Das ursprüngliche Problem besteht aber weiterhin: Du musst alle drei SHA-1 Hash Werte erinnern, um wieder an die Snapshots zu kommen. Ebenso fehlen Dir die Informationen darüber, wer die Snapshots gespeichert hat, wann sie gespeichert wurden und warum. Dies sind die drei Hauptinformationen, die ein Commit Objekt für uns speichert. +Du hast jetzt drei Trees, die verschiedene Snapshots Deines Projektes spezifizieren, die Du nachverfolgen willst. Das ursprüngliche Problem besteht aber weiterhin: Du musst dir alle drei SHA-1-Hashwerte merken, um wieder an die Snapshots zu kommen. Ebenso fehlen Dir die Informationen darüber, wer die Snapshots gespeichert hat, wann sie gespeichert wurden und warum. Dies sind die drei Hauptinformationen, die ein Commit-Objekt für uns speichert. -Um ein Commit Objekt anzulegen, verwendest Du den Befehl `git commit-tree`, spezifizierst einen einzelnen Tree SHA-1 Hash und welche Commit Objekte (sofern vorhanden) die direkten Vorgänger sind. Fangen wir damit an, den ersten Tree, den Du angelegt hast, zu committen: +Um ein Commit-Objekt anzulegen, verwendest Du den Befehl `git commit-tree`, spezifizierst den SHA-1-Hash eines einzelnen Trees und welche Commit-Objekte (sofern vorhanden) die direkten Vorgänger sind. Fangen wir damit an, den ersten Tree, den Du angelegt hast, zu committen: $ echo 'first commit' | git commit-tree d8329f fdf4fc3344e67ab068f836878b6c4951e3b15f3d @@ -264,11 +264,11 @@ Du kannst diesen Commit jetzt mit `git cat-file` nachschlagen: -Das Format für ein Commit Objekt ist einfach: es besteht aus dem toplevel Tree für den Snapshot des Projektes zum gegebenen Zeitpunkt, die Autor und ggf. Committer Information (jeweils entsprechend Deiner `user.name` und `user.email` Konfiguration) und dem Timestamp. Dann folgen eine leere Zeile und die Commit Meldung. +Das Format für ein Commit-Objekt ist einfach: es besteht aus dem obersten Tree für den Snapshot des Projektes zum gegebenen Zeitpunkt, die Autoren- und ggf. Committer-Information (jeweils entsprechend Deiner `user.name`- und `user.email`-Konfiguration) und dem Timestamp. Dann folgen eine leere Zeile und die Commit-Meldung. -Als nächstes speichern wir die beiden anderen Commit Objekte und referenzieren jeweils den vorhergehenden Commit: +Als Nächstes speichern wir die beiden anderen Commit-Objekte und referenzieren jeweils den vorhergehenden Commit: $ echo 'second commit' | git commit-tree 0155eb -p fdf4fc3 cac0cab538b970a37ea1e769cbbde608743bc96d @@ -277,7 +277,7 @@ Als nächstes speichern wir die beiden anderen Commit Objekte und referenzieren -Jedes der drei Commit Objekte zeigt auf einen der drei Snapshopt Trees, die Du zuvor gespeichert hattest. Es mag Dich überraschen, aber Du hast jetzt bereits eine vollständige Git Historie, die Du mit dem `git log` inspizieren kannst, indem Du den letzten Commit SHA-1 Hash angibst: +Jedes der drei Commit-Objekte zeigt auf einen der drei Snapshot-Trees, die Du zuvor gespeichert hattest. Es mag Dich überraschen, aber Du hast jetzt bereits eine vollständige Git-Historie, die Du mit dem `git log` inspizieren kannst, indem Du den SHA-1-Hash des letzten Commits angibst: $ git log --stat 1a410e commit 1a410efbd13591db07496601ebc7a059dd55cfe9 @@ -310,7 +310,7 @@ Jedes der drei Commit Objekte zeigt auf einen der drei Snapshopt Trees, die Du z -Fantastisch, oder? Du hast jetzt sämtliche low-level Operationen durchgeführt, die eine vollständige Git Historie aufbauen, ohne aber irgendwelche Git Frontend Befehle (xxx) zu verwenden. Im wesentlichen ist das derselbe Prozess, der im Hintergrund stattfindet, wenn Du die Befehle `git add` und `git commit` ausführst. Sie speichern Blobs für die Dateien, die Du hinzugefügt oder geändert hast, aktualisieren den Index (d.h. die Staging Area), speichern Trees und legen Commit Objekte an, die die toplevel Trees und Commits referenzieren, die ihnen unmittelbar vorhergingen. Diese drei Hauptobjekte – Blob, Tree und Commit – werden zunächst als separate Dateien im `.git/objects` Verzeichnis gespeichert. Hier ist eine Liste aller Objekte, die sich in unserem Beispiel Repository jetzt in der Datenbank befinden – jeweils mit einem Kommentar darüber, was sie speichern: +Fantastisch, oder? Du hast jetzt sämtliche Low-Level-Operationen durchgeführt, die eine vollständige Git-Historie aufbauen, ohne aber irgendwelche Frontend-Befehle von Git zu verwenden. Im Wesentlichen ist das derselbe Prozess, der im Hintergrund stattfindet, wenn Du die Befehle `git add` und `git commit` ausführst. Sie speichern Blobs für die Dateien, die Du hinzugefügt oder geändert hast, aktualisieren den Index (d.h. die Staging-Area), speichern Trees und legen Commit Objekte an, die die obersten Trees sowie die Commits referenzieren, die ihnen unmittelbar vorhergingen. Diese drei Hauptobjekte – Blob, Tree und Commit – werden zunächst als separate Dateien im Verzeichnis `.git/objects` gespeichert. Hier ist eine Liste aller Objekte, die sich in unserem Beispiel-Repository jetzt in der Datenbank befinden – jeweils mit einem Kommentar darüber, was sie speichern: $ find .git/objects -type f .git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341 # tree 2 @@ -326,19 +326,19 @@ Fantastisch, oder? Du hast jetzt sämtliche low-level Operationen durchgeführt, -Wenn man all diese Zeiger auflöst, erhält man einen Objekt Graphen wie den folgenden (Bild 9-3). +Wenn man all diese Zeiger auflöst, erhält man einen Objekt-Graphen wie den folgenden (Bild 9-3). Insert 18333fig0903.png -Bild 9-3. Die Objekte im Beispielrepository. +Bild 9-3. Alle Objekte in Deinem Git-Repository. -### Objekt Speicher ### +### Objekt-Speicher ### -Wir haben kurz erwähnt, dass zusammen mit einem Inhalt ein Header gespeichert wird. Schauen wir uns also genauer an, wie genau Git Objekte speichert. Du wirst sehen, wie ein Blob Objekt – in diesem Fall der String „what is up, doc?“ (xxx übersetzen? xxx) gespeichert wird. Dazu nuten wir den interaktiven Ruby Modus, den Du mit dem `irb` Befehl starten kannst: +Wir haben kurz erwähnt, dass zusammen mit einem Inhalt ein Header gespeichert wird. Schauen wir uns also genauer an, wie genau Git Objekte speichert. Du wirst sehen, wie ein Blob-Objekt – in diesem Fall die Zeichenkette „what is up, doc?“ gespeichert wird. Dazu nuten wir den interaktiven Ruby-Modus, den Du mit dem `irb` Befehl starten kannst: $ irb >> content = "what is up, doc?" @@ -346,14 +346,14 @@ Wir haben kurz erwähnt, dass zusammen mit einem Inhalt ein Header gespeichert w -Git erzeugt einen Header, der mit dem Objekt Typ beginnt, in diesem Fall ist das ein Blob. Dann folgt ein Leerzeichen, die Anzahl der Zeichen des Inhalts und schließlich ein Nullbyte. +Git erzeugt einen Header, der mit dem Objekttyp beginnt, in diesem Fall ist das ein Blob. Dann folgt ein Leerzeichen, die Anzahl der Zeichen des Inhalts und schließlich ein Nullbyte. >> header = "blob #{content.length}\0" => "blob 16\000" -Git fügt diesen Header mit dem ursprünglichen Inhalt zusammen und kalkuliert aus dem Ergebnis die SHA-1 Prüfsumme (Hash). Du kannst einen SHA-1 Hash in Ruby berechnen, indem Du die SHA1 digest Bibliothek mit `require` einbindest und dann `Digest::SHA1.hexdigest()` mit dem String ausführst: +Git fügt diesen Header mit dem ursprünglichen Inhalt zusammen und kalkuliert aus dem Ergebnis die SHA-1-Prüfsumme (Hash). Du kannst einen SHA-1-Hash in Ruby berechnen, indem Du die SHA1-Digest-Bibliothek mit `require` einbindest und dann `Digest::SHA1.hexdigest()` mit der Zeichenkette ausführst: >> store = header + content => "blob 16\000what is up, doc?" @@ -364,7 +364,7 @@ Git fügt diesen Header mit dem ursprünglichen Inhalt zusammen und kalkuliert a -Git komprimiert den neuen Inhalt (d.h. inklusive des Headers) mit zlib. In Ruby kannst Du dazu die zlib Bibliothek verwenden, indem Du wiederum zuerst die Bibliothek mit `require` einbindest und dann `Zlib::Deflate.deflate()` mit dem Inhalt aufrufst: +Git komprimiert den neuen Inhalt (d.h. inklusive des Headers) mit zlib. In Ruby kannst Du dazu die zlib-Bibliothek verwenden, indem Du wiederum zuerst die Bibliothek mit `require` einbindest und dann `Zlib::Deflate.deflate()` mit dem Inhalt aufrufst: >> require 'zlib' => true @@ -386,18 +386,18 @@ Schließlich schreibst Du den zlib-komprimierten Inhalt in eine Datei auf der Fe -Das ist alles – Du hast jetzt ein valides Git Blob Objekt geschrieben. Git Objekte werden immer in dieser Weise gespeichert, lediglich mit verschiedenen Typen, d.h. anstelle des Strings „blob“ wird der Header mit „commit“ oder „tree“ anfangen. Außerdem sind Commit und Tree Inhalte auf eine sehr spezifische Weise formatiert, während Blobs beliebige Inhalte sein können. +Das ist alles – Du hast jetzt ein valides Git-Blob-Objekt geschrieben. Git-Objekte werden immer in dieser Weise gespeichert, lediglich mit verschiedenen Typen, d.h. anstelle der Zeichenkette „blob“ wird der Header mit „commit“ oder „tree“ anfangen. Außerdem sind Commit- und Tree-Inhalte auf eine sehr spezifische Weise formatiert, während Blobs beliebige Inhalte sein können. -## Git Referenzen ## +## Git-Referenzen ## -Du kannst Befehle wie `git log 1a410e` ausführen, um die Commit Historie zu inspizieren, aber dazu musst Du Dir jeweils merken, dass `1a410e` der jeweils letzte Commit ist. Um diese SHA-1 Hashes mit einfacheren, verständlichen Namen zu referenzieren, verwendet Git weitere Dateien, in denen die Namen für Hashes gespeichert sind. +Du kannst Befehle wie `git log 1a410e` ausführen, um die Commit-Historie zu inspizieren, aber dazu musst Du Dir jeweils merken, dass `1a410e` der jeweils letzte Commit ist. Um diese SHA-1-Hashes mit einfacheren, verständlichen Namen zu referenzieren, verwendet Git weitere Dateien, in denen die Namen für Hashes gespeichert sind. -Diese Namen werden in Git intern als „references“ oder „refs“ bezeichnet. Du kannst diese Dateien, die SHA-1 Hashes enthalten, im `.git/refs` Verzeichnis finden. In unserem gegenwärtigen Projekt enthält dieses Verzeichnis noch keine Dateien, aber eine simple Verzeichnisstruktur: +Diese Namen werden in Git intern als „references“ oder „refs“ bezeichnet. Du kannst diese Dateien, die SHA-1-Hashes enthalten, im Verzeichnis `.git/refs` finden. In unserem gegenwärtigen Projekt enthält dieses Verzeichnis noch keine Dateien, aber eine simple Verzeichnisstruktur: $ find .git/refs .git/refs @@ -408,13 +408,13 @@ Diese Namen werden in Git intern als „references“ oder „refs“ bezeichnet -Um jetzt eine neue Referenz anzulegen, die Dir dabei hilft, Dich zu erinnern, wo sich Dein letzten Commit befindet, könntest Du, technisch gesehen, Folgendes tun: +Um jetzt eine neue Referenz anzulegen, die Dir dabei hilft, Dich zu erinnern, wo sich Dein letzter Commit befindet, könntest Du, technisch gesehen, Folgendes tun: $ echo "1a410efbd13591db07496601ebc7a059dd55cfe9" > .git/refs/heads/master -Jetzt kannst Du diese „head“ Referenz anstelle des SHA-1 Wertes in allen möglichen Git Befehlen verwenden: +Jetzt kannst Du diese „head“-Referenz anstelle des SHA-1-Wertes in allen möglichen Git-Befehlen verwenden: $ git log --pretty=oneline master 1a410efbd13591db07496601ebc7a059dd55cfe9 third commit @@ -423,13 +423,13 @@ Jetzt kannst Du diese „head“ Referenz anstelle des SHA-1 Wertes in allen mö -Allerdings ist es nicht empfehlenswert, die Referenz Dateien direkt zu bearbeiten. Git stellt einen sichereren Befehl dafür zur Verfügung, den Befehl `git update-ref`: +Allerdings ist es nicht empfehlenswert, die Referenz-Dateien direkt zu bearbeiten. Git stellt einen sichereren Befehl dafür zur Verfügung, den Befehl `git update-ref`: $ git update-ref refs/heads/master 1a410efbd13591db07496601ebc7a059dd55cfe9 -Im Prinzip ist das alles, was einen Branch in Git ausmacht: ein simpler Zeiger oder eine Referenz auf den jeweiligen Kopf (xxx head xxx) einer Serie von Commits (xxx ??? xxx). Um einen neuen Branch anzulegen, der vom zweiten Commit aus verzweigt, kannst Du folgendes tun: +Im Prinzip ist das alles, was einen Branch in Git ausmacht: ein simpler Zeiger oder eine Referenz auf den jeweiligen Head einer Arbeitsreihe. Um einen neuen Branch anzulegen, der vom zweiten Commit aus verzweigt, kannst Du Folgendes tun: $ git update-ref refs/heads/test cac0ca @@ -443,23 +443,23 @@ Dein Branch beginnt jetzt beim zweiten Commit: -Die Git Datenbank unseres Beispielrepositories ist jetzt wie folgt strukturiert: +Die Git-Datenbank unseres Beispiel-Repositorys ist jetzt wie folgt strukturiert: Insert 18333fig0904.png -Bild 9-4. Git Verzeichnis Objekte mit Branch Head Referenzen. +Bild 9-4. Git-Verzeichnis-Objekte mit Branch-Head-Referenzen. -Wenn Du Befehle wie `git branch (branchname)` verwendest, führt Git intern im wesentlichen den `update-ref` Befehl aus, um den SHA-1 Hash des letzten Commits des jeweils gegenwärtigen Branches mit dem gegebenen Namen zu referenzieren. +Wenn Du Befehle wie `git branch (branchname)` verwendest, führt Git intern im Wesentlichen den Befehl `update-ref` aus, um den SHA-1-Hash des letzten Commits des jeweils gegenwärtigen Branches mit dem gegebenen Namen zu referenzieren. ### Der HEAD ### -Die Frage ist jetzt: wenn Du `git branch (branchname)` ausführst, woher weiß Git den SHA-1 des letzten Commits? Die Antwort ist: aus der HEAD Datei. Diese Datei ist eine symbolische Referenz auf den jeweiligen Branch, auf dem Du Dich gerade befindest. Mit „symbolischer Referenz“ meine ich, dass sie (anders als eine „normale“ Referenz) keinen SHA-1 Hash enthält, sondern statt dessen auf eine andere Referenz zeigt. Wenn Du die HEAD Datei ansiehst, findest Du normalerweise etwas wie: +Die Frage ist jetzt: Wenn Du `git branch (branchname)` ausführst, woher weiß Git den SHA-1 des letzten Commits? Die Antwort ist: aus der HEAD Datei. Diese Datei ist eine symbolische Referenz auf den jeweiligen Branch, auf dem Du Dich gerade befindest. Mit „symbolischer Referenz“ meine ich, dass sie (anders als eine „normale“ Referenz) keinen SHA-1-Hash enthält, sondern stattdessen auf eine andere Referenz zeigt. Wenn Du die Datei ansiehst, findest Du normalerweise etwas wie: $ cat .git/HEAD ref: refs/heads/master @@ -473,11 +473,11 @@ Wenn Du jetzt `git checkout test` ausführst, wird Git die Datei aktualisieren, -Wenn Du `git commit` ausführst, erzeugt Git das Commit Objekt und verwendet als Parent des Commit Objektes den jeweiligen Wert der Referenz auf die HEAD zeigt. +Wenn Du `git commit` ausführst, erzeugt Git das Commit-Objekt und verwendet als Parent des Commit-Objektes den jeweiligen Wert der Referenz, auf die HEAD zeigt. -Du kannst diese Datei manuell bearbeiten, aber es Git verfügt wiederum über einen sichereren Befehl, um das zu tun: `git symbolic-ref`. Du kannst den Wert des HEAD mit Hilfe des folgenden Befehls lesen: +Du kannst diese Datei manuell bearbeiten, aber wiederum verfügt Git über einen sichereren Befehl, um das zu tun: `git symbolic-ref`. Du kannst den Wert des HEAD mit Hilfe des folgenden Befehls lesen: $ git symbolic-ref HEAD refs/heads/master @@ -502,7 +502,7 @@ Du kannst den Befehl allerdings nicht verwenden, um eine Referenz außerhalb von -Wir haben jetzt Gits drei Haupt Objekttypen besprochen, aber es gibt noch einen vierten. Das Tag Objekt ist dem Commit Objekt sehr ähnlich: es enthält einen Tagger (xxx), ein Datum, eine Meldung und eine Referenz auf ein anderes Objekt. Der Hauptunterschied besteht darin, dass ein Tag Objekt auf einen Commit zeigt und nicht auf einen Tree. Ein Tag ist in dieser Hinsicht also ähnlich einem Branch, aber er bewegt sich nie, sondern zeigt immer auf denselben Commit und gibt ihm damit einen netteren Namen. +Wir haben jetzt Gits drei Haupt-Objekttypen besprochen, aber es gibt noch einen vierten. Das Tag-Objekt ist dem Commit-Objekt sehr ähnlich: es enthält den Autor des Tags, ein Datum, eine Meldung und eine Referenz auf ein anderes Objekt. Der Hauptunterschied besteht darin, dass ein Tag-Objekt auf einen Commit zeigt und nicht auf einen Tree. Ein Tag ist in dieser Hinsicht also ähnlich einem Branch, aber er bewegt sich nie, sondern zeigt immer auf denselben Commit und gibt ihm damit einen netteren Namen. @@ -512,20 +512,20 @@ Wie wir schon in Kapitel 2 besprochen haben, gibt es zwei Typen von Tags: „ann -Das ist alles, woraus ein einfacher Tag besteht: einem Branch, der sich nie bewegt. Ein annotierter Tag ist komplexer. Wenn Du einen annotierten Tag anlegst, erzeugt Git ein Tag Objekt und speichert eine Referenz, die darauf zeigt, statt direkt auf den Commit zu zeigen. Du kannst das sehen, wenn Du einen annotierten Tag anlegst (`-a` bewirkt, dass wir einen annotierten Tag erhalten): +Das ist alles, woraus ein einfacher Tag besteht: einem Branch, der sich nie bewegt. Ein annotierter Tag ist komplexer. Wenn Du einen annotierten Tag anlegst, erzeugt Git ein Tag-Objekt und speichert eine Referenz, die darauf zeigt, statt direkt auf den Commit zu zeigen. Du kannst das sehen, wenn Du einen annotierten Tag anlegst (`-a` bewirkt, dass wir einen annotierten Tag erhalten): $ git tag -a v1.1 1a410efbd13591db07496601ebc7a059dd55cfe9 -m 'test tag' -Das erzeugt den folgenden Objekt SHA-1 Hash: +Das erzeugt den folgenden Objekt SHA-1-Hash: $ cat .git/refs/tags/v1.1 9585191f37f7b0fb9444f35a9bf50de191beadc2 -Jetzt wendest Du den `git cat-file` Befehl auf diesen SHA-1 Hash an: +Jetzt wendest Du den Befehl `git cat-file` auf diesen SHA-1-Hash an: $ git cat-file -p 9585191f37f7b0fb9444f35a9bf50de191beadc2 object 1a410efbd13591db07496601ebc7a059dd55cfe9 @@ -537,13 +537,13 @@ Jetzt wendest Du den `git cat-file` Befehl auf diesen SHA-1 Hash an: -Beachte, dass der der `object` Wert auf den commit SHA-1 zeigt, den Du getaggt hast, und dass die `tags/v1.1` Referenz nicht direkt auf den Commit zeigt, sondern auf das Tag Objekt. In Git kannst Du jedes beliebige Objekt taggen. Im Git Quellcode z.B. befindet sich der öffentliche GPG Schlüssel des Projektbetreibers als ein Blob Objekt, sowie ein Tag, der darauf zeigt. Auf diese Weise kannst den Schlüssel so anzeigen, indem Du den folgenden Befehl im Git Quellcode Repository ausführst: +Beachte, dass der der Wert `object` auf den SHA-1 des Commits zeigt, den Du getaggt hast, und dass die `tags/v1.1` Referenz nicht direkt auf den Commit zeigt, sondern auf das Tag-Objekt. In Git kannst Du jedes beliebige Objekt taggen. Im Git-Quellcode z.B. befindet sich der öffentliche GPG-Schlüssel des Projektbetreibers als ein Blob-Objekt, sowie ein Tag, der darauf zeigt. Auf diese Weise kannst den Schlüssel so anzeigen, indem Du den folgenden Befehl im Git-Quellcode Repository ausführst: $ git cat-file blob junio-gpg-pub -Der Linux Kernel hat also ein Tag Objekt, das nicht auf einen Commit zeigt – der erste Tag (xxx) zeigt auf den ursprünglichen Tree mit dem Import des Quellcodes (xxx what? xxx). +Der Linux-Kernel hat auch ein Tag-Objekt, das nicht auf einen Commit zeigt – der erste erstellte Tag zeigt auf den anfänglichen Tree des Quelltext-Imports. ### Externe Referenzen ### @@ -563,7 +563,7 @@ Der dritte Referenztyp ist die externe Referenz („remote reference“). Wenn D -Dann kannst Du herausfinden, in welchem Zustand sich der `master` Branch auf dem `origin` Server zuletzt befand (d.h. als Du das letzte Mal mit ihm kommuniziert hast), indem Du die Datei `refs/remotes/origin/master` anschaust: +Dann kannst Du herausfinden, in welchem Zustand sich der `master`-Branch auf dem `origin`-Server zuletzt befand (d.h. als Du das letzte Mal mit ihm kommuniziert hast), indem Du die Datei `refs/remotes/origin/master` anschaust: $ cat .git/refs/remotes/origin/master ca82a6dff817ec66f44342007202690a93763949 @@ -577,7 +577,7 @@ Externe Referenzen unterscheiden sich von Branches (`refs/heads`) hauptsächlich -Kommen wir noch einmal auf die Objekt Datenbank zurück, die Du für Dein Test Git Repository angelegt hast. Im Moment müsstest Du 11 Objekte haben: 4 Blobs, 3 Trees, 3 Commits und 1 Tag: +Kommen wir noch einmal auf die Objekt-Datenbank zurück, die Du für Dein Test-Git-Repository angelegt hast. Im Moment müsstest Du 11 Objekte haben: 4 Blobs, 3 Trees, 3 Commits und 1 Tag: $ find .git/objects -type f .git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341 # tree 2 @@ -594,7 +594,7 @@ Kommen wir noch einmal auf die Objekt Datenbank zurück, die Du für Dein Test G -Git komprimiert die Inhalte dieser Dateien mit zlib und Du hast nicht sonderlich viele davon, sodass die Gesamtgröße der Dateien gerade mal 925 Bytes beträgt. Wir wollen ein anderes interessantes Feature von Git demonstrieren, und dazu müssen wir eine größere Datei hinzufügen, z.B. die `repo.rb` Datei aus dem Grit Repository, das Du schon verwendet hast. Diese Datei ist eine etwa 12K große Quellcode Datei: +Git komprimiert die Inhalte dieser Dateien mit zlib und Du hast nicht sonderlich viele davon, sodass die Gesamtgröße der Dateien gerade mal 925 Bytes beträgt. Wir wollen ein anderes interessantes Feature von Git demonstrieren, und dazu müssen wir eine größere Datei hinzufügen, z.B. die `repo.rb` Datei aus der Grit-Bibliothek, die Du schon verwendet hast. Diese Datei ist eine etwa 12K große Quelltext-Datei: $ curl https://raw.github.com/mojombo/grit/master/lib/grit/repo.rb > repo.rb $ git add repo.rb @@ -607,7 +607,7 @@ Git komprimiert die Inhalte dieser Dateien mit zlib und Du hast nicht sonderlich -Wenn Du Dir den resultierenden Tree anschaust, findest Du den SHA-1 Hash, den die Datei `repo.rb` für das Blob Objekt erhalten hat: +Wenn Du Dir den resultierenden Tree anschaust, findest Du den SHA-1-Hash, den die Datei `repo.rb` für das Blob-Objekt erhalten hat: $ git cat-file -p master^{tree} 100644 blob fa49b077972391ad58037050f2a75f74e3671e92 new.txt @@ -623,7 +623,7 @@ Jetzt kannst Du mit `git cat-file` sehen, wie groß das Objekt ist: -Als nächste ändern wir die Datei ein bisschen, um zu sehen, was passiert: +Als Nächstes ändern wir die Datei ein bisschen, um zu sehen, was passiert: $ echo '# testing' >> repo.rb $ git commit -am 'modified repo a bit' @@ -652,7 +652,7 @@ Du hast jetzt zwei fast identische 12K große Objekte auf Deiner Festplatte. Wä -Tatsächlich kann Git das. Das ursprüngliche Format, in dem Git Objekte in der Datenbank speichert wird als „freies Objekt Format“ („loose object format“) bezeichnet. Hin und wieder packt Git allerdings eine Reihe solcher Objekte in eine einzige binäre Datei zusammen, um Platz zu sparen und effizienter zu arbeiten. Eine solche Datei wird als „packfile“ bezeichnet. Git tut das immer dann, wenn zu viele freie Objekte vorhanden sind, wenn Du den Befehl `git gc` manuell ausführst oder wenn Du auf einen externen Server pushst. Schauen wir uns also an, was passiert, wenn wir manuell `git gc` ausführen: +Tatsächlich kann Git das. Das ursprüngliche Format, in dem Git Objekte in der Datenbank speichert, wird als „freies Objekt-Format“ („loose object format“) bezeichnet. Hin und wieder packt Git allerdings eine Reihe solcher Objekte in eine einzige binäre Datei zusammen, um Platz zu sparen und effizienter zu arbeiten. Eine solche Datei wird als „packfile“ bezeichnet. Git tut das immer dann, wenn zu viele freie Objekte vorhanden sind, wenn Du den Befehl `git gc` manuell ausführst oder wenn Du auf einen externen Server pushst. Schauen wir uns also an, was passiert, wenn wir manuell `git gc` ausführen: $ git gc Counting objects: 17, done. @@ -663,7 +663,7 @@ Tatsächlich kann Git das. Das ursprüngliche Format, in dem Git Objekte in der -Wenn Du das Objekt Verzeichnis anschaust, siehst Du, dass die meisten Objekte jetzt fehlen und dass stattdessen zwei neue Objekte aufgetaucht sind: +Wenn Du das Objekt-Verzeichnis anschaust, siehst Du, dass die meisten Objekte jetzt fehlen und dass stattdessen zwei neue Objekte aufgetaucht sind: $ find .git/objects -type f .git/objects/71/08f7ecb345ee9d0084193f147cdad4d2998293 @@ -674,7 +674,7 @@ Wenn Du das Objekt Verzeichnis anschaust, siehst Du, dass die meisten Objekte je -Die verbleibenden Objekte sind diejenigen Blobs, die nicht von irgendeinem Commit referenziert werden – in diesem Fall sind das die „what is up, doc?“ und „test content“ Beispielblobs, die wir zuvor gespeichert hatten: weil wir sie nie zu irgendeinem Commit hinzugefügt haben, werden sie als „dangling“ (xxx) betrachtet und nicht im Packfile zusammengepackt. +Die verbleibenden Objekte sind diejenigen Blobs, die nicht von irgendeinem Commit referenziert werden – in diesem Fall sind das die Beispielblobs „what is up, doc?“ und „test content“, die wir zuvor gespeichert hatten: weil wir sie nie zu irgendeinem Commit hinzugefügt haben, werden sie als „dangling“ (wörtlich: herumbaumelnd) betrachtet und nicht im Packfile zusammengepackt. @@ -709,7 +709,7 @@ Wie stellt Git das genau an? Wenn Git Objekte zusammen packt, sucht es nach Date -Du erinnerst dich, dass der `9bc1d` Blob die erste Version der `repo.rb` Datei ist. Dieser Blob referenziert jetzt den `05408` Blob, der die zweite Version der Datei ist. Die dritte Spalte der Ausgabe ist die Größe des Objektes im Packfile. Wir können also sehen, dass `05408` 12K in Anspruch nimmt, `9bc1d` aber nur 7 Bytes. Das bedeutet also, dass die zweite Version diejenige ist, die vollständig, während die ursprüngliche, erste Version als Delta gespeichert wird! Der Grund dafür ist, dass Du höchstwahrscheinlich einen schnelleren Zugriff auf die jeweils neuesten Dateien brauchst. +Du erinnerst dich, dass der Blob `9bc1d` die erste Version der `repo.rb`-Datei ist. Dieser Blob referenziert jetzt den Blob`05408`, der die zweite Version der Datei ist. Die dritte Spalte der Ausgabe ist die Größe des Objektes im Packfile. Wir können also sehen, dass `05408` 12K in Anspruch nimmt, `9bc1d` aber nur 7 Bytes. Das bedeutet also, dass die zweite Version diejenige ist, die vollständig, während die ursprüngliche, erste Version als Delta gespeichert wird! Der Grund dafür ist, dass Du höchstwahrscheinlich einen schnelleren Zugriff auf die jeweils neuesten Dateien brauchst. @@ -721,13 +721,13 @@ Außerdem ist toll, dass ein Repository jederzeit neu gepackt werden kann. Git m -In diesem Buch haben wir bisher einfache Mappings von externen Branches auf lokale Referenzen verwendet. Sie können aber auch durchaus komplex sein. Nehmen wir an, Du hast ein externes Repository wie folgt definiert: +In diesem Buch haben wir bisher einfache Zuweisungen von externen Branches auf lokale Referenzen verwendet. Sie können aber auch durchaus komplex sein. Nehmen wir an, Du hast ein externes Repository wie folgt definiert: $ git remote add origin git@github.com:schacon/simplegit-progit.git -Das fügt eine Sektion in Deine `.git/config` Datei hinzu, die Deinen lokalen Namen des externen Repositories (`origin`), dessen URL und die Refspec spezifiziert, mit der neue Daten heruntergeladen werden. +Das fügt eine Sektion in Deine `.git/config`-Datei hinzu, die Deinen lokalen Namen des externen Repositorys (`origin`), dessen URL und die Refspec spezifiziert, mit der neue Daten heruntergeladen werden. [remote "origin"] url = git@github.com:schacon/simplegit-progit.git @@ -735,11 +735,11 @@ Das fügt eine Sektion in Deine `.git/config` Datei hinzu, die Deinen lokalen Na -Das Format der Refspec besteht aus einem optionalen `+` gefolgt von `:`, wobei `` ein Pattern für Referenzen auf der Remote Seite ist, und `` angibt, wohin diese Referenzen lokal geschrieben werden. Das `+` weist Git an, die Referenz zu mergen, wenn sie nicht mit einem fast-forward aktualisiert werden kann. +Das Format der Refspec besteht aus einem optionalen `+` gefolgt von `:`, wobei `` ein Muster für Referenzen auf der Remote-Seite ist, und `` angibt, wohin diese Referenzen lokal geschrieben werden. Das `+` weist Git an, die Referenz zu mergen, wenn sie nicht mit einem Fast-forward aktualisiert werden kann. -Der Standard, der von `git remote add` automatisch eingerichtet wird, besteht darin, dass Git austomatisch alle Referenzen unter `refs/heads/` vom Server holt und sie lokal nach `refs/remotes/origin` speichert. D.h., wenn es auf dem Server einen `master` Branch gibt, kannst Du auf das Log dieses Branches wie folgt zugreifen: +Der Standard, der von `git remote add` automatisch eingerichtet wird, besteht darin, dass Git automatisch alle Referenzen unter `refs/heads/` vom Server holt und sie lokal nach `refs/remotes/origin` speichert. D.h., wenn es auf dem Server einen `master`-Branch gibt, kannst Du auf das Log dieses Branches wie folgt zugreifen: $ git log origin/master $ git log remotes/origin/master @@ -751,13 +751,13 @@ Diese Varianten sind allesamt äquivalent, weil Git sie jeweils zu `refs/remotes -Wenn Du statt dessen willst, dass Git jeweils nur den `master` Branch herunterlädt und andere Branches auf dem Server ignoriert, kannst Du die `fetch` Zeile wie folgt ändern: +Wenn Du stattdessen willst, dass Git jeweils nur den `master`-Branch herunterlädt und andere Branches auf dem Server ignoriert, kannst Du die `fetch`-Zeile wie folgt ändern: fetch = +refs/heads/master:refs/remotes/origin/master -Dies ist allerdings lediglich der Default Refspec Wert und Du kannst ihn auf der Kommandozeile jederzeit überschreiben. Z.B. um nur `master` branch vom Server lokal als `origin/mymaster` zu speichern, kannst Du folgendes ausführen: +Dies ist allerdings lediglich der Standardwert der Refspec und Du kannst ihn auf der Kommandozeile jederzeit überschreiben. Um zum Beispiel nur den `master`-branch vom Server lokal als `origin/mymaster` zu speichern, kannst Du Folgendes ausführen: $ git fetch origin master:refs/remotes/origin/mymaster @@ -771,13 +771,13 @@ Du kannst auch mehrere Refspecs gleichzeitig spezifizieren. Z.B.: ! [rejected] master -> origin/mymaster (non fast forward) * [new branch] topic -> origin/topic - + -I diesem Fall wurde ein Pull zurückgewiesen (xxx ist das nicht nur ein fetch? xxx), weil der Branch nicht mit einem simplen fast-forward aktualisiert werden konnte. Du kannst einen Merge erzwingen, indem Du der Refspec ein `+` voranstellst. +In diesem Fall wurde ein Pull zurückgewiesen, weil der Branch nicht mit einem simplen Fast-forward aktualisiert werden konnte. Du kannst einen Merge erzwingen, indem Du der Refspec ein `+` voranstellst. -Du kannst außerdem natürlich auch mehrere Refspecs in Deiner Konfiguration spezifizieren. Wenn Du z.B. immer die `master` und `experiment` Branches holen willst, fügst Du die folgenden Zeilen hinzu: +Du kannst außerdem natürlich auch mehrere Refspecs in Deiner Konfiguration spezifizieren. Wenn Du z.B. immer die Branches `master` und `experiment` holen willst, fügst Du die folgenden Zeilen hinzu: [remote "origin"] url = git@github.com:schacon/simplegit-progit.git @@ -786,13 +786,13 @@ Du kannst außerdem natürlich auch mehrere Refspecs in Deiner Konfiguration spe -Du kannst keine partiellen Glob Patterns verwenden, d.h. folgendes wäre ungültig: +Du kannst keine partiellen Glob-Muster verwenden, d.h. Folgendes wäre ungültig: fetch = +refs/heads/qa*:refs/remotes/origin/qa* -Allerdings kannst Du Namensräume verwenden, um etwas ähnliches zu erreichen. Nehmen wir an, Du hast ein QA Team, das regelmäßig verschiedene Branches pusht, und Du willst nun den master Branch und sämtliche Branches des QA Teams, aber keine anderen Branches haben. Dann kannst Du eine Config Sektion wie die folgende verwenden: +Allerdings kannst Du Namensräume verwenden, um etwas Ähnliches zu erreichen. Nehmen wir an, Du hast ein QA-Team, das regelmäßig verschiedene Branches pusht, und Du willst nun den master-Branch und sämtliche Branches des QA-Teams, aber keine anderen Branches haben. Dann kannst Du eine Config-Sektion wie die folgende verwenden: [remote "origin"] url = git@github.com:schacon/simplegit-progit.git @@ -801,24 +801,24 @@ Allerdings kannst Du Namensräume verwenden, um etwas ähnliches zu erreichen. N -In einem großen Team mit einem komplexen Workflow, in dem ein QA Team, Entwickler und ein Integrations Team jeweils eigene Branches pushen, kann man auf diese Weise Branches einfach in Namensräume einteilen. +In einem großen Team mit einem komplexen Workflow, in dem ein QA-Team, Entwickler und ein Integrations-Team jeweils eigene Branches pushen, kann man auf diese Weise Branches einfach in Namensräume einteilen. ### Refspecs pushen ### -Wie aber legt das QA Team die Branches im `qa/` Namensraum ab? Das geht, indem man mit einer Refspec pusht. +Wie aber legt das QA-Team die Branches im `qa/` Namensraum ab? Das geht, indem man mit einer Refspec pusht. -Wenn das QA Team seinen `master` Branch in einem externen Repository als `qa/master` speichern will, kann es das wie folgt tun: +Wenn das QA-Team seinen `master` Branch in einem externen Repository als `qa/master` speichern will, kann es das wie folgt tun: $ git push origin master:refs/heads/qa/master -Um Git so zu konfigurieren, dass diese Refspec jedes mal automatisch für `git push origin` verwendet wird, kann man den `push` Wert in der Config Datei setzen: +Um Git so zu konfigurieren, dass diese Refspec jedes Mal automatisch für `git push origin` verwendet wird, kann man den `push` Wert in der Config-Datei setzen: [remote "origin"] url = git@github.com:schacon/simplegit-progit.git @@ -840,52 +840,52 @@ Man kann Refspecs außerdem verwenden, um Referenzen aus einem externen Reposito -Das Refspec Format ist `:`. Wenn man den `` Teil weglässt, dann heißt das im obigen Beispiel, dass man den `topic` Branch auf dem `origin` Server auf „nichts“ setzt, d.h. also löscht. +Das Refspec Format ist `:`. Wenn man den Teil `` weglässt, dann heißt das im obigen Beispiel, dass man den `topic` Branch auf dem `origin` Server auf „nichts“ setzt, d.h. also löscht. -## Transfer Protokolle ## +## Transfer-Protokolle ## -Git kann Daten zwischen zwei Repositories im wesentlichen auf zwei Arten transportieren: über HTTP und über sogenannte smarte Protokolle, die mit `file://`, `ssh://` und `git://` verwendet werden. Die folgende Sektion gibt einen kurzen Überblick über diese Protokolle und wie sie funktionieren. +Git kann Daten zwischen zwei Repositorys im Wesentlichen auf zwei Arten transportieren: über HTTP und über sogenannte smarte Protokolle, die mit `file://`, `ssh://` und `git://` verwendet werden. Die folgende Sektion gibt einen kurzen Überblick über diese Protokolle und wie sie funktionieren. ### Das dumme Protokoll ### -Gits HTTP Transfer Protokoll wird oft auch als „dummes“ Protokoll bezeichnet, weil es auf der Server Seite keinen Git-spezifischen Code benötigt. Der `fetch` Prozess besteht aus einer Reihe von GET Requests, für die der Client Vorannahmen über das Layout des Git Repositories auf dem Server machen kann. Schauen wir uns den `http-fetch` Prozess der `simplegit` Bibliothek an: +Das HTTP-Transfer-Protokoll von Git wird oft auch als „dummes“ Protokoll bezeichnet, weil es auf der Server-Seite keinen Git-spezifischen Code benötigt. Der `fetch`-Prozess besteht aus einer Reihe von GET-Requests, für die der Client Vorannahmen über das Layout des Git-Repositorys auf dem Server machen kann. Schauen wir uns den `http-fetch`-Prozess der `simplegit`-Bibliothek an: $ git clone http://github.com/schacon/simplegit-progit.git -Der Befehl lädt zunächst die `info/refs` Datei herunter. Diese Datei wird vom `update-server-info` Befehl geschrieben, den man als einen `post-receive` Hook einrichten muss, damit das HTTP Protokoll richtig funktionieren kann. +Der Befehl lädt zunächst die `info/refs` Datei herunter. Diese Datei wird vom Befehl `update-server-info` geschrieben, den man als einen `post-receive`-Hook einrichten muss, damit das HTTP-Protokoll richtig funktionieren kann. => GET info/refs ca82a6dff817ec66f44342007202690a93763949 refs/heads/master -Jetzt hat man eine Liste aller Referenzen und SHAs in diesem Repository. Als nächstes schaut man die HEAD Referenz nach, um zu wissen, was ausgecheckt werden muss: +Jetzt hat man eine Liste aller Referenzen und SHAs in diesem Repository. Als nächstes schaut man die HEAD-Referenz nach, um zu wissen, was ausgecheckt werden muss: => GET HEAD ref: refs/heads/master -D.h., wenn wir mit dem Prozess fertig sind, wir müssen den `master` Branch auschecken. +D.h., wenn wir mit dem Prozess fertig sind, wir müssen den `master`-Branch auschecken. -Wir können jetzt loslegen. Weil wir in der `info/refs` Datei der Commit `ca82a6` angegeben ist, fangen wir damit an, dieses Objekt herunter zu laden: +Wir können jetzt loslegen. Weil wir in der `info/refs` Datei der Commit `ca82a6` angegeben ist, fangen wir damit an, dieses Objekt herunterzuladen: => GET objects/ca/82a6dff817ec66f44342007202690a93763949 (179 bytes of binary data) -Wir erhalten also ein Objekt zurück. Dieses Objekt ist im losen Format auf dem Server gespeichert, und wir haben es über einen statischen HTTP GET Request herunter geladen. Jetzt können wir es mit zlib dekomprimieren, den Header entfernen und den Inhalt des Commits durchsehen: +Wir erhalten also ein Objekt zurück. Dieses Objekt ist im losen Format auf dem Server gespeichert, und wir haben es über einen statischen HTTP-GET-Request herunter geladen. Jetzt können wir es mit zlib dekomprimieren, den Header entfernen und den Inhalt des Commits durchsehen: $ git cat-file -p ca82a6dff817ec66f44342007202690a93763949 tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf @@ -897,21 +897,21 @@ Wir erhalten also ein Objekt zurück. Dieses Objekt ist im losen Format auf dem -Als nächstes brauchen wir also zwei weitere Objekte: `cfda3b`, welches der Tree der Inhalte dieses Commits ist, und `085bb3`, den Commit Parent: +Als Nächstes brauchen wir also zwei weitere Objekte: `cfda3b`, welches der Tree der Inhalte dieses Commits ist, und `085bb3`, den Commit-Parent: => GET objects/08/5bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 (179 bytes of data) -Das gibt uns das nächste Commit Objekt. Versuchen wir, das Tree Objekt zu holen: +Das gibt uns das nächste Commit-Objekt. Versuchen wir, das Tree-Objekt zu holen: => GET objects/cf/da3bf379e4f8dba8717dee55aab78aef7f4daf (404 - Not Found) -Huch. Es sieht so aus als ob der Tree nicht im losen Format auf dem Server gespeichert ist, weshalb wir einen 404 Response („Not found“) erhalten. Dafür kann es verschiedene Gründe geben. Das Objekt könnte in einem anderen, alternativen Repository liegen, oder es könnte sich in einem Packfile befinden. Git sucht deshalb zunächst nach alternativen Repositories: +Huch. Es sieht so aus, als ob der Tree nicht im losen Format auf dem Server gespeichert ist, weshalb wir einer 404-Antwort („Not found“) erhalten. Dafür kann es verschiedene Gründe geben. Das Objekt könnte in einem anderen, alternativen Repository liegen, oder es könnte sich in einem Packfile befinden. Git sucht deshalb zunächst nach alternativen Repositories: => GET objects/info/http-alternates (empty file) @@ -921,14 +921,14 @@ Huch. Es sieht so aus als ob der Tree nicht im losen Format auf dem Server gespe -Wenn wir hier eine Liste alternativer URLs erhalten, schaut Git dort nach losen Dateien und Packfiles. Auf diese Weise können Repositories, die Forks von anderen Repositories sind, mit diesen Objekte im Dateisystem teilen. In unserem Fall sind allerdings keine Alternativen vorhanden, weshalb sich das gesuchte Objekt in einem Packfile befinden muss. Um die vorhandenen Packfiles nachzuschlagen, holt Git die `objects/info/packs` Datei, die eine entsprechende Auflistung enthält (und ebenfalls mit `update-server-info` erzeugt wird) +Wenn wir hier eine Liste alternativer URLs erhalten, schaut Git dort nach losen Dateien und Packfiles. Auf diese Weise können Repositorys, die Forks von anderen Repositorys sind, mit diesen Objekte im Dateisystem teilen. In unserem Fall sind allerdings keine Alternativen vorhanden, weshalb sich das gesuchte Objekt in einem Packfile befinden muss. Um die vorhandenen Packfiles nachzuschlagen, holt Git die `objects/info/packs` Datei, die eine entsprechende Auflistung enthält (und ebenfalls mit `update-server-info` erzeugt wird) => GET objects/info/packs P pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack -Es gibt nur ein einziges Packfile auf dem Server, weshalb sich unser Objekt darin befinden muss. Aber wir prüfen die Index Datei, um sicher zu sein. Gäbe es mehrere Packfiles auf dem Server, könnten wir auf diese Weise herausfinden, welches Packfile das gesuchte Objekt enthält: +Es gibt nur ein einziges Packfile auf dem Server, weshalb sich unser Objekt darin befinden muss. Aber wir prüfen die Index-Datei, um sicher zu sein. Gäbe es mehrere Packfiles auf dem Server, könnten wir auf diese Weise herausfinden, welches Packfile das gesuchte Objekt enthält: => GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.idx (4k of binary data) @@ -938,7 +938,7 @@ Es gibt nur ein einziges Packfile auf dem Server, weshalb sich unser Objekt dari -Nachdem wir jetzt den Packfile Index haben, können wir prüfen, ob sich unser Objekt darin befindet: der Index enthält eine Liste der SHA Hashes der Objekte, die sich im Packfile befinden und die jeweiligen Offsets dieser Objekte. Unser Objekt ist vorhanden, also laden wir das Packfile herunter: +Nachdem wir jetzt den Packfile-Index haben, können wir prüfen, ob sich unser Objekt darin befindet: der Index enthält eine Liste der SHA-Hashes der Objekte, die sich im Packfile befinden und die jeweiligen Offsets dieser Objekte. Unser Objekt ist vorhanden, also laden wir das Packfile herunter: => GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack (13k of binary data) @@ -948,7 +948,7 @@ Nachdem wir jetzt den Packfile Index haben, können wir prüfen, ob sich unser O -Du hast jetzt das Tree Objekt, also kannst Du jetzt damit fortfahren, über die Commits zu iterieren. Sie sind in unserem Fall allesamt in dem Packfile enthalten, das Du gerade heruntergeladen hast. +Du hast jetzt das Tree-Objekt, also kannst Du jetzt damit fortfahren, über die Commits zu iterieren. Sie sind in unserem Fall allesamt in dem Packfile enthalten, das Du gerade heruntergeladen hast. @@ -968,22 +968,22 @@ Die Ausgabe des ganzen Vorgangs sieht dann in etwa so aus: walk a11bef06a3f659402fe7563abf99ad00de2209e6 -### Das Smart Protokoll (xxx) ### +### Das schlaue Protokoll ### -Die HTTP Methode ist simpel, aber sie ist auch ein bisschen ineffizient. Deshalb ist es üblicher, ein smartes Protokoll für den Datentransfer zu verwenden. Diese Protokolle umfassen serverseitige Prozesse, die Wissen über Git besitzen. Sie können lokale Daten lesen und herausfinden, was auf dem Client schon vorhanden ist oder fehlt und darauf zugeschnitten Daten generieren. Es gibt zwei Sets von Prozessen für den Datentransfer: ein Paar für den Upload und ein Paar für den Download von Daten. +Die HTTP-Methode ist simpel, aber sie ist auch ein bisschen ineffizient. Deshalb ist es üblicher, ein schlaues Protokoll für den Datentransfer zu verwenden. Diese Protokolle umfassen serverseitige Prozesse, die Wissen über Git besitzen. Sie können lokale Daten lesen und herausfinden, was auf dem Client schon vorhanden ist oder fehlt und darauf zugeschnittene Daten generieren. Es gibt zwei Sets von Prozessen für den Datentransfer: ein Paar für den Upload und ein Paar für den Download von Daten. #### Daten hochladen #### -Um Daten an einen serverseitigen Prozess zu schicken, verwendet Git die `send-pack` und `receive-pack` Prozesse. Der `send-pack` Prozess läuft auf dem Client und verbindet sich mit einem `receive-pack` Prozess auf dem Server. +Um Daten an einen serverseitigen Prozess zu schicken, verwendet Git die Prozesse `send-pack` und `receive-pack`. Der Prozess `send-pack` läuft auf dem Client und verbindet sich mit einem `receive-pack`-Prozess auf dem Server. -Nehmen wir z.B. an Du führst `git push origin master` in Deinem Projekt aus und `origin` ist als eine URL mit SSH Protokoll definiert. Git startet dann einen `send-pack` Prozess, der eine SSH Verbindung zum Server initiiert. Dieser versucht, via SSH auf dem Server einen Befehl wie den folgenden auszuführen: +Nehmen wir z.B. an, Du führst `git push origin master` in Deinem Projekt aus und `origin` ist als eine URL mit SSH-Protokoll definiert. Git startet dann einen `send-pack`-Prozess, der eine SSH-Verbindung zum Server initiiert. Dieser versucht, via SSH auf dem Server einen Befehl wie den folgenden auszuführen: $ ssh -x git@github.com "git-receive-pack 'schacon/simplegit-progit.git'" 005bca82a6dff817ec66f4437202690a93763949 refs/heads/master report-status delete-refs @@ -992,15 +992,15 @@ Nehmen wir z.B. an Du führst `git push origin master` in Deinem Projekt aus und -Der `git-receive-pack` Befehl antwortet dann mit jeweils einer Zeile pro Referenz, die er kennt – in diesem Fall sind das lediglich der `master` Branch und dessen SHA. Die erste Zeile listet außerdem Features, die der Server beherrscht (in unserem Fall `report-status` und `delete-refs`). +Der `git-receive-pack`-Befehl antwortet dann mit jeweils einer Zeile pro Referenz, die er kennt – in diesem Fall sind das lediglich der `master`-Branch und dessen SHA. Die erste Zeile listet außerdem Features, die der Server beherrscht (in unserem Fall `report-status` und `delete-refs`). -Jede Zeile beginnt mit einem 4 Byte Hexadezimalzahl Wert, der angibt, wie lang der Rest der Zeile ist. Die erste Zeile beginnt mit 005b, d.h. dezimal 91. ALso ist der Rest der Zeile 91 Zeichen lang. Die nächste Zeile fängt mit 003e an, also dezimal 62. Die letzte Zeile ist 0000, was das Ende der Liste anzeigt. +Jede Zeile beginnt mit einem 4 Byte Hexadezimalzahl-Wert, der angibt, wie lang der Rest der Zeile ist. Die erste Zeile beginnt mit 005b, d.h. dezimal 91. ALso ist der Rest der Zeile 91 Zeichen lang. Die nächste Zeile fängt mit 003e an, also dezimal 62. Die letzte Zeile ist 0000, was das Ende der Liste anzeigt. -Nachdem Dein `send-pack` Prozess jetzt den Zustand des Servers kennt, kann er als nächstes evaluieren, welche Commits lokal, aber nicht auf dem Server vorhanden sind. der `send-pack` Prozess schickt diese Information für jede Referenz, auf die sich der `push` Befehl bezieht, an den `receive-pack` Prozess. Wenn Du beispielsweise den `master` Branch aktualisierst und einen `experiment` Branch hinzufügst, dann könnte die Antwort auf `send-pack` so aussehen: +Nachdem Dein `send-pack`-Prozess jetzt den Zustand des Servers kennt, kann er als nächstes evaluieren, welche Commits lokal, aber nicht auf dem Server vorhanden sind. der `send-pack`-Prozess schickt diese Information für jede Referenz, auf die sich der `push`-Befehl bezieht, an den `receive-pack` Prozess. Wenn Du beispielsweise den `master`-Branch aktualisierst und einen `experiment`-Branch hinzufügst, dann könnte die Antwort auf `send-pack` so aussehen: 0085ca82a6dff817ec66f44342007202690a93763949 15027957951b64cf874c3557a0f3547bd83b3ff6 refs/heads/master report-status 00670000000000000000000000000000000000000000 cdfdb42577e2506715f8cfeacdbabc092bf63e8d refs/heads/experiment @@ -1008,40 +1008,40 @@ Nachdem Dein `send-pack` Prozess jetzt den Zustand des Servers kennt, kann er al -Der SHA-1 Wert, der nur aus Nullen besteht, heißt, dass dort zuvor nichts war: Du fügst die `experiment` Referenz ja neu hinzu. Würdest Du eine Referenz löschen, würdest Du das Gegenteil sehen: nur Nullen auf der rechten Seite (xxx hu? wo ist die rechte seite? xxx) +Der SHA-1-Wert, der nur aus Nullen besteht, heißt, dass dort zuvor nichts war: Du fügst die `experiment`-Referenz ja neu hinzu. Würdest Du eine Referenz löschen, würdest Du das Gegenteil sehen: nur Nullen auf der rechten Seite. -Pro Referenz, die Du aktualisierst, schickt Git eine Zeile mit dem alten SHA, dem neuen SHA und der jeweiligen Referenz, die aktualisiert wird. Die erste Zeile listet zudem die Server Features. Als nächstes lädt der Client ein Packfile aller Objekte hoch, die der Server noch nicht kennt. Abschließend antwortet der Server mit einer Erfolgs- oder Fehlermeldung: +Pro Referenz, die Du aktualisierst, schickt Git eine Zeile mit dem alten SHA, dem neuen SHA und der jeweiligen Referenz, die aktualisiert wird. Die erste Zeile listet zudem die Server-Features auf. Als nächstes lädt der Client ein Packfile aller Objekte hoch, die der Server noch nicht kennt. Abschließend antwortet der Server mit einer Erfolgs- oder Fehlermeldung: 000Aunpack ok -#### Downloading Data #### +#### Daten herunterladen #### -Wenn Du Daten herunterlädst, sind daran die `fetch-pack` und `upload-pack` Prozesse beteiligt. Der Client startet einen `fetch-pack` Prozess, der sich mit einem `upload-pack` Prozess auf dem Server verbindet, um auszuhandeln, welche Daten heruntergeladen werden sollen. +Wenn Du Daten herunterlädst, sind daran die Prozesse `fetch-pack` und `upload-pack` beteiligt. Der Client startet einen `fetch-pack`-Prozess, der sich mit einem `upload-pack`-Prozess auf dem Server verbindet, um auszuhandeln, welche Daten heruntergeladen werden sollen. -Es gibt verschiedene Möglichkeiten, den `upload-pack` Prozess auf dem Server zu starten: einerseits via SSH auf die gleiche Weise wie den `receive-pack` Prozess. Und adnererseits über den Git Daemon, der standardmäßig auf dem Server auf dem Port 9418 läuft. Der `fetch-pack` Prozess schickt etwa folgendes an den Daemon: +Es gibt verschiedene Möglichkeiten, den `upload-pack`-Prozess auf dem Server zu starten: einerseits via SSH auf die gleiche Weise wie den `receive-pack`-Prozess. Und adnererseits über den Git-Daemon, der standardmäßig auf dem Server auf dem Port 9418 läuft. Der `fetch-pack`-Prozess schickt etwa Folgendes an den Daemon: 003fgit-upload-pack schacon/simplegit-progit.git\0host=myserver.com\0 -Diese Zeile beginnt wiederum mit 4 Bytes, die angeben, wieviel Daten folgen. Dann kommt der auszuführende Befehl und ein Null Byte, und schließlich der Hostname des Servers und ein weiteres Null Byte. Der Git Daemon prüft, ob der Befehl ausgeführt werden kann, das Repository existiert und Schreibzugriff erlaubt. Wenn alles stimmt, startet er den `upload-pack` Prozess und gibt den Request dorthin weiter. +Diese Zeile beginnt wiederum mit 4 Bytes, die angeben, wieviel Daten folgen. Dann kommt der auszuführende Befehl und ein Null-Byte, und schließlich der Hostname des Servers und ein weiteres Null-Byte. Der Git-Daemon prüft, ob der Befehl ausgeführt werden kann, das Repository existiert und Schreibzugriff erlaubt. Wenn alles stimmt, startet er den `upload-pack`-Prozess und gibt den Request dorthin weiter. -Wenn Du den `fetch` Befehl über SSH verwendest, führt `fetch-pack` statt dessen etwas aus wie: +Wenn Du den `fetch`-Befehl über SSH verwendest, führt `fetch-pack` stattdessen etwas aus wie: $ ssh -x git@github.com "git-upload-pack 'schacon/simplegit-progit.git'" -In beiden Fällen wird, nachdem `fetch-pack` verbunden ist, `upload-pack` eine Antwort wie die folgende zurück schicken: +In beiden Fällen wird, nachdem `fetch-pack` verbunden ist, `upload-pack` eine Antwort wie die folgende zurückschicken: 0088ca82a6dff817ec66f44342007202690a93763949 HEAD\0multi_ack thin-pack \ side-band side-band-64k ofs-delta shallow no-progress include-tag @@ -1051,11 +1051,11 @@ In beiden Fällen wird, nachdem `fetch-pack` verbunden ist, `upload-pack` eine A -Die Antwort ähnelt der, mit der `receive-pack` antwortet, aber die aufgelisteten Features sind andere. Zusätzlich wird die HEAD Referenz mitgeschickt, sodass der Client weiß, was er auschecken muss, falls es sich um einen Clone handelt. +Die Antwort ähnelt der, mit der `receive-pack` antwortet, aber die aufgelisteten Features sind andere. Zusätzlich wird die HEAD-Referenz mitgeschickt, sodass der Client weiß, was er auschecken muss, falls es sich um einen Clone handelt. -Der `fetch-pack` Prozess inspiziert jetzt die vorhandenen Objekte und antwortet mit einer Liste von Objekten, wobei er das Schlüsselwort „want“ für Objekte verwendet, die benötigt werden, und „have“ für Objekte, die bereits vorhanden sind. Am Ende der Liste folgt das Schlüsselwort „done“. Der `upload-pack` Prozess schickt dann ein Packfile mit allen benötigten Objekten: +Der `fetch-pack`-Prozess inspiziert jetzt die vorhandenen Objekte und antwortet mit einer Liste von Objekten, wobei er das Schlüsselwort „want“ für Objekte verwendet, die benötigt werden, und „have“ für Objekte, die bereits vorhanden sind. Am Ende der Liste folgt das Schlüsselwort „done“. Der `upload-pack`-Prozess schickt dann ein Packfile mit allen benötigten Objekten: 0054want ca82a6dff817ec66f44342007202690a93763949 ofs-delta 0032have 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 @@ -1064,14 +1064,14 @@ Der `fetch-pack` Prozess inspiziert jetzt die vorhandenen Objekte und antwortet -Das ist ein sehr einfaches Beispiel. In komplexeren Fällen unterstützt der Client die `multi_ack` oder `side-band` Features. Aber obiges Beispiel verdeutlicht den grundlegenden Request-Response Zyklus der Smart Protokoll Prozesse. +Das ist ein sehr einfaches Beispiel. In komplexeren Fällen unterstützt der Client die Features `multi_ack` oder `side-band`. Aber obiges Beispiel verdeutlicht den grundlegenden Request-Response Zyklus der Prozesse bei schlauen Protokollen. ## Wartung und Datenwiederherstellung ## -Gelegentlich will man ein bisschen aufräumen – ein Repository verdichten, ein importiertes Repository entfernen (xxx) oder verloren gegangene Daten wieder herstellen. Dieses Kapitel wird sich mit einigen derartigen Szenarien befassen. +Gelegentlich will man ein bisschen aufräumen – ein Repository verdichten, ein importiertes Repository aufräumen oder verloren gegangene Daten wieder herstellen. Dieses Kapitel wird sich mit einigen derartigen Szenarien befassen. ### Wartung ### @@ -1088,7 +1088,7 @@ Du kannst `auto gc` wie folgt manuell ausführen: -Wie schon erwähnt tut dies normalerweise gar nichts. Es müssen sich etwa 7.000 lose Objekte oder mehr als 50 Packfiles angesammelt haben, bevor Git tatsächlich die Garbage Collection startet. Du kannst diese Werte mit Hilfe der `gc.auto` bzw. `gc.autopacklimit` Konfigurationsvariablen manuell setzen. +Wie schon erwähnt tut dies normalerweise gar nichts. Es müssen sich etwa 7.000 lose Objekte oder mehr als 50 Packfiles angesammelt haben, bevor Git tatsächlich den echten gc-Befehl startet. Du kannst diese Werte mit Hilfe der Konfigurationsvariablen `gc.auto` bzw. `gc.autopacklimit` manuell setzen. @@ -1102,7 +1102,7 @@ Wie schon erwähnt tut dies normalerweise gar nichts. Es müssen sich etwa 7.000 -Nachdem Du `git gc` ausgeführt hast, werden diese Dateien um der Effizienz willen aus dem `refs` Verzeichnis entfernt und in eine Datei `.git/packed-refs` verschoben, die dann wie folgt aussieht: +Nachdem Du `git gc` ausgeführt hast, werden diese Dateien um der Effizienz willen aus dem `refs`-Verzeichnis entfernt und in eine Datei `.git/packed-refs` verschoben, die dann wie folgt aussieht: $ cat .git/packed-refs # pack-refs with: peeled @@ -1114,22 +1114,22 @@ Nachdem Du `git gc` ausgeführt hast, werden diese Dateien um der Effizienz will -Wenn Du eine Referenz bearbeitest, lässt Git diese Datei unverändert und schreibt statt dessen eine neue Datei nach `refs/heads`. Um einen SHA für eine Referenz nachzuschlagen, schaut Git zunächst im `refs` Verzeichnis und danach erst in der `packed-refs` Datei nach, falls nötig. Wenn eine Referenz also nicht im `refs` Verzeichnis liegt, befindet sie sich wahrscheinlich in `packed-refs` Datei. +Wenn Du eine Referenz bearbeitest, lässt Git diese Datei unverändert und schreibt stattdessen eine neue Datei nach `refs/heads`. Um einen SHA für eine Referenz nachzuschlagen, schaut Git zunächst im `refs`-Verzeichnis und danach erst in der Datei `packed-refs` nach, falls nötig. Wenn eine Referenz also nicht im `refs`-Verzeichnis liegt, befindet sie sich wahrscheinlich in der Datei `packed-refs`. Beachte, dass die letzte Zeile der Datei mit `^` anfängt. Das bedeutet, dass der Tag darüber ein annotierter Tag ist und diese Zeile zeigt den Commit, auf den der annotierte Tag zeigt. -### Daten Wiederherstellung ### +### Daten-Wiederherstellung ### -Irgendwann wird es vielleicht mal vorkommen, dass Du während der Arbeit mit Git einen Commit verlierst. Normalerweise passiert das, wenn Du versehentlich einen Branch löschst, an dem Du gearbeitet hattest und den Du noch brauchst. Oder Du führst `git reset --hard` aus und stellst fest, dass Du einige der Commits noch brauchst. Nehmen wir an, Du steckst in einer solchen Situation – wie kannst Du Deine Commits wieder herstellen? +Irgendwann wird es vielleicht mal vorkommen, dass Du während der Arbeit mit Git einen Commit verlierst. Normalerweise passiert das, wenn Du versehentlich einen Branch löschst, an dem Du gearbeitet hattest und den Du noch brauchst. Oder Du führst `git reset --hard` aus und stellst fest, dass Du einige der Commits noch brauchst. Nehmen wir an, Du steckst in einer solchen Situation – wie kannst Du Deine Commits wiederherstellen? -Das folgende Beispiel setzt zuerst den `master` Branch auf einen älteren Commit zurück und stellt die verlorenen Commits dann wieder her. Zunächst schauen wir uns den gegenwärtigen Zustand des Repositories an: +Das folgende Beispiel setzt zuerst den `master`-Branch auf einen älteren Commit zurück und stellt die verlorenen Commits dann wieder her. Zunächst schauen wir uns den gegenwärtigen Zustand des Repositories an: $ git log --pretty=oneline ab1afef80fac8e34258ff41fc1b867c702daa24b modified repo a bit @@ -1140,7 +1140,7 @@ Das folgende Beispiel setzt zuerst den `master` Branch auf einen älteren Commit -Jetzt setzen wir den `master` Branch zurück auf den mittleren Commit. +Jetzt setzen wir den `master`-Branch zurück auf den mittleren Commit. $ git reset --hard 1a410efbd13591db07496601ebc7a059dd55cfe9 HEAD is now at 1a410ef third commit @@ -1151,11 +1151,11 @@ Jetzt setzen wir den `master` Branch zurück auf den mittleren Commit. -Du hast damit die oberen beiden Commits verloren, d.h. es gibt keinen Branch mehr, von dem aus diese Commits erreichbar wären. Um sie wieder herzustellen kannst Du einen neuen Branch anlegen, der auf den SHA Hash des obersten (letzten) Commits zeigt. Der Trick besteht darin, diesen letzten Commit Hash heraus zu finden. Es ist ja nicht so, dass Du Dir jederzeit all die Hashes merken könntest, oder? +Du hast damit die oberen beiden Commits verloren, d.h. es gibt keinen Branch mehr, von dem aus diese Commits erreichbar wären. Um sie wiederherzustellen, kannst Du einen neuen Branch anlegen, der auf den SHA-Hash des obersten (letzten) Commits zeigt. Der Trick besteht darin, diesen letzten Commit-Hash herauszufinden. Es ist ja nicht so, dass Du Dir jederzeit all die Hashes merken könntest, oder? -In der Regel ist der schnellste Weg, solche Hashes zu finden, der Befehl `git reflog`. Während Du mit Git arbeitest, macht Git im Stillen fortlaufende Notizen darüber, was HEAD ist. Jedes Mal, wenn Du einen Commit anlegst oder den Branch wechselst, wird das „Reflog“ aktualisiert. Das Reflog wird außerdem vom Befehl `git update-ref` verwendet – ein weiterer guter Grund, nicht statt dessen einfach den SHA Wert in eine Referenz Datei zu schreiben (wie wir das in der Sektion „Git Referenzen“ zuvor in diesem Kapitel besprochen haben). Du kannst also jederzeit nachschlagen, woran Du jeweils gearbeitet hast, indem Du den Befehl `git reflog` verwendest: +In der Regel ist der schnellste Weg, solche Hashes zu finden, der Befehl `git reflog`. Während Du mit Git arbeitest, macht Git im Stillen fortlaufende Notizen darüber, was HEAD ist. Jedes Mal, wenn Du einen Commit anlegst oder den Branch wechselst, wird das „Reflog“ aktualisiert. Das Reflog wird außerdem vom Befehl `git update-ref` verwendet – ein weiterer guter Grund, nicht stattdessen einfach den SHA-Wert in eine Referenz-Datei zu schreiben (wie wir das in der Sektion „Git-Referenzen“ zuvor in diesem Kapitel besprochen haben). Du kannst also jederzeit nachschlagen, woran Du jeweils gearbeitet hast, indem Du den Befehl `git reflog` verwendest: $ git reflog 1a410ef HEAD@{0}: 1a410efbd13591db07496601ebc7a059dd55cfe9: updating HEAD @@ -1184,7 +1184,7 @@ Das zeigt also die beiden verloren gegangenen Commits an, die wir zuvor ausgeche -Es sieht also so aus, als sei der untere Commit derjenige, den Du verloren hast, aber noch brauchst. Du kannst ihn jetzt wieder herstellen, indem Du einen neuen Branch erstellst, der auf diesen Commit zeigt. Beispielsweise kannst Du einen Branch `recover-branch` anlegen, der auf den Commit `ab1afef` zeigt: +Es sieht also so aus, als sei der untere Commit derjenige, den Du verloren hast, aber noch brauchst. Du kannst ihn jetzt wiederherstellen, indem Du einen neuen Branch erstellst, der auf diesen Commit zeigt. Beispielsweise kannst Du einen Branch `recover-branch` anlegen, der auf den Commit `ab1afef` zeigt: $ git branch recover-branch ab1afef $ git log --pretty=oneline recover-branch @@ -1197,14 +1197,14 @@ Es sieht also so aus, als sei der untere Commit derjenige, den Du verloren hast, -Sehr gut. Du hast jetzt einen neuen Branch `recover-branch`, der diejenigen Commits enthält, die sich zuvor in Deinem `master` Branch befanden. Damit hast Du wieder Zugriff auf die beiden verloren gegangenen Commits. Als nächstes nehmen wir aber außerdem an, dass diese verlorenen Commits aus irgendeinem Grunde nicht im Reflog enthalten sind – Du kannst das z.B. simulieren, indem Du den Branch `recover-branch` und das Reflog löschst. Damit sind die beiden Commits jetzt von nirgendwo her mehr erreichbar: +Sehr gut. Du hast jetzt einen neuen Branch `recover-branch`, der diejenigen Commits enthält, die sich zuvor in Deinem `master`-Branch befanden. Damit hast Du wieder Zugriff auf die beiden verloren gegangenen Commits. Als nächstes nehmen wir aber außerdem an, dass diese verlorenen Commits aus irgendeinem Grunde nicht im Reflog enthalten sind – Du kannst das z.B. simulieren, indem Du den Branch `recover-branch` und das Reflog löschst. Damit sind die beiden Commits jetzt von nirgendwo her mehr erreichbar: $ git branch -D recover-branch $ rm -Rf .git/logs/ -Das Reflog wird im Verzeichnis `.git/logs/` aufbewahrt, d.h. Du hast nun faktisch kein Reflog mehr. Wie kann man einen Commit jetzt noch wieder herstellen? Eine Möglichkeit dazu ist der Befehl `git fsck`, der die Git Datenbank Integrität prüft. Wenn Du den Befehl mit der Option `--full` ausführst, zeigt er alle Objekte an, auf die nicht von einem anderen Objekt verwiesen wird: +Das Reflog wird im Verzeichnis `.git/logs/` aufbewahrt, d.h. Du hast nun faktisch kein Reflog mehr. Wie kann man einen Commit jetzt noch wiederherstellen? Eine Möglichkeit dazu ist der Befehl `git fsck`, der die Integrität der Git-Datenbank prüft. Wenn Du den Befehl mit der Option `--full` ausführst, zeigt er alle Objekte an, auf die nicht von einem anderen Objekt verwiesen wird: $ git fsck --full dangling blob d670460b4b4aece5915caf5c68d12f560a9fe3e4 @@ -1214,26 +1214,26 @@ Das Reflog wird im Verzeichnis `.git/logs/` aufbewahrt, d.h. Du hast nun faktisc -In diesem Fall findest Du den verlorenen Commit nach dem (xxx dangling xxx) Commit. Du kannst ihn dann auf die selbe Weise wieder herstellen wie zuvor, indem Du einen Branch erstellst, der auf diesen Commit Hash zeigt. +In diesem Fall findest Du den verlorenen Commit nach den Worten „dangling commit“. Du kannst ihn dann auf dieselbe Weise wiederherstellen wie zuvor, indem Du einen Branch erstellst, der auf diesen Commit-Hash zeigt. ### Objekte entfernen ### -Git ist in vielerlei Hinsicht unschlagbar, aber es gibt auch Features, die Probleme verursachen können. Ein solches Problem kann darin bestehen, dass `git clone` die vollständige Historie eines Projektes herunter lädt, d.h. jede einzelne Version jeder einzelnen Datei. Das ist eine feine Sache, solange es sich um Quellcode handelt, den Git ist darauf optimiert, diese Art von Daten effizient zu komprimieren. Wenn allerdings irgendwann einmal eine einzelne, sehr große Datei zur Versionskontrolle hinzugefügt wurde, wird jeder Clone dieses Repositories diese Datei gezwungenermaßen herunter laden müssen – auch dann, wenn die Datei inzwischen aus dem Repository entfernt würde. Weil sie über die Historie erreichbar ist, muss die Datei vorhanden sein. +Git ist in vielerlei Hinsicht unschlagbar, aber es gibt auch Features, die Probleme verursachen können. Ein solches Problem kann darin bestehen, dass `git clone` die vollständige Historie eines Projektes herunterlädt, d.h. jede einzelne Version jeder einzelnen Datei. Das ist eine feine Sache, solange es sich um Quellcode handelt, denn Git ist darauf optimiert, diese Art von Daten effizient zu komprimieren. Wenn allerdings irgendwann einmal eine einzelne, sehr große Datei zur Versionskontrolle hinzugefügt wurde, wird jeder Clone dieses Repositorys diese Datei gezwungenermaßen herunterladen müssen – auch dann, wenn die Datei inzwischen aus dem Repository entfernt würde. Weil sie über die Historie erreichbar ist, muss die Datei vorhanden sein. -Hierin kann ein großes Problem bestehen, wenn Du Subversion oder Perforce Repositories nach Git konvertierst. Weil Du in diesen Systemen nicht die gesamte Historie herunter lädst, kann diese Art von (xxx addition??? hu? xxx) einige unangenehme Konsequenzen haben. Wenn Du Dein Repository aus einem anderen System importiert hast oder aus irgendeinem anderen Grunde findest, dass es sehr viel größer ist als es eigentlich sein sollte, kannst Du große Objekte wie folgt suchen und entfernen. +Hierin kann ein großes Problem bestehen, wenn Du Subversion oder Perforce-Repositorys nach Git konvertierst. Weil Du in diesen Systemen nicht die gesamte Historie herunterlädst, kann diese Art von Hinzufügung einige unangenehme Konsequenzen haben. Wenn Du Dein Repository aus einem anderen System importiert hast oder aus irgendeinem anderen Grunde findest, dass es sehr viel größer ist, als es eigentlich sein sollte, kannst Du große Objekte wie folgt suchen und entfernen. -Sei Dir allerdings bewusst, dass diese Technik die Commit Historie zerstört. Sie schreibt angefangen beim ursprünglichen Tree jedes einzelne Commit Objekt neu, um die jeweilige, große Datei zu entfernen. Wenn Du das direkt nach einem Import tust, d.h. bevor jemand angefangen hat, auf der Basis eines Commits zu arbeiten, ist das in Ordnung – andernfalls müssen alle Mitarbeiter ihre Arbeit auf Deinen Commit rebasen. +Sei Dir allerdings bewusst, dass diese Technik die Commit-Historie zerstört. Sie schreibt angefangen beim ursprünglichen Tree jedes einzelne Commit-Objekt neu, um die jeweilige, große Datei zu entfernen. Wenn Du das direkt nach einem Import tust, d.h. bevor jemand angefangen hat, auf der Basis eines Commits zu arbeiten, ist das in Ordnung – andernfalls müssen alle Mitarbeiter ihre Arbeit auf Deinen Commit rebasen. -Um das zu demonstrieren, werden wir eine große Datei zu Deinem Test Repository hinzufügen, sie dann im nächsten Commit löschen, in der Datenbank nachschlagen und sie schließlich dauerhaft aus dem Repository entfernen. Als erstes committe also eine große Datei in Dein Repository: +Um das zu demonstrieren, werden wir eine große Datei zu Deinem Test-Repository hinzufügen, sie dann im nächsten Commit löschen, in der Datenbank nachschlagen und sie schließlich dauerhaft aus dem Repository entfernen. Als erstes committe also eine große Datei in Dein Repository: $ curl http://kernel.org/pub/software/scm/git/git-1.6.3.1.tar.bz2 > git.tbz2 $ git add git.tbz2 @@ -1255,7 +1255,7 @@ Oha. Du wolltest keinen dermaßen großen Tarball in Deinem Projekt. Am besten l -Jetzt lassen wir die Garbage Collection über die Datenbank laufen und sehen, wieviel Platz sie braucht: +Jetzt lassen wir die Garbage-Collection über die Datenbank laufen und sehen, wieviel Platz sie braucht: $ git gc Counting objects: 21, done. @@ -1266,7 +1266,7 @@ Jetzt lassen wir die Garbage Collection über die Datenbank laufen und sehen, wi -Du kannst auch den `count-objects` Befehl laufen lassen, um einen schnellen Überblick darüber zu erhalten, wieviel Platz das Repository einnimmt: +Du kannst auch den Befehl `count-objects` laufen lassen, um einen schnellen Überblick darüber zu erhalten, wieviel Platz das Repository einnimmt: $ git count-objects -v count: 4 @@ -1279,11 +1279,11 @@ Du kannst auch den `count-objects` Befehl laufen lassen, um einen schnellen Übe -Der `size-pack` Eintrag zeigt die Größe der Packfiles in Kilobytes, d.h. Dein Repository braucht 2 MB. Vor dem letzten Commit lag dieser Wert eher bei 2 KB. D.h., die Datei wurde im letzten Commit eindeutig nicht aus der History entfernt. Jedes Mal, wenn jemand künftig dieses sehr kleine Repository clont, wird er die 2 MB mit herunterladen müssen – nur weil wir versehentlich diese große Datei hinzugefügt hatten. Also versuchen wir, sie endgültig los zu werden. +Der `size-pack`-Eintrag zeigt die Größe der Packfiles in Kilobytes, d.h. Dein Repository braucht 2 MB. Vor dem letzten Commit lag dieser Wert eher bei 2 KB. D.h., die Datei wurde im letzten Commit eindeutig nicht aus der History entfernt. Jedes Mal, wenn jemand künftig dieses sehr kleine Repository clont, wird er die 2 MB mit herunterladen müssen – nur weil wir versehentlich diese große Datei hinzugefügt hatten. Also versuchen wir, sie endgültig loszuwerden. -Zunächst mal müssen wir sie finden. In diesem Fall wissen wir bereits, um welche Datei es sich handelt. Aber nehmen wir an, wir wüssten es nicht. Wie würdest Du herausfinden, welche Datei (oder welche Dateien) so viel Platz verbrauchen? Wenn Du `git gc` laufen gelassen hast, werden sich alle Objekte in einem Packfile befinden. Du kannst dann große Objekte identifizieren, indem Du einen weiteren Plumbing Befehl, nämlich `git verify-pack` ausführst und nach dem dritten Feld der Ausgabe sortierst, d.h. der Dateigröße. Du kannst sie außerdem durch den `tail` Befehl leiten, denn Du bist ja nur an den wenigen größten Objekten interessiert: +Zunächst mal müssen wir sie finden. In diesem Fall wissen wir bereits, um welche Datei es sich handelt. Aber nehmen wir an, wir wüssten es nicht. Wie würdest Du herausfinden, welche Datei (oder welche Dateien) so viel Platz verbrauchen? Wenn Du `git gc` laufen gelassen hast, werden sich alle Objekte in einem Packfile befinden. Du kannst dann große Objekte identifizieren, indem Du einen weiteren Plumbing-Befehl, nämlich `git verify-pack` ausführst und nach dem dritten Feld der Ausgabe sortierst, d.h. der Dateigröße. Du kannst sie außerdem durch den `tail` Befehl leiten, denn Du bist ja nur an den wenigen größten Objekten interessiert: $ git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3 e3f094f522629ae358806b17daf78246c27c007b blob 1486 734 4667 @@ -1292,14 +1292,14 @@ Zunächst mal müssen wir sie finden. In diesem Fall wissen wir bereits, um welc -Das größte Objekt ist ganz klar das letzte: es ist 2 MB groß. Um herauszufinden, welche Datei das ist, kannst Du den `rev-list` Befehl verwenden, den wir in Kapitel 7 schon einmal kurz verwendet haben. Wenn Du die Optionen `--objects` und `rev-list` verwendest, werden alle Commit und Blob SHAs mit den jeweiligen Dateipfaden aufgelistet, die mit ihnen assoziiert sind. Auf diese Weise kannst Du den Namen des Blobs finden: +Das größte Objekt ist ganz klar das letzte: es ist 2 MB groß. Um herauszufinden, welche Datei das ist, kannst Du den `rev-list` Befehl verwenden, den wir in Kapitel 7 schon einmal kurz verwendet haben. Wenn Du die Optionen `--objects` und `rev-list` verwendest, werden alle Commit- und Blob-SHAs mit den jeweiligen Dateipfaden aufgelistet, die mit ihnen assoziiert sind. Auf diese Weise kannst Du den Namen des Blobs finden: $ git rev-list --objects --all | grep 7a9eb2fb 7a9eb2fba2b1811321254ac360970fc169ba2330 git.tbz2 -Du musst diese Datei jetzt aus allen Trees entfernen, in denen er sich befindet. Du kannst leicht herausfinden, welche Commits diese Datei verändert haben: +Du musst diese Datei jetzt aus allen Trees entfernen, in denen sie sich befindet. Du kannst leicht herausfinden, welche Commits diese Datei verändert haben: $ git log --pretty=oneline --branches -- git.tbz2 da3f30d019005479c99eb4c3406225613985a1db oops - removed large tarball @@ -1307,7 +1307,7 @@ Du musst diese Datei jetzt aus allen Trees entfernen, in denen er sich befindet. -Es geht also darum, alle Commits angefangen bei `6df76` neu zu schreiben, sodass der Tarball nicht mehr in Deiner Git Historie enthalten ist. Um das zu erreichen, verwendest Du den Befehl `git filter-branch`, den wir schon mal in Kapitel 6 verwendet haben: +Es geht also darum, alle Commits angefangen bei `6df76` neu zu schreiben, sodass der Tarball nicht mehr in Deiner Git-Historie enthalten ist. Um das zu erreichen, verwendest Du den Befehl `git filter-branch`, den wir schon mal in Kapitel 6 verwendet haben: $ git filter-branch --index-filter \ 'git rm --cached --ignore-unmatch git.tbz2' -- 6df7640^.. @@ -1317,7 +1317,7 @@ Es geht also darum, alle Commits angefangen bei `6df76` neu zu schreiben, sodass -Die `--index-filter` Option ist ähnlich der `--tree-filter` Option aus Kapitel 6. Allerdings übergibt man in diesem Fall nicht einen Befehl, der die Dateien verändert, die sich jeweils ausgecheckt auf der Festplatte befinden. Statt dessen verändert man jeweils die Staging Area bzw. den Index. Statt eine bestimmte Datei mit z.B: `rm file` zu entfernen, müssen wir also `git rm --cached` verwenden – denn wir wollen sie aus dem Index, nicht von der Festplatte löschen. Der Grund dafür ist einfach Geschwindigkeit: Git braucht nicht jede einzelne Revision auf die Festplatte auszuchecken, um den Filter anzuwenden. Auf diese Weise läuft der ganze Prozess sehr viel schneller. Man kann dieselbe Aufgabe aber auch mit `--tree-filter` erledigen, wenn man will. Die Option `--ignore-match` weist Git an, nicht mit einer Fehlermeldung abzubrechen, wenn die Datei, die wir löschen wollen, nicht vorhanden ist. Außerdem teilen wir `filter-branch` mit, die Historie nur von dem Commit `6df7640` an umzuschreiben. Andernfalls würde der Befehl von ganz vorn beginnen und unnötig länger brauchen. +DieOption `--index-filter` ist ähnlich der Option `--tree-filter` aus Kapitel 6. Allerdings übergibt man in diesem Fall nicht einen Befehl, der die Dateien verändert, die sich jeweils ausgecheckt auf der Festplatte befinden. Stattdessen verändert man jeweils die Staging-Area bzw. den Index. Statt eine bestimmte Datei mit z.B: `rm file` zu entfernen, müssen wir also `git rm --cached` verwenden – denn wir wollen sie aus dem Index, nicht von der Festplatte löschen. Der Grund dafür ist einfach Geschwindigkeit: Git braucht nicht jede einzelne Revision auf die Festplatte auszuchecken, um den Filter anzuwenden. Auf diese Weise läuft der ganze Prozess sehr viel schneller. Man kann dieselbe Aufgabe aber auch mit `--tree-filter` erledigen, wenn man will. Die Option `--ignore-match` weist Git an, nicht mit einer Fehlermeldung abzubrechen, wenn die Datei, die wir löschen wollen, nicht vorhanden ist. Außerdem teilen wir `filter-branch` mit, die Historie nur von dem Commit `6df7640` an umzuschreiben. Andernfalls würde der Befehl von ganz vorn beginnen und unnötig länger brauchen. @@ -1347,15 +1347,15 @@ Prüfen wir also, wieviel Platz wir damit eingespart haben: -Das gepackte Repository umfasst jetzt nur noch 7K – sehr viel besser als die vorherigen 2MB. Du kannst an dem Wert `size` erkennen, dass sich die große Datei selbst jetzt immer noch in Deinen loosen Objekten befindet. Aber sie wird bei einem `git push` oder anschließenden `git clone` nicht übermittelt werden – und das war unser Ziel. Wenn Du das wirklich willst, kannst Du sie jetzt vollständig und endgültig mit `git prune --expire` aus Deinem Repository löschen. +Das gepackte Repository umfasst jetzt nur noch 7K – sehr viel besser als die vorherigen 2MB. Du kannst an dem Wert `size` erkennen, dass sich die große Datei selbst jetzt immer noch in Deinen losen Objekten befindet. Aber sie wird bei einem `git push` oder anschließenden `git clone` nicht übermittelt werden – und das war unser Ziel. Wenn Du das wirklich willst, kannst Du sie jetzt vollständig und endgültig mit `git prune --expire` aus Deinem Repository löschen. ## Zusammenfassung ## -Du solltest jetzt ein gutes Verständnis davon haben, was Git im Hintergrund tut, und in einem gewissen Maße auch davon, wie es implementiert ist. In diesem Kapitel haben wir eine Reihe von Plumbing Befehlen besprochen, als Befehlen, die grundlegender und einfacher als die Porzellan Befehle sind, um die es im restlichen Buch ging. Dieses Verständnis sollte Dir helfen, zu verstehen, warum Git tut, was es tut – und natürlich auch dabei, Deine eigenen Werkzeuge und Hilfsskripte zu schreiben, um einen bestimmten Workflow für Dich anzupassen. +Du solltest jetzt ein gutes Verständnis davon haben, was Git im Hintergrund tut, und in einem gewissen Maße auch davon, wie es implementiert ist. In diesem Kapitel haben wir eine Reihe von Plumbing-Befehlen besprochen, also Befehlen, die grundlegender und einfacher als die Porcelain-Befehle sind, um die es im restlichen Buch ging. Dieses Verständnis sollte Dir helfen, zu verstehen, warum Git tut, was es tut – und natürlich auch dabei, Deine eigenen Werkzeuge und Hilfsskripte zu schreiben, um einen bestimmten Arbeitsablauf für Dich anzupassen. -Git als ein Dateisystem, das Inhalte addressieren kann, ist ein äußerst mächtiges Werkzeug, das Du leicht als mehr als „nur“ als (xxx) ein VCS einsetzen kannst. Ich hoffe, Du kannst Dein neugewonnenes Wissen der Git Interna nutzen, um Deine eigene tolle Anwendung dieser Technologie zu implementieren und Dich wohler damit zu fühlen, Git auch in fortgeschrittener Weise zu benutzen. +Git als ein Dateisystem, das Inhalte addressieren kann, ist ein äußerst mächtiges Werkzeug, das Du leicht für mehr als „nur“ als VCS einsetzen kannst. Ich hoffe, Du kannst Dein neugewonnenes Wissen der Git-Interna nutzen, um Deine eigene tolle Anwendung dieser Technologie zu implementieren und Dich wohler damit zu fühlen, Git auch in fortgeschrittener Weise zu benutzen. From 8c361261d251c6fd9500ebc01d4ea729c73b1ad1 Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 19 Jan 2014 17:00:08 +0100 Subject: [PATCH 114/690] [de] Connect compound nouns with dash --- de/06-git-tools/01-chapter6.markdown | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index 31bcf958a..ed355aee2 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -95,7 +95,7 @@ Allerdings solltest Du Dir bewusst machen, wie unglaublich unwahrscheinlich dies Hier ist ein Beispiel, das Dir eine Vorstellung davon gibt, was nötig ist, um in SHA-1 eine Kollision zu bekommen. Wenn alle 6,5 Milliarden Menschen auf der Erde programmieren würden und jeder jede Sekunde Code schreiben würde, der der gesamten Geschichte des Linux-Kernels (1 Million Git-Objekte) entspricht, und diesen dann in ein gigantisches Git-Repository übertragen würde, würde es fünf Jahre dauern, bis das Repository genügend Objekte hätte, um eine 50% Wahrscheinlichkeit für eine einzige SHA-1-Kollision aufzuweisen. Es ist wahrscheinlicher, dass jedes Mitglied Deines Programmierer-Teams, unabhängig voneinander, in einer Nacht von Wölfen angegriffen und getötet wird. -### Branch Referenzen ### +### Branch-Referenzen ### @@ -274,7 +274,7 @@ Du willst jetzt herausfinden, welche Änderungen in Deinem `experiment`-Branch s -Wenn Du allerdings – anders herum – diejenigen Commits anzeigen willst, die in `master`, aber noch nicht in `experiment` sind, kannst Du die Branch Namen umdrehen: `experiment..master` zeigt „alles in `master`, das nicht in `experiment` enthalten ist“. +Wenn Du allerdings – anders herum – diejenigen Commits anzeigen willst, die in `master`, aber noch nicht in `experiment` sind, kannst Du die Branch-Namen umdrehen: `experiment..master` zeigt „alles in `master`, das nicht in `experiment` enthalten ist“. $ git log experiment..master F @@ -314,7 +314,7 @@ Das ist praktisch, weil Du auf diese Weise mehr als nur zwei Referenzen angeben Damit hast Du ein sehr mächtiges System von Abfragen zur Verfügung, mit denen Du herausfinden kannst, was in welchen Deiner Branches enthalten ist. -#### Drei-Punkte Syntax #### +#### Drei-Punkte-Syntax #### @@ -472,7 +472,7 @@ Um einen Diff dessen zu sehen, das Du gestaget hast, kannst Du den Befehl `6` od -Mit diesen grundlegenden Befehlen kannst Du den interaktiven add Modus nutzen, um Dir den Umgang mit Deiner Staging-Area etwas zu erleichtern. +Mit diesen grundlegenden Befehlen kannst Du den interaktiven Hinzufüge-Modus nutzen, um Dir den Umgang mit Deiner Staging-Area etwas zu erleichtern. ### Patches stagen ### @@ -895,7 +895,7 @@ Man kann mit Git einen einzelnen Commit auch aufsplitten. Das bedeutet, man setz -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 dass die Änderungen im Arbeitsverzeichnis zurückgesetzt werden. Das heißt, der Commit im Repository wird 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: +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 dass die Änderungen im Arbeitsverzeichnis zurückgesetzt werden. Das heißt, der Commit im Repository wird 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 @@ -1131,7 +1131,7 @@ Nehmen wir einmal an, dass Du die Rack-Bibliothek (eine Ruby-Gateway-Schnittstel -Innerhalb Deines Projekts befindet sich nun im Unterverzeichnis `rack` das komplette Rack-Projekt. Man kann jetzt in diesem Verzeichnis Änderungen vornehmen und ein eigenes Remote Repository mit Schreibrechten, zu welchem man pushen kann, hinzufügen. Ebenso ist es möglich, Änderungen von den Rack-Entwicklern in sein Repository zu laden und diese mit den eigenen Ergebnissen zu mergen. Im Prinzip kann man innerhalb eines Submoduls die gleichen Vorgänge, wie in einem normalen Repository ausführen. Vorher müssen wir aber noch ein paar weitere Dinge zu Submodulen besprechen. Wenn Du gleich nach dem Hinzufügen des Submoduls, den Befehl `git status` ausführst, wirst Du gleich zwei Dinge bemerken: +Innerhalb Deines Projekts befindet sich nun im Unterverzeichnis `rack` das komplette Rack-Projekt. Man kann jetzt in diesem Verzeichnis Änderungen vornehmen und ein eigenes Remote-Repository mit Schreibrechten, zu welchem man pushen kann, hinzufügen. Ebenso ist es möglich, Änderungen von den Rack-Entwicklern in sein Repository zu laden und diese mit den eigenen Ergebnissen zu mergen. Im Prinzip kann man innerhalb eines Submoduls die gleichen Vorgänge, wie in einem normalen Repository ausführen. Vorher müssen wir aber noch ein paar weitere Dinge zu Submodulen besprechen. Wenn Du gleich nach dem Hinzufügen des Submoduls, den Befehl `git status` ausführst, wirst Du gleich zwei Dinge bemerken: $ git status # On branch master From a3809eadd47e8974b82c711164c9192c5a6dceb2 Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 19 Jan 2014 17:03:43 +0100 Subject: [PATCH 115/690] [de] Use "Branch master" instead of "Master-Branch" - master is a special term in Git terminology - It is used in other sections in the exact same manner --- de/06-git-tools/01-chapter6.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index ed355aee2..fa81fd758 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -942,7 +942,7 @@ Die Option `--tree-filer` führt den nachfolgenden Befehl nach jedem Auschecken -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. +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 Branch master 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 #### @@ -1471,7 +1471,7 @@ Wenn Du jetzt einen Commit ausführst, erscheint es einem so, als ob die ganzen -Danach kann man diese Änderungen wieder in den master-Branch mergen. Wenn man den Befehl `git merge -s subtree` verwendet, sollte dies einwandfrei funktionieren. Allerdings wird Git bei Ausführen dieses Befehls auch die jeweilige Historie mergen, was Du wahrscheinlich nicht haben möchtest. Um nun die Änderungen zu holen und eine entsprechende Commit-Nachricht vorzubereiten, hängt man einfach `--squash`, `--no-commit` und natürlich `-s subtree` als Option an: +Danach kann man diese Änderungen wieder in den Branch master mergen. Wenn man den Befehl `git merge -s subtree` verwendet, sollte dies einwandfrei funktionieren. Allerdings wird Git bei Ausführen dieses Befehls auch die jeweilige Historie mergen, was Du wahrscheinlich nicht haben möchtest. Um nun die Änderungen zu holen und eine entsprechende Commit-Nachricht vorzubereiten, hängt man einfach `--squash`, `--no-commit` und natürlich `-s subtree` als Option an: $ git checkout master $ git merge --squash -s subtree --no-commit rack_branch @@ -1480,7 +1480,7 @@ Danach kann man diese Änderungen wieder in den master-Branch mergen. Wenn man d -Die ganzen Änderungen des Rack-Projekts wurden nun zusammengeführt, Du musst jetzt nur noch einen entsprechenden Commit durchführen. Man kann aber auch genau das Gegenteil machen: Man führt Änderungen im Unterverzeichnis `rack` des master-Branches aus und mergt diese dann später in den Zweig `rack_branch`. Diesen kann man dann den Entwicklern des Rack-Projekts zur Verfügung stellen. +Die ganzen Änderungen des Rack-Projekts wurden nun zusammengeführt, Du musst jetzt nur noch einen entsprechenden Commit durchführen. Man kann aber auch genau das Gegenteil machen: Man führt Änderungen im Unterverzeichnis `rack` des Branches master aus und mergt diese dann später in den Zweig `rack_branch`. Diesen kann man dann den Entwicklern des Rack-Projekts zur Verfügung stellen. From db6eb4147a6b88549f695ee7a39379b8f154f76d Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 19 Jan 2014 17:09:37 +0100 Subject: [PATCH 116/690] [de] Use correct plural Repositorys instead of Repositories --- de/06-git-tools/01-chapter6.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index fa81fd758..edd87d1ba 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -289,7 +289,7 @@ Dies ist nützlich, wenn Du vorhast, den `experiment`-Branch zu aktualisieren, u -Dieser Befehl zeigt Dir alle Commits im gegenwärtigen, lokalen Branch, die noch nicht im `master`-Branch des `origin` Repositories sind. D.h., der Befehl listet diejenigen Commits auf, die auf den Server transferiert würden, wenn Du `git push` benutzt und der aktuelle Branch `origin/master` trackt. Du kannst mit dieser Syntax außerdem eine Seite der beiden Punkte leer lassen. Git nimmt dann an, Du meinst an dieser Stelle HEAD. Z.B. kannst Du dieselben Commits wie im vorherigen Beispiel auch mit `git log origin/master..` anzeigen lassen. Git fügt dann HEAD auf der rechten Seite ein. +Dieser Befehl zeigt Dir alle Commits im gegenwärtigen, lokalen Branch, die noch nicht im `master`-Branch des `origin` Repositorys sind. D.h., der Befehl listet diejenigen Commits auf, die auf den Server transferiert würden, wenn Du `git push` benutzt und der aktuelle Branch `origin/master` trackt. Du kannst mit dieser Syntax außerdem eine Seite der beiden Punkte leer lassen. Git nimmt dann an, Du meinst an dieser Stelle HEAD. Z.B. kannst Du dieselben Commits wie im vorherigen Beispiel auch mit `git log origin/master..` anzeigen lassen. Git fügt dann HEAD auf der rechten Seite ein. #### Mehrfache Punkte (xxx) #### From 86258cf596d9bfc27fe1e2e742c156d5f124c65e Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 19 Jan 2014 17:22:28 +0100 Subject: [PATCH 117/690] [de] Review paragraphs marked with "xxx" and fix them --- de/06-git-tools/01-chapter6.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index edd87d1ba..1362c864f 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -258,7 +258,7 @@ Nachdem Du jetzt einzelne Commits spezifizieren kannst, schauen wir uns an, wie -Die gängigste Weise, Commit-Reihen anzugeben, ist die Zwei-Punkte-Notation. Allgemein gesagt evaluiert Git eine Reihe von Commits, die von einem Commit aus erreichbar sind, nicht aber von einem anderen (xxx ??? xxx). Nehmen wir z.B. an, Du hättest eine Commit-Historie wie die folgende (Bild 6-1). +Die gängigste Weise, Commit-Reihen anzugeben, ist die Zwei-Punkte-Notation. Allgemein gesagt liefert Git damit eine Reihe von Commits, die von dem einem Commit aus erreichbar sind, allerdings nicht von dem anderen aus. Nehmen wir z.B. an, Du hättest eine Commit-Historie wie die folgende (Bild 6-1). @@ -292,7 +292,7 @@ Dies ist nützlich, wenn Du vorhast, den `experiment`-Branch zu aktualisieren, u Dieser Befehl zeigt Dir alle Commits im gegenwärtigen, lokalen Branch, die noch nicht im `master`-Branch des `origin` Repositorys sind. D.h., der Befehl listet diejenigen Commits auf, die auf den Server transferiert würden, wenn Du `git push` benutzt und der aktuelle Branch `origin/master` trackt. Du kannst mit dieser Syntax außerdem eine Seite der beiden Punkte leer lassen. Git nimmt dann an, Du meinst an dieser Stelle HEAD. Z.B. kannst Du dieselben Commits wie im vorherigen Beispiel auch mit `git log origin/master..` anzeigen lassen. Git fügt dann HEAD auf der rechten Seite ein. -#### Mehrfache Punkte (xxx) #### +#### Mehrere Bezugspunkte #### @@ -373,7 +373,7 @@ Wie Du siehst, zeigt dieser Befehl eine andere Ansicht der Staging-Area an – i Danach folgt eine Liste von Befehlen wie, u.a., Dateien ganz oder teilweise stagen und unstagen, nicht versionskontrollierte Dateien hinzufügen, Diffs der gestageten Änderungen anzeigen etc. -### Dateien stagen und unstagen (xxx) ### +### Hinzufügen und Enfernen von Dateien aus der Staging-Area ### From 472dbeabe6fe29cb053abf3c61193ceed028700f Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 19 Jan 2014 17:24:32 +0100 Subject: [PATCH 118/690] [de] Numbers less than twelve are written-out --- de/06-git-tools/01-chapter6.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index 1362c864f..e5b3a555f 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -479,7 +479,7 @@ Mit diesen grundlegenden Befehlen kannst Du den interaktiven Hinzufüge-Modus nu -Es ist für Git auch möglich, bestimmte Teile einer Datei zu stagen und nicht den Rest. Wenn Du z.B. 2 Veränderungen an der simplegit.rb machst und eine davon stagen willst und die andere nicht, ist dies sehr einfach in Git möglich. Wähle `5` oder `p` (für patch) auf dem interaktiven Prompt. Git wird Dich fragen, welche Dateien Du teilweise stagen willst; dann wird es für jeden Abschnitt der gewählten Dateien Diff-Ausschnitte ausgeben und Dich jeweils einzeln fragen, ob Du sie stagen willst. +Es ist für Git auch möglich, bestimmte Teile einer Datei zu stagen und nicht den Rest. Wenn Du z.B. zwei Veränderungen an der simplegit.rb machst und eine davon stagen willst und die andere nicht, ist dies sehr einfach in Git möglich. Wähle `5` oder `p` (für patch) auf dem interaktiven Prompt. Git wird Dich fragen, welche Dateien Du teilweise stagen willst; dann wird es für jeden Abschnitt der gewählten Dateien Diff-Ausschnitte ausgeben und Dich jeweils einzeln fragen, ob Du sie stagen willst. diff --git a/lib/simplegit.rb b/lib/simplegit.rb index dd5ecc4..57399e0 100644 From e64ed85756c1ce083258dcb8d8c83e85f170eeb0 Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 19 Jan 2014 17:24:40 +0100 Subject: [PATCH 119/690] [de] Fix typo --- de/06-git-tools/01-chapter6.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/de/06-git-tools/01-chapter6.markdown b/de/06-git-tools/01-chapter6.markdown index e5b3a555f..aec049519 100644 --- a/de/06-git-tools/01-chapter6.markdown +++ b/de/06-git-tools/01-chapter6.markdown @@ -76,7 +76,7 @@ Git kann auch selber eine Kurzform für Deine einzigartigen SHA-1-Werte erzeugen Generell kann man sagen, dass acht bis zehn Zeichen mehr als ausreichend in einem Projekt sind, um eindeutig zu bleiben. Eines der größten Git-Projekte, der Linux-Kernel, fängt langsam an 12 von maximal 40 Zeichen zu nutzen, um eindeutig zu bleiben. -### EINE KURVE NOTIZ ÜBER SHA-1 ### +### Ein kurzer Hinweis zu SHA-1 ### From f4ff8e4edcc3874470ff63044cc2158612290d1a Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Sun, 19 Jan 2014 19:59:42 +0100 Subject: [PATCH 120/690] [de] Update status of chapter 6 and add some git specific terms --- de/README.md | 62 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/de/README.md b/de/README.md index d9e8abcad..5d72f1653 100644 --- a/de/README.md +++ b/de/README.md @@ -63,6 +63,50 @@ Beispiel: * Bei englischen Nomen, die auf "y" enden, wird beim Plural nur ein einzelnes "s" angehängt (kein ies). Siehe hierzu auch http://www.duden.de/sprachwissen/sprachratgeber/crashkurs--in-25-schritten-zur-neuen-rechtschreibung +#### Schreibweise von verschiedenen Git-Begriffen #### + +##### A - D ##### + +* Branch (Plural: Branches) +* Branch-Name +* Branch-Referenz (Plural: Branch-Referenzen) +* Commit +* Commit-Datum +* Commit-ID +* Commit-Objekt (Plural: Commit-Objekte) +* Commit-Nachricht +* Drei-Punkte-Syntax + +##### E - H ##### + +* Git-Repository +* HEAD +* HEAD-Referenz + +##### I - Q ##### + +* der Klon (Plural: Klone) +* Low-Level-Operation + +##### R - T ##### + +* Reflog-Ausgabe +* Remote-Repository +* Repository (Plural: Repositorys) +* SHA-1 +* SHA-1-Hash (Genitiv: SHA-1-Hashes) +* SHA-1-Hashwert (Plural: SHA-1-Hashwerte) +* SHA-1-Prüfsumme +* SHA-1-Wert +* stagen (gestaget, ungestaget) +* Staging-Area +* Stash +* stashen + +##### U - Z ##### + +* Zwei-Punkte-Syntax + ### Übersetzung von Git spezifischen Begriffen ### Wir versuchen die englischen Fachbegriffe, die in der Welt von Git existieren, zu benutzen. Zusätzlich versuchen wir aber immer, dass ein neu eingeführter Git-spezifischer Begriff, auch auf Deutsch erklärt wird. @@ -379,63 +423,63 @@ Bitte den Status nicht aktualisieren. Dies übernimmt ein Maintainer. Ja Nein Ja -Review notwendig +Ok 6.1 Ja Nein Ja -Review notwendig +Ok 6.2 Ja Nein Ja -Review notwendig +Ok 6.3 Ja Nein Ja -Review notwendig +Ok 6.4 Ja Nein Ja -Review notwendig +Ok 6.5 Ja Nein Ja -Review notwendig +Ok 6.6 Ja Nein Ja -Review notwendig +Ok 6.7 Nein Nein Ja -Übersetzung fehlt +Ok 6.8 Nein Nein Ja -Übersetzung fehlt +Ok 7 From 3fd7e2ac8781a0197afc128c1c1efdecb53d27be Mon Sep 17 00:00:00 2001 From: Cor Date: Mon, 20 Jan 2014 08:18:18 +0100 Subject: [PATCH 121/690] [nl] re-cloned local repository, copied other chapter4 over. --- nl/04-git-server/01-chapter4.markdown | 381 +++++++++++++++++++------- 1 file changed, 278 insertions(+), 103 deletions(-) diff --git a/nl/04-git-server/01-chapter4.markdown b/nl/04-git-server/01-chapter4.markdown index f2bd2ae65..c6bdd3c65 100644 --- a/nl/04-git-server/01-chapter4.markdown +++ b/nl/04-git-server/01-chapter4.markdown @@ -1,24 +1,24 @@ # Git op de Server # -Op dit punt zou je alledaagse taken waarvoor je Git zult gebruiken kunnen doen. Maar, om samen te kunnen werken in Git, zul je een remote repository moeten hebben. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden, omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers bij het repository kunnen, zelfs als jouw computer van het netwerk is – het hebben van een betrouwbaar gezamenlijk repository is vaak handig. Daarom heeft het hebben van een tussenliggend repository waarin je met iemand anders samenwerkt de voorkeur, en daaruit kun je dan pushen en pullen. We zullen dit repository de `Git server` noemen, maar je zult zien dat het over het algemeen maar een klein beetje systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. +Op dit punt zou je alledaagse taken waarvoor je Git zult gebruiken kunnen doen. Maar, om samen te kunnen werken in Git zul je een remote repository moeten hebben. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden, omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers de repository kunnen bereiken, zelfs als jouw computer van het netwerk is – het hebben van een betrouwbare gezamenlijke repository is vaak handig. De voorkeursmethode om met iemand samen te werken is om een tussenliggende repository in te richten waar beide partijen toegang to hebben en om daar naartoe te pushen en vandaan te pullen. We zullen deze repository de `Git server` noemen, maar je zult zien dat het over het algemeen maar een klein beetje systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. -Een Git server draaien is eenvoudig. Als eerste kies je met welke protocollen je je server wilt laten communiceren. Het eerste gedeelte van dit hoofdstuk zullen we de beschikbare protocollen bespreken met de voor- en nadelen van elk. De volgende secties zullen veel voorkomende opstellingen bespreken, die van die protocollen gebruik maken hoe je je server ermee kunt opzetten. Als laatste laten we een paar servers van derden zien, als je het niet erg vindt om je code op iemands server te zetten en niet het gedoe wilt hebben van het opzetten en onderhouden van je eigen server. +Een Git server draaien is eenvoudig. Als eerste kies je met welke protocollen je de server wilt laten communiceren. Het eerste gedeelte van dit hoofdstuk zullen we de beschikbare protocollen bespreken met de voor- en nadelen van elk. De daarop volgende paragrafen zullen we een aantal veel voorkomende opstellingen bespreken die van die protocollen gebruik maken en hoe je je server ermee kunt opzetten. Als laatste laten we een paar servers van derden zien, als je het niet erg vindt om je code op de server van een ander te zetten en niet het gedoe wilt hebben van het opzetten en onderhouden van je eigen server. -Als je geen interesse hebt om je eigen server te draaien, dan kun je de rest overslaan en direct naar het laatste gedeelte van het hoofdstuk gaan om wat mogelijkheden van online accounts te zien en dan door te gaan naar het volgende hoofdstuk, waar we alle zaken bespreken die komen kijken bij het werken met een gedistribueerde versie beheer omgeving. +Als je niet van plan bent om je eigen server te draaien, dan kun je de direct naar de laatste paragraaf van dit hoofdstuk gaan om wat mogelijkheden van online accounts te zien en dan door gaan naar het volgende hoofdstuk, waar we diverse zaken bespreken die komen kijken bij het werken met een gedistribueerde versiebeheer omgeving. -Een remote repository is over het algemeen een _bare repository_ (kale repository) – een Git repository dat geen werkmap heeft. Omdat het repository alleen gebruikt wordt als een samenwerkingspunt, is er geen reden om een snapshot op de schijf te hebben; alleen de Git data. Een kale repository is eenvoudigweg de inhoud van de `.git` map in je project, en niets anders. +Een remote repository is over het algemeen een _bare repository_ (kale repository) – een Git repository dat geen werkmap heeft. Omdat de repository alleen gebruikt wordt als een samenwerkingspunt, is er geen reden om een snapshot op de schijf te hebben; het is alleen de Git data. Een kale repository is eenvoudigweg de inhoud van de `.git` map in je project, en niets meer. ## De Protocollen ## -Git kan vier veel voorkomende netwerk protocollen gebruiken om data te transporteren: Lokaal, Beveiligde Shell (SSH), Git en HTTP. Hier laten we zien wat het zijn, en in welke omstandigheden je ze wilt gebruiken (of juist niet). +Git kan vier veel voorkomende netwerk protocollen gebruiken om data te transporteren: Lokaal, Beveiligde Shell (Secure Shell, SSH), Git en HTTP. Hier bespreken we wat deze zijn, en in welke omstandigheden je ze zou willen gebruiken (of juist niet). -Het is belangrijk om te zien dat, met uitzondering van de HTTP protocollen, ze allemaal een werkende Git versie op de server geinstalleerd moeten hebben. +Het is belangrijk om op te merken dat, met uitzondering van de HTTP protocollen, ze allemaal een werkende Git versie op de server geïnstalleerd moeten hebben. ### Lokaal Protocol ### -Het meest basale is het _lokale protocol_, waarbij het remote repository in een andere map op de schijf is. Dit wordt vaak gebruikt als iedereen in je team toegang heeft op een gedeeld bestandssyteem zoals een NFS map, of in het weinig voorkomende geval dat iedereen in dezelfde computer werkt. Het laatste zou niet ideaal zijn, want dan zouden alle repositories zich op dezelfde computer bevinden, zodat de kans op een fataal verlies veel groter wordt. +Het simpelste is het _Lokale protocol_, waarbij de remote repository in een andere directory op de schijf staat. Deze opzet wordt vaak gebruikt als iedereen in het team toegang heeft op een gedeeld bestandssyteem zoals een NFS mount, of in het weinig voorkomende geval dat iedereen op dezelfde computer werkt. Het laatste zou niet ideaal zijn, want dan zouden alle repositories op dezelfde computer staan, zodat een fataal verlies van gegevens veel groter wordt. -Als je een gedeeld bestandssyteem 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 bestandssyteem hebt, dan kun je clonen, pushen en pullen van een op een lokaal bestand aanwezige 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 het volgende uitvoeren: $ git clone /opt/git/project.git @@ -26,29 +26,29 @@ Of je kunt dit doen: $ git clone file:///opt/git/project.git -Git werkt iets anders als je explicite `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gebruikt om data te transporteren over een netwerk, wat over het algemeen een stuk minder efficiente methode is om data te transporteren. De reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de extra referenties of objecten eruit gelaten – over het algemeen na een import van een ander versie beheer systeem of iets dergelijks (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. +Git werkt iets anders als je explicite `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gesproken gebruikt om data te transporteren over een netwerk, wat over het algemeen een minder efficiënte methode is om gegevens over te dragen. De belangrijkste reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de vreemde refenties of objecten eruit gelaten – over het algemeen na een import uit een ander versiebeheer systeem of iets dergelijks (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. -Om een lokaal repository aan een bestaand Git project toe te voegen, kun je zoiets als dit uitvoeren: +Om een lokale repository aan een bestaand Git project toe te voegen, kun je iets als het volgende uitvoeren: $ git remote add local_proj /opt/git/project.git -Daarna kun je pushen en pullen van dat remote alsof je over een netwerk werkt. +Daarna kun je op gelijke wijze pushen naar, en pullen van die remote als je over een netwerk zou doen. #### De Voordelen #### -De voordelen van bestands-gebaseerde repositories zijn dat ze eenvoudig zijn en ze maken gebruik van bestaande bestandspermissies en netwerk toegang. Als je al een gedeeld bestandssysteem hebt, waar je hele team al toegang tot heeft, dan is een repository opzetten heel gemakkelijk. Je stopt de kale repository ergens waar iedereen gedeelde toegang tot heeft, en stelt de lees- en schrijfrechten in zoals je dat bij iedere andere gedeelde map zou doen. In de volgende sectie "Git op een Server krijgen" bespreken we hoe je een kopie van een kale repository kunt exporteren voor dit doeleind. +De voordelen van bestands-gebaseerde repositories zijn dat ze eenvoudig zijn en ze maken gebruik van bestaande bestandspermissies en netwerk toegang. Als je al een gedeeld bestandssysteem hebt, waar het hele team al toegang toe heeft, dan is een repository opzetten heel gemakkelijk. Je stopt de kale repository ergens waar iedereen gedeelde toegang tot heeft, en stelt de lees- en schrijfrechten in zoals je dat bij iedere andere gedeelde directory zou doen. In de volgende paragraaf "Git op een Server Krijgen" bespreken we hoe je een kopie van een kale repository kunt exporteren voor dit doeleinde. -Dit is ook een fijne optie om snel werk van een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project aan het werk zijn, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan dat hij naar een remote server moet pushen, en jij er van moet pullen. +Dit is ook een prettige optie om snel werk uit een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project werken, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan dat hij naar een remote server moet pushen, en jij er van moet pullen. #### De Nadelen #### -Een van de nadelen van deze methode is dat gedeelde toegang over het algemeen moeilijker op te zetten en te bereiken is vanaf meerdere lokaties dan basaal netwerk toegang. Als je wilt pushen van je laptop als je thuis bent, dan moet je de remote schijf aankoppelen, wat moeilijk en langzaam kan zijn in vergelijking tot netwerk gebaseerde toegang. +Een van de nadelen van deze methode is dat gedeelde toegang over het algemeen moeilijker op te zetten en te bereiken is vanaf meerdere lokaties dan simpele netwerk toegang. Als je wilt pushen van je laptop als je thuis bent, dan moet je de remote schijf aankoppelen, wat moeilijk en langzaam kan zijn als je het vergelijkt met netwerk gebaseerde toegang. -Het is ook belangrijk om te melden dat het niet noodzakelijk de snelste optie is, als je een gedeeld koppelpunt of iets dergelijks gebruikt. Een lokale repository is alleen snel als je snelle toegang tot de data hebt. Een repository op NFS is vaak langzamer dan het repository via SSH op dezelfde server, wat Git toelaat om vanaf lokale schijven te werken op ieder systeem. +Het is ook belangrijk om te vermelden dat het niet altijd de snelste optie is, als je een gedeeld koppelpunt (mount) of iets dergelijks gebruikt. Een lokale repository is alleen snel als je snelle toegang tot de data hebt. Een repository op NFS is vaak langzamer dan een repository via SSH op dezelfde server omdat dit Git in staat stelt om op lokale schijven te werken op elk van de betrokken systemen. ### Het SSH Protocol ### -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 ongeinitieerden, 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. +Waarschijnlijk het meest voorkomende protocol voor Git is SSH. De reden hiervoor is dat toegang met SSH tot servers in veel plaatsen al geconfigureerd is – en als dat niet het geval is, dan is het eenvoudig 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 ongeïnitieerde massas, dan heb je nog steeds SSH nodig voor je eigen schrijfcommandos. SSH is ook een geauthenticieerd protocol; en omdat het alom aanwezig is, 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: @@ -58,32 +58,32 @@ Of je geeft geen protocol op – Git gaat uit van SSH als je niet expliciet bent $ git clone user@server:project.git -Je kunt ook de gebruiker niet opgeven, en Git neemt aan dat je de gebruiker bedoelt waarmee je op het moment bent ingelogged. +Je kunt ook de gebruiker weglaten, en Git gebruikt gegevens van de gebruiker waarmee je op dat moment bent ingelogd. #### De Voordelen #### -Er zijn vele voordelen om SSH te gebruiken. De eerste is dat je het eigenlijk wel moet gebruiken als je geverifieerde schrijftoegang op je repository via een netwerk wilt. Het tweede is dat het relatief eenvoudig in te stellen is – SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig – alle data transporten zijn versleuteld en geverifieerd. En als laatste is SSH efficient, zoals het Git en lokale protocol, waarbij de data zo compact mogelijk wordt gemaakt voordat het getransporteerd wordt. +Er zijn vele voordelen om SSH te gebruiken. Ten eerste moet je het eigenlijk wel gebruiken als je geauthenticeerde schrijftoegang op je repository via een netwerk wilt. Ten tweede is het relatief eenvoudig in te stellen – SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig – alle data transporten zijn versleuteld en geauthenticeerd. En als laatste is SSH efficiënt, net zoals het Git en lokale protocol, de gegevens worden zo compact mogelijk gemaakt voordat het getransporteerd wordt. #### De Nadelen #### -Het negatieve aspect van SSH is dat je er geen anonieme toegang over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken, zelfs als het alleen lezen is, zodat SSH toegang niet bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, dan kan SSH misschien het enige protocol zijn waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. +Het negatieve aspect van SSH is dat je er geen anonieme toegang naar je repository over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken, zelfs als het alleen lezen is, zodat SSH toegang niet bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, dan is SSH misschien het enige protocol waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. ### 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 verificatie. 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 is er om gecloned te kunnen worden door iedereen, of het is er 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 verificatie 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 specifieke daemon, die met Git meegeleverd wordt; het luistert op een toegewezen poort (9418), en verleent een vergelijkbare dienst als het SSH protocol, maar dan zonder enige vorm van authenticatie. Om een repository beschikbaar te stellen over het Git protocol, moet je een `git-export-daemon-ok` bestand aanmaken – de daemon zal een repository zonder dit bestand erin niet verspreiden – maar daarbuiten is er geen beveiliging. De Git repository beschikbaar om gecloned te kunnen worden door iedereen, of het is het niet. Dit betekent dat er over het algemeen geen pushing is via dit protocol. Je kunt push toegang aanzetten, maar gegeven het gebrek aan authenticatie kan als je de push toegang aan zet iedereen die de URL van jouw project op het internet vindt, pushen naar jouw project. We volstaan met te zeggen dat dit zelden de bedoeling kan zijn. #### De Voordelen #### -Het Git protocol is het snelste dat beschikbaar is. Als je veel verkeer serveert voor een publiek project, of een zeer groot project dat geen gebruikersverificatie nodig heeft voor leestoegang, dan is het waarschijnlijk dat je een Git daemon wilt instellen om je project te serveren. Het maakt van hetzelfde data-transport mechanisme gebruik als het SSH protocol, maar dan zonder de extra belasting van versleuteling en verificatie. +Het Git protocol is het snelste dat beschikbaar is. Als je veel verkeer verwerkt voor een publiek project, of een zeer groot project dat geen gebruikersauthenticatie nodig heeft voor leestoegang, dan is het waarschijnlijk dat je een Git daemon wilt inrichten om je project te verspreiden. Het maakt van hetzelfde data-transport mechanisme gebruik als het SSH protocol, maar dan zonder de extra belasting van versleuteling en authenticatie. #### De Nadelen #### -Het nadeel van het Git protocol is het gebrek van verificatie. Het is over het algemeen onwenselijk dat het Git protocol de enige toegang tot je project is. Over het algemeen zul je het samen met SSH toegang gebruiken voor de paar ontwikkelaars die push (schrijf-)toegang hebben en de rest laat je `git://` voor alleen leestoegang gebruiken. -Het is waarschijnlijk ook het meest ingewikkelde protocol om in te stellen. Het moet een eigen daemon hebben, die speciaal ontworpen is – we zullen er een instellen in het "Gitosis" gedeelte van dit hoofdstuk – het gebruikt `xinetd` configuratie of iets dergelijks, wat niet altijd eenvoudig is. Het heeft ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat bedrijfsfirewalls altijd toestaan. Achter grote bedrijfsfirewalls, is deze obscure poort meestal geblokkeerd. +Het nadeel van het Git protocol is het gebrek aan authenticatie. Het is over het algemeen onwenselijk dat het Git protocol de enige toegang tot je project is. Meestal zul je het samen met SSH toegang gebruiken voor de paar ontwikkelaars die push (schrijf-)toegang hebben en de rest laat je `git://` voor alleen leestoegang gebruiken. +Het is waarschijnlijk ook het meest ingewikkelde protocol om in te richten. Het moet een eigen daemon hebben, die speciaal voor die situatie ingericht is – we zullen er een instellen in het "Gitosis" gedeelte van dit hoofdstuk – het gebruikt `xinetd` configuratie of iets vergelijkbaars, wat ook niet altijd eenvoudig is op te zetten. Daarbij is ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat in bedrijfsfirewalls is opengezet. Bij firewalls van grote bedrijven, is deze ongebruikelijke poort meestal dichtgezet. ### 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 waar je de repository op gezet hebt ook je repository clonen. 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,30 +91,30 @@ 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 geleverd wordt, voert het noodzakelijke commando uit (`git update-server-info`) om HTTP fetching en cloning goed werkend te krijgen en houden. Dit commando wordt uitgevoerd als je via SSH naar deze repository pushed; en andere mensen kunnen clonen met behulp van zoiets als $ git clone http://example.com/gitproject.git -In dit geval, gebruiken we het `/var/www/htdocs` pad wat gebruikelijk is voor Apache opstellingen, maar je kunt iedere statische webserver gebruiken – stop de kale repository in haar pad. De Git data wordt geserveerd als standaard statische bestanden (zie hoofdstuk 9 voor details over hoe het precies geserveerd wordt). +In dit specifieke voorbeeld gebruiken we het `/var/www/htdocs` pad wat gebruikelijk is voor Apache opstellingen, maar je kunt iedere statische webserver gebruiken – stop de kale repository in het betreffende pad. De Git data wordt geserveerd als standaard statische bestanden (zie hoofdstuk 9 voor details over hoe het precies geserveerd wordt). -Het ook is mogelijk om Git over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en erom vraagt dat je complexe WebDAV vereisten insteld. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek beschrijven. Als je geinteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Een fijn ding aan Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken, zonder specifieke Git eigenschappen; dus je kunt deze functionaliteit gebruiken als je web-hosting provider WebDAV ondersteunt voor schrijf vernieuwingen aan je webpagina. +Het is mogelijk om Git ook over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en het vraagt dat je complexe WebDAV instellingen inricht. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek beschrijven. Als je geïnteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Het aardige van Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken, zonder specifieke Git funtionaliteit, dus je kunt deze functionaliteit gebruiken als je web-hosting provider WebDAV ondersteunt voor het maken van wijzigingen aan je webpagina. #### De Voordelen #### -Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren zorgt voor een eenvoudige manier om de wereld leestoegang te geven aan je Git repository. Het kost slechts een paar minuten om te doen. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te serveren, een normale Apache server kan gemiddeld duizenden bestanden serveren per seconde – is het moeilijk om zelfs een kleine server te overbelasten. +Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren is alles wat er moet gebeuren om de wereld leestoegang te geven tot je Git repository. Het neemt maar een paar minuten van je tijd. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te verspreiden - een normale Apache server kan gemiddeld duizenden bestanden zenden per seconde - is het moeilijk om zelfs een kleine server te overbelasten. -Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat betekend dat je het transport kunt versleutelen; of je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat moeten gebruiken. Als je over het algemeen zo ver gaat, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan een betere oplossing in jouw specifieke geval om gesigneerde SSL certificaten of andere HTTP-gebaseerde verificatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. +Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat inhoudt dat je het transport kunt versleutelen; je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat laat gebruiken. Normaal gesproken als je je deze moeite wilt getroosten, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan in jouw specifieke geval een betere oplossing zijn om gesigneerde SSL certificaten of andere HTTP-gebaseerde authenticatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. -Een ander fijn ding is dat HTTP zo'n veel voorkomend protocol is dat bedrijfsfirewalls vaak zo ingesteld zijn dat ze verkeerd via deze poort toelaten. +Een andere prettige bijkomstigheid is dat HTTP een dusdanig veel voorkomend protocol is dat bedrijfsfirewalls vaak zo ingesteld zijn dat ze verkeer via deze poort toestaan. #### De Nadelen #### -Het nadeel van je repository serveren via HTTP is dat het relatief inefficient 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 ingewikkeld 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 efficientie tussen het HTTP protocol en andere protocollen, zie Hoofdstuk 9. +Het nadeel van je repository verspreiden 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 veel hogere netwerk belasting en transport volume via HTTP dan met elk van de andere netwerk protocollen. Omdat het niet zo ingewikkeld is om alleen de data te versturen die je nodig hebt – er wordt geen dynamisch werk door de server gedaan in deze uitwisselingen – 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 initiele 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 een Git server initieel op te zetten, moet je een bestaande repository naar 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 conventie eindigen de namen van kale repository mappen met `.git`, zoals: $ git clone --bare my_project my_project.git Initialized empty Git repository in /opt/projects/my_project.git/ @@ -125,29 +125,29 @@ Dit is ongeveer gelijk aan $ cp -Rf my_project/.git my_project.git -Er zijn een paar kleine verschillen in het configuratie bestand; maar voor jouw doeleinde ligt dit dicht bij hetzelfde. Het neemt de Git repository zelf, zonder een werkmap, en maakt een map aan specifiek alleen voor dat ding. +Er zijn een paar kleine verschillen in het configuratie bestand, maar het komt op hetzelfde neer. Het neemt de Git repository zelf, zonder een werkmap, en maakt een map aan specifiek hiervoor. -### Het Bare Repository op een Server Zetten ### +### De Kale Repository op een Server Zetten ### -Nu dat je een kale kopie van je repository hebt, is het enige dat je moet doen het op een server zetten en je protocollen instellen. Stel dat je een server ingesteld hebt, die `git.example.com` heet, waar je SSH toegang op hebt, en waar je al je Git repositories wilt opslaan onder de `/opt/git` map. Je kunt je nieuwe repository instellen door je kale repository ernaartoe te kopieeren: +Nu je een kale kopie van je repository hebt, is het enige dat je moet doen het op een server zetten en je protocollen instellen. Laten we aannemen dat je een server ingericht hebt, die `git.example.com` heet, waar je SSH toegang op hebt, en waar je al je Git repositories wilt opslaan onder de `/opt/git` map. Je kunt je nieuwe repository beschikbaar stellen door je kale repository ernaartoe te kopiëren: $ 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: +Vanaf dat moment 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: $ git clone user@git.example.com:/opt/git/my_project.git -Als een gebruiker in een server SSH-ed en schrijftoegang heeft tot de `/opt/git/my_project.git` map, dan hebben ze automatisch ook push toegang. Git zal automatisch correcte groep schrijfrechten aan een repository toevoegen als je het `git init` commando met de `--shared` optie uitvoert. +Als een gebruiker met SSH op een server inlogt en schrijftoegang heeft tot de `/opt/git/my_project.git` map, dan hebben ze automatisch ook push toegang. Git zal automatisch de correcte groep schrijfrechten aan een repository toekennen als je het `git init` commando met de `--shared` optie uitvoert. $ ssh user@git.example.com $ cd /opt/git/my_project.git $ git init --bare --shared -Je ziet hoe eenvoudig het is om een Git repository te nemen, een kale versie aan te maken, en het op een server plaatsen waar jij en je medewerkers SSH toegang tot hebben. Nu ben je klaar om aan hetzelfde project samen te werken. +Je ziet hoe eenvoudig het is om een Git repository te nemen, een kale versie aan te maken, en het op een server plaatsen waar jij en je medewerkers SSH toegang tot hebben. Nu zijn jullie klaar om aan hetzelfde project samen te werken. -Het is belangrijk om te zien dat dit letterlijk alles is wat je moet doen om een bruikbare Git server te draaien waarop meerdere mensen toegang hebben – voeg alleen een paar SSH accounts toe op een server, en stop een kale repository ergens waar al die gebruikers lees- en schrijftoegang tot hebben. Je bent er klaar voor – je hebt niets anders nodig. +Het is belangrijk om op te merken dat dit letterlijk alles is wat je moet doen om een bruikbare Git server te draaien waarop meerdere mensen toegang hebben – maak alleen een paar accounts met SSH toegang aan op een server, en stop een kale repository ergens waar al die gebruikers lees- en schrijftoegang toe hebben. Je bent er klaar voor – je hebt niets anders nodig. -In de volgende secties zul je zien hoe je meer ingewikkelde opstellingen kunt maken. Deze bespreking zal het niet hoeven aanmaken van gebruikers accounts voor elke gebruiker, publieke leestoegang tot repositories, grafische web interfaces, de Gitosis applicatie gebruiken en meer omvatten. Maar, hou in gedachten dat om samen te kunnen werken met mensen op een prive project, alles wat je _nodig_ hebt is een SSH server en een kale repository. +In de volgende paragrafen zul je zien hoe je meer ingewikkelde opstellingen kunt maken. Deze bespreking zal het niet hoeven aanmaken van gebruikers accounts voor elke gebruiker, publieke leestoegang tot repositories, grafische web interfaces, het gebruik van de Gitosis applicatie en meer omvatten. Maar, hou in gedachten dat om samen te kunnen werken met mensen op een privé project, alles wat je _nodig_ hebt een SSH server is en een kale repository. ### Kleine Opstellingen ### @@ -155,27 +155,26 @@ Als je met een kleine groep bent of net begint met Git in je organisatie en slec #### SSH Toegang #### -Als je reeds een server hebt waar al je ontwikkelaars SSH toegang op hebben, dan is het over het algemeen het gemakkelijkst om je eerste repository daar in te stellen, omdat je dan bijna niets hoeft te doen (zoals beschreven in de vorige sectie). Als je meer complexe toegangscontrole wilt op je repositories, dan kun je ze instellen met de normale bestandssysteem permissies van het operating systeem dat op je server draait. +Als je al een server hebt waar al je ontwikkelaars SSH toegang op hebben, dan is het over het algemeen het eenvoudigste om je eerste repository daar op te zetten, omdat je dan bijna niets hoeft te doen (zoals beschreven in de vorige paragraaf). Als je meer complexe toegangscontrole wilt op je repositories, dan kun je ze instellen met de normale bestandssysteem permissies van het operating systeem dat op je server draait. -Als je je repositories op een server wilt zetten, die geen accounts heeft voor iedereen in je team die je schrijftoegang wilt geven, dan moet je SSH toegang voor ze instellen. We gaan er vanuit dat je een server hebt waarmee je dit kunt doen, je reeds een SSH server geinstalleerd hebt, en dat de manier is waarop je toegang hebt tot de server. +Als je je repositories op een server wilt zetten, die geen accounts heeft voor iedereen in je team die je schrijftoegang wilt geven, dan moet je SSH toegang voor ze opzetten. We gaan er vanuit dat je een server hebt waarmee je dit kunt doen, dat je reeds een SSH server geïnstalleerd hebt, en dat de manier is waarop je toegang hebt tot de server. -Er zijn een paar manieren waarop je iedereen in je team toegang kunt geven. De eerste is voor iedereen accounts aanmaken, wat rechttoe rechtaan is maar omslachtig kan zijn. Je wilt misschien niet `adduser` uitvoeren en tijdelijke wachtwoorden voor iedere gebruiker instellen. +Er zijn een paar manieren waarop je iedereen in je team toegang kunt geven. De eerste is voor iedereen accounts aanmaken, wat rechttoe rechtaan is maar bewerkelijk kan zijn. Je wilt vermoedelijk niet `adduser` uitvoeren en tijdelijke wachtwoorden instellen voor iedere gebruiker. -Een tweede methode is een 'git' gebruiker aanmaken op de machine, aan iedere gebruiker die schijftoegang moet hebben vragen of ze je een publieke SSH sleutel sturen, en die sleutel toevoegen aan het `~/.ssh/authorized_keys` bestand van je nieuwe 'git' gebruiker. Vanaf dat punt zal iedereen toegang hebben op die machine via de 'git' gebruiker. Dit tast de commit data op geen enkele manier aan – de SSH gebruiker waarmee je inlogged zal de commits die je opgeslagen hebt niet beinvloeden. +Een tweede methode is een generieke 'git' gebruiker aan te maken op de machine, aan iedere gebruiker die schijftoegang moet hebben vragen of ze je een publieke SSH sleutel sturen, en die sleutel toevoegen aan het `~/.ssh/authorized_keys` bestand van die nieuwe 'git' gebruiker. Vanaf dat moment zal iedereen toegang hebben op die machine via de 'git' gebruiker. Dit tast de commit data op geen enkele manier aan – de SSH gebruiker waarmee je inlogt zal de commits die je opgeslagen hebt niet beïnvloeden. -Een andere manier waarop je het kunt doen is je SSH server laten verifieren vanaf een LDAP server of een andere gecentraliseerde verificatie bron, die je misschien al ingesteld hebt. Zolang iedere gebruiker een shell toegang heeft op de machine, zou ieder SSH verificatie mechanisme dat je kunt bedenken moeten werken. +Een andere manier waarop je het kunt doen is je SSH server laten authenticeren middels een LDAP server of een andere gecentraliseerde authenticatie bron, die misschien al ingericht is. Zolang iedere gebruiker shell toegang kan krijgen op de machine, zou ieder SSH authenticatie mechanisme dat je kunt bedenken moeten werken. ## Je Publieke SSH Sleutel Genereren ## -Dat gezegd hebbende, zijn er vele Git servers die verifieren met een publieke SSH sleutel. Om een publieke sleutel te hebben, zal iedere gebruiker in je systeem er een moeten genereren als ze er nog geen hebben. Dit proces is bij alle operating systemen vergelijkbaar. -Als eerste moet je controleren dat je er niet al een hebt. Standaard staan de SSH sleutels van de gebruikers in hun eigen `~/.ssh` map. Je kunt makkelijk nagaan of je al een sleutel hebt door naar die map te gaan en de inhoud te tonen: +Dat gezegd hebbende, zijn er vele Git servers die authenticeren met een publieke SSH sleutel. Om een publieke sleutel te hebben, zal iedere gebruiker in je systeem er een moeten genereren als ze er nog geen hebben. Dit proces is bij alle operating systemen vergelijkbaar. Als eerste moet je controleren of je er niet al een hebt. Standaard staan de SSH sleutels van de gebruikers in hun eigen `~/.ssh` map. Je kunt makkelijk nagaan of je al een sleutel hebt door naar die map te gaan en de inhoud te bekijken: $ cd ~/.ssh $ ls authorized_keys2 id_dsa known_hosts config id_dsa.pub -Je bent op zoek naar een aantal bestanden genaamd iets en iets.pub, waarbij het `iets` meestal zoiets is als `id_dsa` of `id_rsa`. Het `.pub` bestand is je publieke sleutel en het andere bestand is je private sleutel. Als je deze bestanden niet hebt (of als je zelfs geen `.ssh` map hebt), dan kun je ze aanmaken door een applicatie genaamd `ssh-keygen` uit te voeren, wat meegeleverd wordt met het SSH pakket op Linux/Mac systemen en meegeleverd wordt met het MSysGit pakket op Windows: +Je bent op zoek naar een aantal bestanden genaamd iets en iets.pub, waarbij het `iets` meestal zoiets is als `id_dsa` of `id_rsa`. Het `.pub` bestand is je publieke sleutel en het andere bestand is je private sleutel. Als je deze bestanden niet hebt (of als je zelfs geen `.ssh` map hebt), dan kun je ze aanmaken door een applicatie genaamd `ssh-keygen` uit te voeren, deze wordt met het SSH pakket op Linux/Mac systemen meegeleverd en met het MSysGit pakket op Windows: $ ssh-keygen Generating public/private rsa key pair. @@ -187,9 +186,9 @@ Je bent op zoek naar een aantal bestanden genaamd iets en iets.pub, waarbij het The key fingerprint is: 43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local -Eerst bevestigt het de lokatie waar je de sleutel wilt opslaan (`.ssh/id_rsa`), en vervolgens vraagt het tweemaal om een wachtzin, die je leeg kunt laten als je geen wachtwoord wilt intypen op het moment dat je de sleutel gebruikt. +Eerst wordt de lokatie waar je de sleutel wordt opgeslagen (`.ssh/id_rsa`) aangegeven, en vervolgens vraagt het tweemaal om een wachtwoord, die je leeg kunt laten als je geen wachtwoord wilt intypen op het moment dat je de sleutel gebruikt. -Iedere gebruiker die dit doet, moet zijn sleutel sturen naar jou of degene die de Git server beheert (aangenomen dat je een SSH server gebruikt die publieke sleutels vereist). Het enige dat ze hoeven doen is de inhoud van het `.pub` bestand kopieeren en e-mailen. De publieke sleutel ziet er ongeveer zo uit: +Iedere gebruiker die dit doet, moet zijn sleutel sturen naar jou of degene die de Git server beheert (aangenomen dat je een SSH server gebruikt die publieke sleutels vereist). Het enige dat ze hoeven doen is de inhoud van het `.pub` bestand kopiëren en e-mailen. De publieke sleutel ziet er ongeveer zo uit: $ cat ~/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU @@ -199,18 +198,18 @@ Iedere gebruiker die dit doet, moet zijn sleutel sturen naar jou of degene die d mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx NrRFi9wrf+M7Q== schacon@agadorlaptop.local -Voor een uitgebreide tutorial over het aanmaken van een SSH sleutel op meerdere operating systemen, zie de GitHub handleiding over SSH sleutels op `http://github.com/guides/providing-your-ssh-key`. +Voor een uitgebreide tutorial over het aanmaken van een SSH sleutel op meerdere operating systemen, verwijzen ze je naar de GitHub handleiding over SSH sleutels op `http://github.com/guides/providing-your-ssh-key`. -## De Server Instellen ## +## De Server Opzetten ## -Laten we het instellen van SSH toegang aan de server kant eens doorlopen. In dit voorbeeld zul je de `authorized_keys` methode gebruiken om je gebruikers te verifieren. We gaan er ook vanuit dat je een standaard Linux distributie gebruikt zoals Ubuntu. Als eerste creeer je een 'git' gebruiker een een `.ssh` map voor die gebruiker. +Laten we het opzetten van SSH toegang aan de server kant eens doorlopen. In dit voorbeeld zul je de `authorized_keys` methode gebruiken om je gebruikers te authenticeren. We gaan er ook vanuit dat je een standaard Linux distributie gebruikt zoals Ubuntu. Als eerste maak je een 'git' gebruiker aan en een `.ssh` map voor die gebruiker. $ sudo adduser git $ su git $ cd $ mkdir .ssh -Daarna moet je een aantal publieke SSH sleutels van ontwikkelaars aan het `authorized_keys` bestand toevoegen voor die gebruiker. Laten we aannemen dat je een aantal sleutels per e-mail ontvangen hebt en ze hebt opgeslagen in tijdelijke bestanden. Nogmaals, de sleutels zien er ongeveer zo uit: +Vervolgens moet je een aantal publieke SSH sleutels van ontwikkelaars aan het `authorized_keys` bestand toevoegen voor die gebruiker. Laten we aannemen dat je een aantal sleutels per e-mail ontvangen hebt en ze hebt opgeslagen in tijdelijke bestanden. Nogmaals, de sleutels zien er ongeveer zo uit: $ cat /tmp/id_rsa.john.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4L @@ -220,20 +219,20 @@ Daarna moet je een aantal publieke SSH sleutels van ontwikkelaars aan het `autho O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq dAv8JggJICUvax2T9va5 gsg-keypair -Je voegt ze slechts toe aan je `authorized_keys` bestand: +Je voegt ze eenvoudigweg toe aan je `authorized_keys` bestand: $ 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 -Nu kun je een leeg repository voor ze instellen door `git init` uit te voeren met de `--bare` optie, wat het repository initialiseert zonder een werkmap: +Nu kun je een lege repository voor ze instellen door `git init` uit te voeren met de `--bare` optie, wat de repository initialiseert zonder een werkmap: $ cd /opt/git $ mkdir project.git $ cd project.git $ git --bare init -Daarna kunnen John, Josie of Jessica de eerste versie van hun project in de repository pushen door het als een remote toe te voegen en naar een branch te pushen. Let op dat iemand met een shell op de machine zal moeten inloggen en een kale repository moet creeeren, iedere keer als je een project wilt toevoegen. Laten we `gitserver` als hostnaam gebruiken voor de server waar je je 'git' gebruiker en repository hebt ingesteld. Als je het intern gaat draaien, en je de DNS instelt zodat `gitserver` naar die server wijst, dan kun je de commando's vrijwel ongewijzigd gebruiken: +Daarna kunnen John, Josie of Jessica de eerste versie van hun project in de repository pushen door het als een remote toe te voegen en een branch te pushen. Merk op dat iemand met een shell op de machine zal moeten inloggen en een kale repository moet creëren voor elke keer dat je een project wilt toevoegen. Laten we `gitserver` als hostnaam gebruiken voor de server waar je de 'git' gebruiker en repository hebt aangemaakt. Als je het binnenshuis draait, en je de DNS instelt zodat `gitserver` naar die server wijst, dan kun je de commando's vrijwel ongewijzigd gebruiken: # op Johns computer $ cd myproject @@ -243,14 +242,14 @@ 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: +Vanaf dat moment kunnen de anderen het clonen en wijzigingen even gemakkelijk terug pushen: $ git clone git@gitserver:/opt/git/project.git $ vim README $ git commit -am 'fix for the README file' $ git push origin master -Met deze methode kun je snel een lees/schrijf Git server draaiend krijgen voor een handvol ontwikkelaars. +Op deze manier kun je snel een lees/schrijf Git server draaiend krijgen voor een handjevol ontwikkelaars. Als een extra voorzorgsmaatregel kun je de 'git' gebruiker makkelijk beperken tot het doen van alleen Git activiteiten, met een gelimiteerde shell applicatie genaamd `git-shell` die bij Git geleverd wordt. Als je dit als login shell voor je 'git' gebruiker instelt, dan kan de 'git' gebruiker geen normale shell toegang hebben op je server. Specificeer `git-shell` in plaats van bash of csh voor je gebruikers login shell om dit te gebruiken. Om dit te doen zul je waarschijnlijk het `/etc/passwd` bestand aan moeten passen: @@ -261,7 +260,7 @@ Aan het einde zou je een regel moeten vinden die er ongeveer zo uit ziet: git:x:1000:1000::/home/git:/bin/sh -Verander `/bin/sh` in `/usr/bin/git-shell` (of voer `which git-shell` uit om te zien waar het geinstalleerd is). De regel moet er ongeveer zo uit zien: +Verander `/bin/sh` in `/usr/bin/git-shell` (of voer `which git-shell` uit om te zien waar het geïnstalleerd is). De regel moet er ongeveer zo uit zien: git:x:1000:1000::/home/git:/usr/bin/git-shell @@ -273,11 +272,11 @@ Nu kan de 'git' gebruiker de SSH connectie alleen gebruiken om Git repositories ## Publieke Toegang ## -Wat als je anonieme leestoegang op je project wil? Misschien wil je geen intern prive project serveren, maar een open source project. Of misschien heb je een serie geautomatiseerde bouwservers of continue integratie servers die vaak wijzigen, en wil je niet doorlopend SSH sleutels hoeven genereren – je wil gewoon eenvoudige leestoegang toevoegen. +Wat als je anonieme leestoegang op je project wil? Misschien wil je geen intern privé project beheren, maar een open source project. Of misschien heb je een aantal geautomatiseerde bouwservers of continue integratie servers die vaak wisselen, en wil je niet doorlopend SSH sleutels hoeven genereren – je wil gewoon eenvoudige anonieme leestoegang toevoegen. -Waarschijnlijk is de eenvoudigste manier voor kleinschalige opstellingen om een statische webserver in te stellen, waarbij de document root naar de plaats van je Git repositories wijst, en dan die `post-update` haak aanzetten waar we het in de eerste sectie van dit hoofdstuk over gehad hebben. Laten we eens uitgaan van het vorige voorbeeld. Stel dat je je repositories in de `/opt/git` map hebt staan, en er draait een Apache server op je machine. Nogmaals, je kunt hiervoor iedere web server gebruiken: maar als voorbeeld zullen we wat basis Apache configuraties laten zien, die je een idee kunnen geven van wat je nodig hebt. +Waarschijnlijk is de eenvoudigste manier voor kleinschalige opstellingen om een statische webserver in te stellen, waarbij de document root naar de plaats van je Git repositories wijst, en dan de `post-update` haak aanzetten waar we het in de eerste paragraaf van dit hoofdstuk over gehad hebben. Laten we eens uitgaan van het voorgaande voorbeeld. Stel dat je je repositories in de `/opt/git` map hebt staan, en er draait een Apache server op je machine. Nogmaals, je kunt hiervoor iedere web server gebruiken: maar als voorbeeld zullen we wat simpele Apache configuraties laten zien, die je het idee weergeven van wat je nodig hebt. -Eerst moet je de haak aanzetten: +Eerst moet je de haak inschakelen: $ cd project.git $ mv hooks/post-update.sample hooks/post-update @@ -285,7 +284,7 @@ Eerst moet je de haak aanzetten: Als je een lagere versie dan 1.6 van Git gebruikt, dan is het `mv` commando niet nodig – Git is recentelijk pas begonnen met de namen van de haak voorbeelden op .sample te laten eindigen. -Wat doet deze `post-update` haak? Het ziet er ongeveer zo uit: +Wat doet deze `post-update` haak? Het ziet er eigenlijk als volgt uit: $ cat .git/hooks/post-update #!/bin/sh @@ -293,7 +292,7 @@ Wat doet deze `post-update` haak? Het ziet er ongeveer zo uit: Dit betekent dat wanneer je naar de server via SSH pushed, 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: +Vervolgens moet je een VirtualHost regel in je Apache configuratie aanmaken, met de document root als de hoofdmap van je Git projecten. Hier nemen we aan dat je wildcard DNS ingesteld hebt om `*.gitserver` door te sturen naar waar je dit alles draait: ServerName git.gitserver @@ -304,7 +303,7 @@ Vervolgens moet je een VirtualHost toevoeging in je Apache configuratie aanmaken -Je zult ook de Unix gebruikers groep van de `/opt/git` mappen moeten instellen op `www-data` zodat je web server leestoegang heeft op de repositories, omdat de Apache instantie die het CGI script uitvoert (standaard) als die gebruiker draait: +Je zult ook de Unix gebruikers groep van de `/opt/git` mappen moeten zetten op `www-data` zodat je web server leestoegang hebt op de repositories, omdat de Apache instantie het CGI script (standaard) uitvoert als die gebruiker draait: $ chgrp -R www-data /opt/git @@ -312,26 +311,26 @@ Als je Apache herstart, dan zou je je repositories onder die map moeten kunnen c $ git clone http://git.gitserver/project.git -Op deze manier kun je HTTP-gebaseerde toegang voor ieder van je projecten voor een groot aantal gebruikers in slechts een paar minuten instellen. Een andere eenvoudige optie om publieke ongeverifieerde toegang in te stellen is een Git daemon starten, alhoewel dat vereist dat je het proces als daemon uitvoert – we beschrijven deze optie in de volgende sectie als je een voorkeur hebt voor die route. +Op deze manier kun je HTTP-gebaseerde toegang voor elk van je projecten voor een groot aantal gebruikers in slechts een paar minuten regelen. Een andere eenvoudige optie om publieke ongeauthenticeerde toegang in te stellen is een Git daemon te starten, alhoewel dat vereist dat je het proces als daemon uitvoert – we beschrijven deze optie in de volgende paragraaf als je een voorkeur hebt voor deze variant. ## GitWeb ## -Nu dat je basis lees/schrijf en alleen-lezen toegang tot je project hebt, wil je misschien een eenvoudige web-gebaseerde visualiseerder instellen. Git levert een CGI script genaamd GitWeb mee, dat veelal voor hiervoor gebruikt wordt. Je kunt GitWeb in gebruik zien bij sites zoals `http://git.kernel.org` (zie Figuur 4-1). +Nu je gewone lees/schrijf en alleen-lezen toegang tot je project hebt, wil je misschien een eenvoudige web-gebaseerde visualisatie instellen. Git levert een CGI script genaamd GitWeb mee, dat normaalgesproken hiervoor gebruikt wordt. Je kunt GitWeb in actie zien bij sites zoals `http://git.kernel.org` (zie Figuur 4-1). Insert 18333fig0401.png Figuur 4-1. De GitWeb web-gebaseerde gebruikers interface. -Als je wil zien hoe GitWeb er op jouw project uitziet, dan heeft Git een commando waarmee je een tijdelijke instantie op kunt starten als je een lichtgewicht server op je systeem hebt zoals `lighttpd` of `webrick`. Op Linux machines is `lighttpd` vaak geinstalleerd, dus je kunt het misschien draaiend krijgen door `git instaweb` in te typen in je project map. Als je op een Mac werkt: Leopard heeft Ruby voorgeinstalleerd, dus `webrick` zou je beste gok kunnen zijn. Om `instaweb` met een server anders dan lighttpd te starten, kun je het uitvoeren met de `--httpd` optie. +Als je wil zien hoe GitWeb er voor jouw project uitziet, dan heeft Git een commando waarmee je een tijdelijke instantie op kunt starten als je een lichtgewicht server op je systeem hebt zoals `lighttpd` of `webrick`. Op Linux machines is `lighttpd` vaak geïnstalleerd, dus je kunt het misschien draaiend krijgen door `git instaweb` in te typen in je project map. Als je op een Mac werkt: Leopard heeft Ruby voorgeïnstalleerd, dus `webrick` zou je de meeste kans geven. Om `instaweb` met een server anders dan lighttpd te starten, moet je het uitvoeren met de `--httpd` optie. $ 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] -Dat start een HTTPD server op poort 1234 op en start automatisch een web browser op die met die pagina opent. Het is dus makkelijk voor jou. Als je klaar bent en de server wilt afsluiten, dan kun je hetzelfde commando uitvoeren met de `--stop` optie: +Dat start een HTTPD server op poort 1234 op en start automatisch een web browser die op die pagina opent. Het is dus makkelijk voor je. Als je klaar bent en de server wilt afsluiten, dan kun je hetzelfde commando uitvoeren met de `--stop` optie: $ git instaweb --httpd=webrick --stop -Als je de web interface doorlopend op een server wilt draaien voor je team of voor een open source project dat je serveert, dan moet je het CGI script instellen zodat het door je normale web server geserveerd wordt. Sommige Linux distributies hebben een `gitweb` pakket dat je misschien kunt installeren via `apt` of `yum`, dus misschien wil je dat eerst proberen. We zullen zeer binnenkort door een handmatige GitWeb installatie heenlopen. Eerst moet je de Git broncode pakken, waar GitWeb bij zit, en het persoonlijke CGI script genereren: +Als je de web interface doorlopend op een server wilt draaien voor je team of voor een open source project dat je verspreid, dan moet je het CGI script instellen zodat het door je normale web server geserveerd wordt. Sommige Linux distributies hebben een `gitweb` pakket dat je zou kunnen installeren via `apt` of `yum`, dus wellicht kan je dat eerst proberen. We zullen snel door een handmatige GitWeb installatie heen lopen. Eerst moet je de Git broncode pakken waar GitWeb bij zit, en het aangepaste CGI script genereren: $ git clone git://git.kernel.org/pub/scm/git/git.git $ cd git/ @@ -339,7 +338,7 @@ Als je de web interface doorlopend op een server wilt draaien voor je team of vo prefix=/usr gitweb/gitweb.cgi $ sudo cp -Rf gitweb /var/www/ -Let op dat je het commando moet vertellen waar het je Git repositories kan vinden met de `GITWEB_PROJECTROOT` variabele. Nu moet je zorgen dat de Apache server CGI gebruikt voor dat script, waarvoor je een VirtualHost kunt toevoegen: +Merk op dat je het commando moet vertellen waar het je Git repositories kan vinden met de `GITWEB_PROJECTROOT` variabele. Nu moet je zorgen dat de Apache server CGI gebruikt voor dat script, waarvoor je een VirtualHost kunt toevoegen: ServerName gitserver @@ -354,17 +353,17 @@ 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 web server die in staat is CGI te verwerken. Als je iets anders prefereert zou het niet moeilijk moeten zijn dit in te stellen. Vanaf dit moment 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. ## Gitosis ## -De publieke sleutels van alle gebruikers in een `authorized_keys` bestand bewaren voor toegang werkt slechts korte tijd 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. +De publieke sleutels van alle gebruikers in een `authorized_keys` bestand bewaren voor toegang werkt slechts korte tijd goed. Als je honderden gebruikers hebt, dan is het te bewerkelijk om dat proces te blijven volgen. 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 dat moment zou je kunnen overwegen een veelgebruikt software project genaamd Gitosis te gaan gebruiken. Gitosis is in feite een verzameling scripts die je helpen het `authorized_keys` bestand te beheren alsmede eenvoudig toegangscontrole te implementeren. Het interessante hieraan 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 beheert de informatie in dat project en als je het pushed, dan herconfigureert Gitosis de server op basis van dat project, wat best wel slim bedacht 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. +Gitosis installeren is niet de makkelijkste taak ooit, maar het is ook niet al te moeilijk. Het is het makkelijkste om er een Linux server voor te gebruiken – deze voorbeelden gebruiken een standaard Ubuntu 8.10 server. -Gitosis vereist wat Python applicaties, dus moet je eerst het Python setuptools pakket installeren, wat Ubuntu meelevert als python-setuptools: +Gitosis vereist enkele Python tools, dus moet je eerst het Python setuptools pakket installeren, wat Ubuntu beschikbaar stelt als python-setuptools: $ apt-get install python-setuptools @@ -374,15 +373,15 @@ Vervolgens clone en installeer je Gitosis van de hoofdpagina van het project: $ cd gitosis $ sudo python setup.py install -Daarmee worden een aantal bestanden geinstalleerd, die Gitosis zal gebruiken. Daarna wil Gitosis zijn repositories onder `/home/git` stoppen, wat prima is. Maar je hebt je repositories al in `/opt/git` geconfigureerd, dus in plaats van alles te herconfigureren maken we een symbolische link aan: +Daarmee worden een aantal bestanden geïnstalleerd, die Gitosis zal gebruiken. Daarna wil Gitosis zijn repositories onder `/home/git` stoppen, wat prima is. Maar je hebt je repositories al in `/opt/git` geconfigureerd, dus in plaats van alles te herconfigureren maken we een symbolische link aan: $ ln -s /opt/git /home/git/repositories -Gitosis zal je sleutels voor je beheren, dus je moet het huidige bestand verwijderen, de sleutels later opnieuw toevoegen en Gitosis het `authorized_keys` bestand automatisch laten beheren. Voor nu verplaatsen we het `authorized_keys` bestand: +Gitosis zal de sleutels voor je beheren, dus je moet het huidige bestand verwijderen, om de sleutels later opnieuw toe te voegen en Gitosis het `authorized_keys` bestand automatisch laten beheren. Voor nu verplaatsen we het `authorized_keys` bestand: $ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak -Nu moet je je shell terugzetten voor de 'git' gebruiker, als je het veranderd hebt naar het `git-shell` commando. Mensen zullen nog steeds niet in staat zijn in te loggen, maar Gitosis zal dat voor je beheren. Dus, laten we deze regel veranderen in je `/etc/passwd` bestand +Nu moet je de shell terugzetten voor de 'git' gebruiker, als je het veranderd hebt naar het `git-shell` commando. Mensen zullen nog steeds niet in staat zijn in te loggen, Gitosis zal dat voor je beheren. Dus, laten we deze regel veranderen in je `/etc/passwd` bestand git:x:1000:1000::/home/git:/usr/bin/git-shell @@ -390,18 +389,17 @@ terug naar dit: git:x:1000:1000::/home/git:/bin/sh -Nu wordt het tijd om Gitosis te initialiseren. Je doet dit door het `gitosis-init` commando met je eigen publieke sleutel uit te voeren. Als je publieke sleutel niet op de server staat zul je het daar naartoe moeten kopieeren: +Nu wordt het tijd om Gitosis te initialiseren. Je doet dit door het `gitosis-init` commando met je eigen publieke sleutel uit te voeren. Als je publieke sleutel niet op de server staat zul je het daar naartoe moeten kopiëren: $ 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/ -Dit staat de gebruiker met die sleutel toe de hoofd Git repository, die de Gitosis installatie beheert, aan te passen. Daarna zul je met de hand het execute -bit op het `post-update` script moeten instellen voor je nieuwe beheer repository. +Dit staat de gebruiker met die sleutel toe de hoofd Git repository, die de Gitosis setup regelt, aan te passen. Daarna zul je met de hand het execute bit op het `post-update` script moeten aanzetten voor je nieuwe beheer repository. $ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update -Je bent nu klaar om te gaan. Als je alles juist hebt ingesteld, kun je nu met SSH in je server loggen als de gebruiker waarvoor je de publieke sleutel hebt toegevoegd om Gitosis te initialiseren. Je zou dan zoiets als dit moeten zien: +Je bent nu klaar voor de start. Als je alles juist hebt ingesteld, kun je nu met SSH in je server loggen als de gebruiker waarvoor je de publieke sleutel hebt toegevoegd om Gitosis te initialiseren. Je zou dan zoiets als dit moeten zien: $ ssh git@gitserver PTY allocation request failed on channel 0 @@ -421,7 +419,7 @@ Nu heb je een map genaamd `gitosis-admin`, die twee gedeeltes heeft: ./keydir ./keydir/scott.pub -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 geimporteerd met het `gitosis-init` script. +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 de repositories hebben – één bestand per gebruiker. De naam van het bestand in `keydir` (in het vorige voorbeeld, `scott.pub`) zal anders zijn in jouw geval – 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: @@ -432,15 +430,15 @@ Als je naar het `gitosis.conf` bestand kijkt, zou het alleen informatie over het writable = gitosis-admin members = scott -Het laat je zien dat de gebruiker 'scott' – de gebruiker met wiens publieke sleutel je Gitosis geinitialiseerd hebt – de enige is die toegang heeft tot het `gitosis-admin project. +Het laat je zien dat de gebruiker 'scott' – de gebruiker met wiens publieke sleutel je Gitosis geïnitialiseerd hebt – de enige is die toegang heeft tot het `gitosis-admin` project. -Laten we een nieuw project voor je toevoegen. Je voegt een nieuwe sectie genaamd `mobile` toe, waar je de ontwikkelaars in je mobile team neerzet, en de projecten waar deze ontwikkelaars toegang tot moeten hebben. Omdat 'scott' op het moment de enige gebruiker in het systeem is, zul je hem als enig lid toevoegen en zul je een nieuw project genaamd `iphone_project` toevoegen om mee te beginnen: +Laten we nu een nieuw project voor je toevoegen. Je voegt een nieuwe sectie genaamd `mobile` toe, waar je de ontwikkelaars in het mobile team neerzet, en de projecten waar deze ontwikkelaars toegang tot moeten hebben. Omdat 'scott' op het moment de enige gebruiker in het systeem is, zul je hem als enig lid toevoegen en voeg je een nieuw project genaamd `iphone_project` toe om mee te beginnen: [group mobile] writable = iphone_project members = scott -Wanneer je wijzigingen aan het `gitosis-admin` project moet maken, moet je de veranderingen committen en terug pushen naar de server voordat ze effect hebben: +Wanneer je wijzigingen aan het `gitosis-admin` project maakt, moet je de veranderingen committen en terug pushen naar de server voordat ze effect hebben: $ git commit -am 'add iphone_project and mobile group' [master]: created 8962da8: "changed name" @@ -466,7 +464,7 @@ Je kunt je eerste push naar het nieuwe `iphone_project` doen door je server als Merk op dat je geen pad hoeft te specificeren (sterker nog, het wel doen zal niet werken), alleen een dubbele punt en dan de naam van het project – Gitosis zal het voor je vinden. -Je wil samen met je vrienden aan dit project werken, dus je zult hun publieke sleutels weer toe moeten voegen. Maar in plaats van ze handmatig aan het `~/.ssh/authorized_keys` bestand op je server toe te voegen, voeg je ze, één sleutel per bestand, aan de `keydir` map toe. Hoe je de sleutels noemt bepaalt hoe je aan de gebruikers refereert in het `gitosis.conf` bestand. Laten we de publieke sleutels voor John, Josie en Jessica toevoegen: +Je wil samen met je vrienden aan dit project werken, dus je zult hun publieke sleutels weer toe moeten voegen. Maar in plaats van ze handmatig aan het `~/.ssh/authorized_keys` bestand op je server toe te voegen, voeg je ze één sleutel per bestand, aan de `keydir` map toe. Hoe je de sleutels noemt bepaalt hoe je aan de gebruikers refereert in het `gitosis.conf` bestand. Laten we de publieke sleutels voor John, Josie en Jessica toevoegen: $ cp /tmp/id_rsa.john.pub keydir/john.pub $ cp /tmp/id_rsa.josie.pub keydir/josie.pub @@ -490,7 +488,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 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 alle verschillende gebruikers en projecten mogen bevatten. Je kunt ook een andere groep als een van de leden specificeren (met @ als voorvoegsel), waarmee de groepsleden automatisch worden overerfd: [group mobile_committers] members = scott josie jessica @@ -503,21 +501,198 @@ 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 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. + +## Gitolite ## + +Merk op: de laatste versie van deze paragraaf in het ProGit boek is altijd beschikbaar binnen de [gitolite documentation][gldpg]. De auteur geeft ook nederig aan dat, hoewel deze paragraaf accuraat is, het *kan* (en vaak ook *is*) gebruikt om gitolie te installeren zonder enige andere documentatie te lezen, dat het niet gegarandeerd compleet is, en het zeker niet de gehele enorme hoeveelheid documentatie kan vervangen dat meegeleverd wordt met gitolite. + +[gldpg]: http://github.com/sitaramc/gitolite/blob/pu/doc/progit-article.mkd + +Git begint erg populair te worden in het bedrijfsleven, die de neiging hebben nog wat additionele eisen te hebben op het gebied van toegangscontrole. Gitolite was oorspronkelijk gemaakt om bij het vervullen van deze eisen te helpen, maar het blijkt dat het even bruikbaar is in de wereld van de open source: het Fedora Project beheert toegang tot hun package beheer repositories (meer dan 10.000 daarvan!) met gitolite, en het is waarschijnlijk daarbij ook nog eens de grootste gitolite installatie waar dan ook. + +Gitolite stelt je in staat de permissies niet alleen per repository, maar ook per branch of tag naam binnen elke repository. Dus, je kunt aangeven dat bepaalde mensen (of groepen van mensen) alleen maar bepaalde "refs" (branches of tags) kunnen pushen maar niet andere. + +### Installatie ### + +Het installeren van Gitolite is zeer eenvoudig, zelfs als je de uitgebreide documentatie, dat erbij geleverd wordt, niet leest. Je hebt een account op een Unix(achtige) server hebben; verschillende Linux smaken en Solaris 10 zijn getest. Je hebt geen root toegang nodig, aangenomen dat git, perl, en een openssh compatible ssh server al zijn geïnstalleerd. In de onderstaand voorbeelden zullen we het `gitolite` account gebruiken op een host genaamd `gitserver`. + +Gitolite is nogal ongebruikelijk in de zin van "server" software -- toegang gaat via ssh, en elke userid op de server is in potentie een "gitolite host". Het resultaat is, dat er een idee is van "installeren" van de software zelf, en dan het "opzetten" van een gebruiker als een "gitolist host". + +Mensen zonder root toegang kunnen het installeren binnen hun eigen user id. Als laatste: gitlite kan geïnstalleerd worden door een script te starten *op het werkstation*, vanuit een bash-shell. (Zelfs de bash die meegeleverd wordt met msysgit volstaat, voor het geval je je dat afvroeg.) + +We zullen dit laatste in dit stuk beschrijven, voor de overige methoden verwijzen we je naar de documentatie. + +Je begint met het verkrijgen van toegang op basis van een publieke sleutel, zodat je vanaf je werkstation op de server kan inloggen zonder het intypen van je wachtwoord. De volgende methode werkt op Linux; voor andere werkstation besturingssystemen moet je dit wellicht handmatig doen. We gaan er vanuit dat je al een sleutelpaar hebt gegenereerd met `ssh-keygen`. + + $ ssh-copy-id -i ~/.ssh/id_rsa gitolite@gitserver + +Dit zal je vragen naar een wachtwoord naar het gitolite account, en dan de publieke sleutel toegang opzetten. Dit is **absoluut noodzakelijk** voor het installatiescript, dus controleer dit om er zeker van te zijn dat je een commando kan laten lopen zonder een wachtwoord te hoeven in typen. + + $ ssh gitolite@gitserver pwd + /home/gitolite + +Vervolgens, clone je Gitolite van de hoofdsite van het project en roept de "easy install" script aan (het derde argument is jouw naam zoals je deze in de resulterende gitolite-admin repository wilt laten verschijnen): + + $ git clone git://github.com/sitaramc/gitolite + $ cd gitolite/src + $ ./gl-easy-install -q gitolite gitserver sitaram + +En dat is het! Gitolite is nu geïnstalleerdop je server, en je hebt nu een gloednieuwe repository genaamd `gitolite-admin` in de home directory van jouw werkstation. Je beheert je gitolite setup door een wijziging aan te brengen in deze reporitory en deze te pushen. + +Dat laatste commando produceert nogal een hoeveelheid uitvoer dat wellicht interessant is om te lezen. Ook wordt er, de eerste keer dat je het laat lopen, er een nieuwe sleutelpaar gemaakt; je moet een wachtwoord kiezen of Enter als je er geen wilt. Waarom een tweede sleutelpaar nodig is, en hoe deze wordt gebruikt, wordt uitgelegd in het "ssh troubleshooting" document dat bij Gitolite wordt meegeleverd. (Hey, de documentatie moet *ergens* goed voor zijn!) + +Repositories genaamd `gitolite-admin` en `testing` worden standaard op de server aangemaakt. Als je een van beide lokaal wilt clonen (van een account die SSA console toegang heeft naar het gitolite account via *authorized_keys*) type je: + + $ git clone gitolite:gitolite-admin + $ git clone gitolite:testing + +Om deze zelfde repositories te clonen van een willekeurige ander account: + + $ git clone gitolite@servername:gitolite-admin + $ git clone gitolite@servername:testing + +### De Installatie Aanpassen ### + +Hoewel de standaard, snelle, installatie werkt voor de meeste mensen, zijn er een aantal manieren om de installatie aan te passen als dat nodig is. Als je het `-q` argument weg laat, krijg je een "verbose" installatie wijze -- gedetaileerde informatie over wat de installatie aan het doen is bij elke stap. De verbose wijze staat je ook toe om bepaalde server-side parameters aan te passen, zoals de locatie van de eigenlijke repositories, door het wijzigen van een "rc" bestand dat de server gebruikt. Dit "rc" bestand is ruimhartig van commentaar voorzien dus je zou in staat moeten zijn om elke wijziging die je nodig vindt vrij snel te maken, op te slaan en door te gaan. Dit bestand bevat ook enkele instellingen die je kunt aanpassen om de meer geavanceerde functies van gitolite aan of uit te zetten. + +### Config bestand en Beheer van Toegangsregels ### + +Op het moment dat de installatie afgerond is, schakel je over naar de `gitolite-admin` repository (staat in je HOME directory) en begin je rond te snuffelen om te zien wat je daar hebt: + + $ cd ~/gitolite-admin/ + $ ls + conf/ keydir/ + $ find conf keydir -type f + conf/gitolite.conf + keydir/sitaram.pub + $ cat conf/gitolite.conf + #gitolite conf + # please see conf/example.conf for details on syntax and features + + repo gitolite-admin + RW+ = sitaram + + repo testing + RW+ = @all + +Merk op dat "sitaram" (het laatste argument in het `gl-easy-install` commando dat je eerder gegeven hebt) lees en schrijf rechten heeft op de `gitolite-admin` repository en een publiek sleutelbestand met dezelfde naam. + +De syntax van het config bestand voor gitolite is ruimhartig van documentatie voorzien in `conf/example.conf`, dus we zullen alleen wat hoofdpunten benoemen. + +Je kunt voor het gemak gebruikers of repositories groeperen. De groepnamen zijn vergelijkbaar met macros; als je ze definieert maakt het niet uit of het projecten of gebruikers zijn, dat onderscheid wordt pas gemaakt als je de "macro" gaat *gebruiken*. + + @oss_repos = linux perl rakudo git gitolite + @secret_repos = fenestra pear + + @admins = scott # Adams, not Chacon, sorry :) + @interns = ashok # get the spelling right, Scott! + @engineers = sitaram dilbert wally alice + @staff = @admins @engineers @interns + +Je kunt de permissies beheren op het "ref" niveau. In het volgende voorbeeld kunnen stagieres (interns) alleen maar naar de "int" branch pushen. Techneuten (engineers) kunnen naar elke branch pushen waarvan de naam begint met "eng-", en tags die beginnen met "rc" gevolgd door een getal. En de admins kunnen alles (inclusief terugdraaien) naar elke ref. + + repo @oss_repos + RW int$ = @interns + RW eng- = @engineers + RW refs/tags/rc[0-9] = @engineers + RW+ = @admins + +De expressie achter de `RW` of `RW+` is een zgn. regular expression (regex) waartegen de refname (ref) die wordt gepushed wordt vergeleken. Dus we noemen het natuurlijk een "refex"! En natuurlijk kan een refex veel krachtiger zijn dan hier wordt getoond, dus ga het niet overdrijven als je niet al te goed in de perl regexen zit. + +Zoals je wellicht al geraden hebt, prefixed Gitolite `refs/heads/` als een syntactische handigheid als de refex niet begint met `refs/`. + +Een belangrijke eigenschap van de syntax van het config bestand is dat alle regels van een repository niet op één plek hoeft te staan. Je kunt al het generieke spul bij elkaar houden, zoals de regels voor alle `oss_repos` zoals ze hier boven staan, en dan op een latere plaats specifieke regels voor specifieke gevallen, zoals hier: + + repo gitolite + RW+ = sitaram + +Deze regel wordt gewoon toegevoegd aan de set met regels voor de `gitolite` repository. + +Je zou je op dit punt kunnen afvragen hoe de toegangsregels eigenlijk worden toegepast, laten we dat kort behandelen. + +Er zijn twee niveaus van toegangsbeheer in gitolite. De eerste is op repository niveau. Als je lees (of schrijf)rechten hebt tot *enige* ref in de repository, dan heb je lees (of schrijf) rechten tot de repository. + +Het tweede niveau, alleen van toepassing voor "schrijf" toegang, is per branch of tag binnen een repository. De gebruikersnaam, het type toegang wat wordt gevraagd (`W` of '+'), en de refname dat wordt gewijzigd (update) zijn bekend. De toegangsregels worden gecontroleerd in volgorde van voorkomst in het config bestand, en er wordt gekeken naar een treffer voor deze combinatie (maar onthoudt dat de refname middels een regex wordt vergeleken, niet een simpele string-vergelijking). Als er een treffer is, dan slaagt de push. Als er geen treffer wordt gevonden (fallthrough) dan wordt toegang geweigerd. + +### Geavanceerde Toegangs Controle met "deny" regels ### + +Tot zover hebben we alleen permissies gezien uit het rijtje `R`, `RW` of `RW+`. Echter, gitolite kent een andere permissie: `-`, wat staat voor "deny" (ontken). Dit geeft je veel meer macht, tegen kosten van wat hogere complexiteit omdat een fallthrough nu niet de *enige* manier is waarop toegang kan worden geweigerd, wordt *de volgorde van regels belangrijk*! + +Stel dat, in de onderstaande situatie, we de techneuten in staat willen stellen elke branch te laten terugdraaien *behalve* master en integ. Dit is de manier om dat te doen: + + RW master integ = @engineers + - master integ = @engineers + RW+ = @engineers + +Nogmaals, je hoeft slechts de regels van boven naar beneden af te lopen tot je een treffer hebt voor je gevraagde toegangswijze, of een afwijzing. Een push die niets terugdraait naar master of integ wordt door de eerste regel toegestaan. Een terugdraai-push naar deze refs geeft geen treffer op de eerste regel en valt door naar de tweede regel en wordt daarom geweigerd. Elke push (terugdraaiend of niet) naar refs anders dan master of integ zullen op de eerste twee regels zowiezo niet treffen en de derde regel staat dit toe. + +### Beperken van pushes bij gewijzigde bestanden ### + +Bovenop het beperken van gebruikersrechten op branches voor een gebruiker, kan je ook de rechten van gebruikers beperken op bestanden. Als voorbeeld, misschien is de Makefile (of een ander programma) niet echt bedoeld om te worden gewijzigd door iedereen, omdat een groot aantal dingen afhankelijk ervan zijn of omdat het stuk loopt als de wijzigingen niet *precies goed* gebeuren. Je kunt het gitolite duidelijk maken: + + repo foo + RW = @junior_devs @senior_devs + + RW NAME/ = @senior_devs + - NAME/Makefile = @junior_devs + RW NAME/ = @junior_devs + +Deze krachtige eigenschap is gedocumenteerd in `conf/example.conf`. + +### Persoonlijke branches ### + +Gitolite heeft ook een mogelijkheid van "persoonlijke branches" (of liever gezegd "persoonlijke branch namespace") wat erg nuttig kan zijn in een bedrijfssituatie. + +Veel van de code-uitwisselingen in de git-wereld verlopen via zgn. "please pull" aanvragen. In een bedrijfsomgeving echter is ongeauthoriseerde toegang taboe, en het werkstation van een ontwikkelaar kan geen authenticatie doen, dus je moet naar de centrale server pushen en iemand vragen daarvandaan te pullen. + +Dit zou normaalgesproken een gelijksoortige branch-brij veroorzaken als in een gecentraliseerde versiebeheersysteem, en daarbij wordt het opzetten van permissies een vervelende klus voor de administrator. + +Gitolite stelt je in staat een "personal" of "scratch" namespace prefix voor elke ontwikkelaar te definiëren (bijvoorbeeld `refs/personal//*`); zie ook de "personal branches" paragraaf in `doc/3-faq-tips-etc.mkd` voor details. + +### "Wildcard" repositores ### + +Gitolite laat je repositories specificeren met wildcards (eigenlijk perl regex expressies), zoals bijvoorbeeld `assignments/s[0-9][0-9]/a[0-9][0-9]`, om maar een willekeurig voorbeeld te nemen. Dit is een *heel* krachtige eigenschap die wordt aangezet door de regel `$GL_WILDREPOS = 1;` in het rc bestand. Het laat je een nieuwe permissiewijze ("C") toe te wijzen welke gebruikers in staat stelt repositories aan te maken die voldoen aan zulke wildcards, automatisch eigenaarsschap toe te wijzen aan de gebruiker die hem heeft aangemaakt, staat deze gebruiker toe om "R" en "RW" permissies aan anderen toe te wijzen om samen te werken, etc. Deze eigenschap is beschreven in `doc/4-wildcard-repositories.mkd`. + +### Andere eigenschappen ### + +We ronden deze uiteenzetting af met een passe partout van andere eigenschappen, welke alle (en nog vele andere) tot in de kleinste detail zijn beschreven in de "faqs, tips, etc" en andere documenten. + +**Logging**: Gitolite logt alle succesvolle toegangspogingen. Als je wat te los bent geweest in het toekennen van terugdraai permissies (`RW+`) en een of andere nozem heeft "master" vernaggelt, is de log-file een redder in de nood in de zin van snel en eenvoudig achterhalen van de SHA die verdwenen is. + +**Git buiten reguliere PATH**: Een ontzettend handige eigenschap in gitolite is het ondersteunen van git buiten het regulier `$PATH` (dit komt vaker voor dan je zou denken, sommige bedrijfs omgevingen of zelfs sommige hosting providers weigeren dingen systeem-breed te installeren en je eindigt ermee dat je ze in je eigen directories zet). Normaalgesproken ben je gedwongen git aan de *client-side* op de een of andere manier te vertellen van deze niet-standaard locatie van de git binaries. Met gitolite hoe je alleen een verbose installatie te kiezen en `$GIT_PATH` in de "rc" bestanden in te vullen. Hierna geen wijzigingen aan de kant van de clients nodig :-) + +**Rapportage van toegangsrechten**: Nog zo'n handige eigenschap is wat er gebeurt als je gewoon met ssh naar de server gaat. Gitolite laat zien welke repositories je toegang toe hebt en welke soort toegang dat dan wel is. Hier is een voorbeeld: + + hello sitaram, the gitolite version here is v1.5.4-19-ga3397d4 + the gitolite config gives you the following access: + R anu-wsd + R entrans + R W git-notes + R W gitolite + R W gitolite-admin + R indic_web_input + R shreelipi_converter + + +**Delegeringen**: Voor extreem grote installaties kan je de verantwoordelijkheid voor groepen van repositories delegeren aan verschilllende mensen en hen het beheer van die delen onafhankelijk laten regelen. Dit vermindert de werkdruk van de hoofd-beheerder, en maakt van hem minder een faalpunt. Deze eigenschap heeft zijn eigen docuentatie bestand in de `doc/` directory. + +**Gitweb ondersteuning**: Gitolite ondersteunt gitweb op verschillende manieren. Je kunt aangeven welke repositories zichtbaar zijn via gitweb. Je kunt de "owner" (eigenaar) en "description" (omschrijving) voor gitweb vanuit de gitolite configuratie bestanden definiëren. Gitweb heeft een mechanisme beschikbaar waarmee toegang via HTTP wordt geïmplementeerd, deze kan je het "gecompileerde" config bestand van de gitolite config file laten gebruiken, wat inhoudt dat gitweb en gitolite dezelfde toegangsregels gebruikt (voor lees toegang). + ## Git Daemon ## -Voor publieke ongeverifieerde leestoegang tot je projecten zul je het HTTP protocol achter je willen laten, en overstappen op het Git protocol. De hoofdreden is snelheid. Het Git protocol is veel efficienter en daarmee sneller dan het HTTP protocol, dus het zal je gebruikers tijd besparen. +Voor publieke ongeauthenticeerde leestoegang tot je projecten zul je het HTTP protocol achter je willen laten, en overstappen op het Git protocol. De belangrijkste reden is snelheid. Het Git protocol is veel efficiënter en daarmee sneller dan het HTTP protocol, dus het zal je gebruikstijd besparen. -Nogmaals, dit is voor ongeverifieerde alleen-lezen toegang. Als je dit op een server buiten je firewall draait, zul je het alleen moeten gebruiken voor projecten die voor de hele wereld toegankelijk moeten zijn. Als de server waarop je het draait binnen je firewall staat, zou je het kunnen gebruiken voor projecten waarbij een groot aantal mensen of computers (continue integratie of bouwservers) alleen-lezen toegang moeten hebben, waarbij je niet voor iedereen een SSH sleutel wilt toevoegen. +Nogmaals, dit is voor ongeauthenticeerde alleen-lezen toegang. Als je dit op een server buiten je firewall draait, zul je het alleen moeten gebruiken voor projecten die voor de hele wereld toegankelijk moeten zijn. Als de server waarop je het draait binnen je firewall staat, zou je het kunnen gebruiken voor projecten waarbij een groot aantal mensen of computers (continue integratie of bouwservers) alleen-lezen toegang moeten hebben, waarbij je niet voor iedereen een SSH sleutel wilt toevoegen. In ieder geval is het Git protocol relatief eenvoudig in te stellen. Eigenlijk is het enige dat je moet doen dit commando een daemon uitvoeren: 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 in 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 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 poort 9418 open moeten zetten op de machine waar je dit op gaat doen. -Je kunt dit proces op een aantal manieren daemonisern, afhankelijk van het besturingssystem waarop je draait. Op een Ubuntu machine, zul je een Upstart script gebruiken. Dus in het volgende bestand +Je kunt dit proces op een aantal manieren daemoniseren, afhankelijk van het besturingssystem waarop je draait. Op een Ubuntu machine, zul je een Upstart script gebruiken. Dus in het volgende bestand /etc/event.d/local-git-daemon @@ -534,18 +709,18 @@ stop je dit script: Omwille van veiligheidsredenen, wordt sterk aangeraden om deze daemon uit te voeren als gebruiker met alleen-lezen toegang op de repositories – je kunt dit makkelijk doen door een gebruiker 'git-ro' aan te maken en de daemon als deze uit te voeren. Om het eenvoudig te houden voeren we het als dezelfde 'git' gebruiker uit, als waarin Gitosis draait. -Als je je machine herstart, zal je Git daemon automatisch opstarten en herstarten als hij onderuit gaat. Om het te laten draaien zonder te herstarten, kun je dit uitvoeren: +Als je de machine herstart, zal de Git daemon automatisch opstarten en herstarten als de server onderuit gaat. Om het te laten draaien zonder te herstarten, kun je dit uitvoeren: initctl start local-git-daemon -Op andere systemen zul je misschien `xinetd` willen gebruiken, een script in je `sysvinit` systeem, of iets anders – zolang je dat commando maar ge-daemoniseerd krijgt en op een of andere manier in de gaten gehouden wordt. +Op andere systemen zul je misschien `xinetd` willen gebruiken, een script in je `sysvinit` systeem, of iets anders – zolang je dat commando maar ge-daemoniseerd krijgt en deze op een of andere manier in de gaten gehouden wordt. -Vervolgens zul je je Gitosis server moeten vertellen welke repositories je ongeverifieerde Gitserver gebaseerde toegang toestaat. Als je een sectie toevoegt voor iedere repository, dan kun je die repositories specificeren waarop je je Git daemon wilt laten lezen. Als je Git protocol toegang tot je iphone project wilt toestaan, dan voeg je dit toe aan het eind van het `gitosis.conf` bestand: +Vervolgens zul je je Gitosis server moeten vertellen welke repositories je onauthenticeerde Gitserver gebaseerde toegang toestaat. Als je een sectie toevoegt voor iedere repository, dan kun je die repositories specificeren waarop je je Git daemon wilt laten lezen. Als je Git protocol toegang tot je iphone project wilt toestaan, dan voeg je dit toe aan het eind van het `gitosis.conf` bestand: [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 gepushed is, dan zou de 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: @@ -571,15 +746,15 @@ Als je nu het project commit en pushed, start GitWeb automatisch met het tonen v ## Hosted Git ## -Als je niet door al het werk heen wilt om je eigen Git server op te zetten, heb je meerdere opties om je Git project op een externe speciale hosting pagina te laten beheren. Dit biedt een aantal voordelen: een ge-hoste pagina is over het algemeen snel in te stellen, en eenvoudig om projecten op te starten, en er komt geen server beheer en onderhoud bij kijken. Zelfs als je je eigen server intern ingesteld hebt, zul je misschien een publieke host pagina voor je open source broncode willen – dat is over het algemeen makkelijker voor de open source commune te vinden en je er mee te helpen. +Als je niet al het werk wilt doen om je eigen Git server op te zetten, heb je meerdere opties om je Git project op een externe speciale hosting pagina te laten beheren. Dit biedt een aantal voordelen: een ge-hoste pagina is over het algemeen snel in te stellen, eenvoudig om projecten mee op te starten, en er komt geen serverbeheer en -onderhoud bij kijken. Zelfs als je je eigen server intern ingesteld hebt, zul je misschien een publieke host pagina voor je open source broncode willen – dat is over het algemeen makkelijker voor de open source commune te vinden en je er mee te helpen. Vandaag de dag heb je een enorm aantal beheer opties om uit te kiezen, elk met verschillende voor- en nadelen. Om een bijgewerkte lijst te zien, ga dan kijken op de GitHosting pagina op de hoofd Git wiki: http://git.or.cz/gitwiki/GitHosting -Omdat we ze niet allemaal kunnen behandelen, en ik toevalllig bij een ervan werk, zullen we deze sectie gebruiken om door het instellen van een account en het opzetten van een project op GitHub lopen. Dit geeft je een idee van het benodigde werk. +Omdat we ze niet allemaal kunnen behandelen, en ik toevallig bij een ervan werk, zullen we deze paragraaf gebruiken het instellen van een account en het opzetten van een project op GitHub te doorlopen. Dit geeft je een idee van het benodigde werk. -GitHub is veruit de grootste open source Git beheer pagina en het is ook een van de weinige die zowel publieke als privé beheer opties biedt, zodat je je open source en commerciele privé code in dezelfde plaats kunt bewaren. Sterker nog, we hebben GitHub gebruikt om privé samen te werken aan dit boek. +GitHub is veruit de grootste open source Git beheer pagina en het is ook een van de weinige die zowel publieke als privé beheer opties biedt, zodat je je open source en commerciele privé code op dezelfde plaats kunt bewaren. Sterker nog, we hebben GitHub gebruikt om privé samen te werken aan dit boek. ### GitHub ### From acf785e6b308f26609adca7ff8d559c63525faca Mon Sep 17 00:00:00 2001 From: Cor Date: Mon, 20 Jan 2014 13:33:17 +0100 Subject: [PATCH 122/690] [nl] Completed translating to Dutch, repaired a false "link" to "Simple Setups" section (that section does not exist) and made it point to the section where the ssh_keygen command is used.;sK --- nl/04-git-server/01-chapter4.markdown | 127 +++++++++++++------------- 1 file changed, 65 insertions(+), 62 deletions(-) diff --git a/nl/04-git-server/01-chapter4.markdown b/nl/04-git-server/01-chapter4.markdown index c6bdd3c65..c45b26ba6 100644 --- a/nl/04-git-server/01-chapter4.markdown +++ b/nl/04-git-server/01-chapter4.markdown @@ -1,6 +1,6 @@ # Git op de Server # -Op dit punt zou je alledaagse taken waarvoor je Git zult gebruiken kunnen doen. Maar, om samen te kunnen werken in Git zul je een remote repository moeten hebben. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden, omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers de repository kunnen bereiken, zelfs als jouw computer van het netwerk is – het hebben van een betrouwbare gezamenlijke repository is vaak handig. De voorkeursmethode om met iemand samen te werken is om een tussenliggende repository in te richten waar beide partijen toegang to hebben en om daar naartoe te pushen en vandaan te pullen. We zullen deze repository de `Git server` noemen, maar je zult zien dat het over het algemeen maar een klein beetje systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. +Je zou nu de alledaagse taken waarvoor je Git zult gebruiken moeten kunnen uitvoeren. Echter, om enige vorm van samenwerking te hebben in Git is een remote repository nodig. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers de repository kunnen bereiken, zelfs als jouw computer van het netwerk is – het hebben van een betrouwbare gezamenlijke repository is vaak handig. De voorkeursmethode om met iemand samen te werken is om een tussenliggende repository in te richten waar beide partijen toegang tot hebben en om daar naartoe te pushen en vandaan te pullen. We zullen deze repository de `Git server` noemen, maar je zult zien dat het over het algemeen maar weinig systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. Een Git server draaien is eenvoudig. Als eerste kies je met welke protocollen je de server wilt laten communiceren. Het eerste gedeelte van dit hoofdstuk zullen we de beschikbare protocollen bespreken met de voor- en nadelen van elk. De daarop volgende paragrafen zullen we een aantal veel voorkomende opstellingen bespreken die van die protocollen gebruik maken en hoe je je server ermee kunt opzetten. Als laatste laten we een paar servers van derden zien, als je het niet erg vindt om je code op de server van een ander te zetten en niet het gedoe wilt hebben van het opzetten en onderhouden van je eigen server. @@ -16,7 +16,7 @@ Het is belangrijk om op te merken dat, met uitzondering van de HTTP protocollen, ### Lokaal Protocol ### -Het simpelste is het _Lokale protocol_, waarbij de remote repository in een andere directory op de schijf staat. Deze opzet wordt vaak gebruikt als iedereen in het team toegang heeft op een gedeeld bestandssyteem zoals een NFS mount, of in het weinig voorkomende geval dat iedereen op dezelfde computer werkt. Het laatste zou niet ideaal zijn, want dan zouden alle repositories op dezelfde computer staan, zodat een fataal verlies van gegevens veel groter wordt. +Het simpelste is het _Lokale protocol_, waarbij de remote repository in een andere directory op de schijf staat. Deze opzet wordt vaak gebruikt als iedereen in het team toegang heeft op een gedeeld bestandssyteem zoals een NFS mount, of in het weinig voorkomende geval dat iedereen op dezelfde computer werkt. Het laatste zou niet ideaal zijn, want dan zouden alle repositories op dezelfde computer staan, zodat de kans op een fataal verlies van gegevens veel groter wordt. Als je een gedeeld bestandssyteem hebt, dan kun je clonen, pushen en pullen van een op een lokaal bestand aanwezige 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 het volgende uitvoeren: @@ -26,7 +26,7 @@ Of je kunt dit doen: $ git clone file:///opt/git/project.git -Git werkt iets anders als je explicite `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gesproken gebruikt om data te transporteren over een netwerk, wat over het algemeen een minder efficiënte methode is om gegevens over te dragen. De belangrijkste reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de vreemde refenties of objecten eruit gelaten – over het algemeen na een import uit een ander versiebeheer systeem of iets dergelijks (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. +Git werkt iets anders als je explicite `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gesproken gebruikt om data te transporteren over een netwerk, wat over het algemeen een minder efficiënte methode is om gegevens over te dragen. De belangrijkste reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de vreemde referenties of objecten eruit gelaten – over het algemeen na een import uit een ander versiebeheer systeem of iets dergelijks (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. Om een lokale repository aan een bestaand Git project toe te voegen, kun je iets als het volgende uitvoeren: @@ -38,7 +38,7 @@ Daarna kun je op gelijke wijze pushen naar, en pullen van die remote als je over De voordelen van bestands-gebaseerde repositories zijn dat ze eenvoudig zijn en ze maken gebruik van bestaande bestandspermissies en netwerk toegang. Als je al een gedeeld bestandssysteem hebt, waar het hele team al toegang toe heeft, dan is een repository opzetten heel gemakkelijk. Je stopt de kale repository ergens waar iedereen gedeelde toegang tot heeft, en stelt de lees- en schrijfrechten in zoals je dat bij iedere andere gedeelde directory zou doen. In de volgende paragraaf "Git op een Server Krijgen" bespreken we hoe je een kopie van een kale repository kunt exporteren voor dit doeleinde. -Dit is ook een prettige optie om snel werk uit een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project werken, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan dat hij naar een remote server moet pushen, en jij er van moet pullen. +Dit is ook een prettige optie om snel werk uit een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project werken, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan wanneer hij naar een remote server moet pushen, en jij er van moet pullen. #### De Nadelen #### @@ -62,15 +62,15 @@ Je kunt ook de gebruiker weglaten, en Git gebruikt gegevens van de gebruiker waa #### De Voordelen #### -Er zijn vele voordelen om SSH te gebruiken. Ten eerste moet je het eigenlijk wel gebruiken als je geauthenticeerde schrijftoegang op je repository via een netwerk wilt. Ten tweede is het relatief eenvoudig in te stellen – SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig – alle data transporten zijn versleuteld en geauthenticeerd. En als laatste is SSH efficiënt, net zoals het Git en lokale protocol, de gegevens worden zo compact mogelijk gemaakt voordat het getransporteerd wordt. +Er zijn vele voordelen om SSH te gebruiken. Ten eerste moet je het eigenlijk wel gebruiken als je geauthenticeerde schrijftoegang op je repository via een netwerk wilt. Ten tweede is het relatief eenvoudig in te stellen – SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig – alle data transporten zijn versleuteld en geauthenticeerd. En als laatste is SSH efficiënt, net zoals bij het Git en lokale protocol worden de gegevens zo compact mogelijk gemaakt voordat het getransporteerd wordt. #### De Nadelen #### -Het negatieve aspect van SSH is dat je er geen anonieme toegang naar je repository over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken, zelfs als het alleen lezen is, zodat SSH toegang niet bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, dan is SSH misschien het enige protocol waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. +Het negatieve aspect van SSH is dat je er geen anonieme toegang naar je repository over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken zelfs als het alleen lezen is, dit maakt dat SSH toegang niet echt bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, is SSH wellicht het enige protocol waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. ### Het Git Protocol ### -Het volgende is het Git protocol. Dit is een specifieke daemon, die met Git meegeleverd wordt; het luistert op een toegewezen poort (9418), en verleent een vergelijkbare dienst als het SSH protocol, maar dan zonder enige vorm van authenticatie. Om een repository beschikbaar te stellen over het Git protocol, moet je een `git-export-daemon-ok` bestand aanmaken – de daemon zal een repository zonder dit bestand erin niet verspreiden – maar daarbuiten is er geen beveiliging. De Git repository beschikbaar om gecloned te kunnen worden door iedereen, of het is het niet. Dit betekent dat er over het algemeen geen pushing is via dit protocol. Je kunt push toegang aanzetten, maar gegeven het gebrek aan authenticatie kan als je de push toegang aan zet iedereen die de URL van jouw project op het internet vindt, pushen naar jouw project. We volstaan met te zeggen dat dit zelden de bedoeling kan zijn. +Het volgende is het Git protocol. Dit is een specifieke daemon, die met Git meegeleverd wordt. Het luistert op een toegewezen poort (9418), en verleent een vergelijkbare dienst als het SSH protocol, maar dan zonder enige vorm van authenticatie. Om een repository beschikbaar te stellen over het Git protocol, moet je een `git-export-daemon-ok` bestand aanmaken – de daemon zal een repository zonder dit bestand erin niet verspreiden – maar daarbuiten is er geen beveiliging. De Git repository is beschikbaar om gecloned te kunnen worden door iedereen, of het is het niet. Dit betekent dat er over het algemeen geen pushing is via dit protocol. Je kunt push toegang aanzetten maar gegeven het gebrek aan authenticatie kan, als je de push toegang aan zet, iedereen die de URL van jouw project op het internet vindt pushen naar jouw project. We volstaan met te zeggen dat dit zelden de bedoeling kan zijn. #### De Voordelen #### @@ -79,7 +79,7 @@ Het Git protocol is het snelste dat beschikbaar is. Als je veel verkeer verwerkt #### De Nadelen #### Het nadeel van het Git protocol is het gebrek aan authenticatie. Het is over het algemeen onwenselijk dat het Git protocol de enige toegang tot je project is. Meestal zul je het samen met SSH toegang gebruiken voor de paar ontwikkelaars die push (schrijf-)toegang hebben en de rest laat je `git://` voor alleen leestoegang gebruiken. -Het is waarschijnlijk ook het meest ingewikkelde protocol om in te richten. Het moet een eigen daemon hebben, die speciaal voor die situatie ingericht is – we zullen er een instellen in het "Gitosis" gedeelte van dit hoofdstuk – het gebruikt `xinetd` configuratie of iets vergelijkbaars, wat ook niet altijd eenvoudig is op te zetten. Daarbij is ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat in bedrijfsfirewalls is opengezet. Bij firewalls van grote bedrijven, is deze ongebruikelijke poort meestal dichtgezet. +Het is waarschijnlijk ook het meest ingewikkelde protocol om in te richten. Het moet een eigen daemon hebben, die speciaal voor die situatie ingericht is – we zullen er een instellen in de "Gitosis" paragraaf van dit hoofdstuk – het gebruikt `xinetd` configuratie of iets vergelijkbaars, wat ook niet altijd eenvoudig is op te zetten. Daarbij is ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat in bedrijfsfirewalls is opengezet. Bij firewalls van grote bedrijven, is deze ongebruikelijke poort meestal dichtgezet. ### Het HTTP/S Protocol ### @@ -91,41 +91,41 @@ 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 geleverd wordt, voert het noodzakelijke commando uit (`git update-server-info`) om HTTP fetching en cloning goed werkend te krijgen en houden. Dit commando wordt uitgevoerd als je via SSH naar deze repository pushed; en andere mensen kunnen clonen met behulp van zoiets als +Dat is alles. De `post-update` hook, die standaard bij Git geleverd wordt, voert het noodzakelijke commando uit (`git update-server-info`) om HTTP fetching en cloning goed werkend te krijgen en houden. Dit commando wordt uitgevoerd als je via SSH naar deze repository pushed, en andere mensen kunnen clonen met behulp van zoiets als $ git clone http://example.com/gitproject.git In dit specifieke voorbeeld gebruiken we het `/var/www/htdocs` pad wat gebruikelijk is voor Apache opstellingen, maar je kunt iedere statische webserver gebruiken – stop de kale repository in het betreffende pad. De Git data wordt geserveerd als standaard statische bestanden (zie hoofdstuk 9 voor details over hoe het precies geserveerd wordt). -Het is mogelijk om Git ook over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en het vraagt dat je complexe WebDAV instellingen inricht. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek beschrijven. Als je geïnteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Het aardige van Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken, zonder specifieke Git funtionaliteit, dus je kunt deze functionaliteit gebruiken als je web-hosting provider WebDAV ondersteunt voor het maken van wijzigingen aan je webpagina. +Het is mogelijk om Git ook over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en het vereist dat je complexe WebDAV instellingen inricht. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek behandelen. Als je geïnteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Het aardige van Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken zonder specifieke Git funtionaliteit, dus je kunt deze optie gebruiken als je web-hosting provider WebDAV ondersteunt voor het maken van wijzigingen aan je webpagina. #### De Voordelen #### -Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren is alles wat er moet gebeuren om de wereld leestoegang te geven tot je Git repository. Het neemt maar een paar minuten van je tijd. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te verspreiden - een normale Apache server kan gemiddeld duizenden bestanden zenden per seconde - is het moeilijk om zelfs een kleine server te overbelasten. +Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren is alles wat er moet gebeuren om de wereld leestoegang te geven tot je Git repository. Het neemt maar een paar minuten van je tijd. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te verspreiden is het moeilijk om zelfs een kleine server te overbelasten - een normale Apache server kan gemiddeld duizenden bestanden zenden per seconde. -Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat inhoudt dat je het transport kunt versleutelen; je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat laat gebruiken. Normaal gesproken als je je deze moeite wilt getroosten, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan in jouw specifieke geval een betere oplossing zijn om gesigneerde SSL certificaten of andere HTTP-gebaseerde authenticatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. +Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat inhoudt dat je het gegevenstransport kunt versleutelen; je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat laat gebruiken. Normaal gesproken als je je deze moeite wilt getroosten, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan in jouw specifieke geval een betere oplossing zijn om gesigneerde SSL certificaten of andere HTTP-gebaseerde authenticatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. Een andere prettige bijkomstigheid is dat HTTP een dusdanig veel voorkomend protocol is dat bedrijfsfirewalls vaak zo ingesteld zijn dat ze verkeer via deze poort toestaan. #### De Nadelen #### -Het nadeel van je repository verspreiden 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 veel hogere netwerk belasting en transport volume via HTTP dan met elk van de andere netwerk protocollen. Omdat het niet zo ingewikkeld is om alleen de data te versturen die je nodig hebt – er wordt geen dynamisch werk door de server gedaan in deze uitwisselingen – 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 verspreiden 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 veel hogere netwerk belasting en transport volume via HTTP dan met elk van de andere netwerk protocollen. Omdat het niet zo slim is om eerst te bepalen van welke gegevens het nodig is te versturen – er wordt geen dynamisch werk door de server gedaan in deze uitwisselingen – wordt vaak naar het HTTP protocol gerefereerd als het _domme_ 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 Git server initieel op te zetten, moet je een bestaande repository naar 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 conventie eindigen de namen van kale repository mappen met `.git`, zoals: +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 conventie eindigen de namen van kale repository mappen met `.git`, zoals hier: $ git clone --bare my_project my_project.git Initialized empty Git repository in /opt/projects/my_project.git/ -De output van dit commando is een beetje verwarrend. Omdat `clone` eigenlijk een `git init` en dan een `git fetch` is, zien we de output van het `git init` gedeelte, wat een lege map aanmaakt. De eigenlijke object overdracht geeft geen output, maar het gebeurt wel. Nu zou je een kopie van de Git map data in je `my_project.git` map moeten hebben. +De output van dit commando is een beetje verwarrend. Het commando `clone` is eigenlijk een `git init` en dan een `git fetch`, wat we hier zien is de output van het `git init` gedeelte wat een lege map aanmaakt. De eigenlijke object overdracht geeft geen output, maar het gebeurt wel. Nu zou je een kopie van de Git map data in je `my_project.git` map moeten hebben. Dit is ongeveer gelijk aan $ cp -Rf my_project/.git my_project.git -Er zijn een paar kleine verschillen in het configuratie bestand, maar het komt op hetzelfde neer. Het neemt de Git repository zelf, zonder een werkmap, en maakt een map aan specifiek hiervoor. +Er zijn een paar kleine verschillen in het configuratie bestand, maar het komt op hetzelfde neer. Het neemt de Git repository zelf, zonder een werkmap, en maakt een directory specifiek hiervoor aan. ### De Kale Repository op een Server Zetten ### @@ -505,25 +505,27 @@ Als je problemen hebt, kan het handig zijn om `loglevel=DEBUG` onder de `[gitosi ## Gitolite ## -Merk op: de laatste versie van deze paragraaf in het ProGit boek is altijd beschikbaar binnen de [gitolite documentation][gldpg]. De auteur geeft ook nederig aan dat, hoewel deze paragraaf accuraat is, het *kan* (en vaak ook *is*) gebruikt om gitolie te installeren zonder enige andere documentatie te lezen, dat het niet gegarandeerd compleet is, en het zeker niet de gehele enorme hoeveelheid documentatie kan vervangen dat meegeleverd wordt met gitolite. +Merk op: de laatste versie van deze paragraaf in het ProGit boek is altijd beschikbaar binnen de [gitolite documentation][gldpg]. De auteur geeft ook nederig aan dat, hoewel deze paragraaf accuraat is, het *kan* (en vaak ook *is*) worden gebruikt om gitolite te installeren zonder enige andere documentatie te lezen, maar dat je er vanuit mag gaan dat het niet compleet is, en het zeker niet de gehele enorme hoeveelheid documentatie kan vervangen dat meegeleverd wordt met gitolite. [gldpg]: http://github.com/sitaramc/gitolite/blob/pu/doc/progit-article.mkd -Git begint erg populair te worden in het bedrijfsleven, die de neiging hebben nog wat additionele eisen te hebben op het gebied van toegangscontrole. Gitolite was oorspronkelijk gemaakt om bij het vervullen van deze eisen te helpen, maar het blijkt dat het even bruikbaar is in de wereld van de open source: het Fedora Project beheert toegang tot hun package beheer repositories (meer dan 10.000 daarvan!) met gitolite, en het is waarschijnlijk daarbij ook nog eens de grootste gitolite installatie waar dan ook. +Git begint erg populair te worden in het bedrijfsleven, die de neiging heeft nog wat additionele eisen te hebben op het gebied van toegangscontrole. Gitolite was oorspronkelijk gemaakt om bij het vervullen van deze eisen te helpen, maar het blijkt dat het even bruikbaar is in de wereld van de open source: het Fedora Project beheert toegang tot hun package beheer repositories (meer dan 10.000 daarvan!) met gitolite, en het is daarbij waarschijnlijk ook nog eens de grootste gitolite installatie waar dan ook. Gitolite stelt je in staat de permissies niet alleen per repository, maar ook per branch of tag naam binnen elke repository. Dus, je kunt aangeven dat bepaalde mensen (of groepen van mensen) alleen maar bepaalde "refs" (branches of tags) kunnen pushen maar niet andere. ### Installatie ### -Het installeren van Gitolite is zeer eenvoudig, zelfs als je de uitgebreide documentatie, dat erbij geleverd wordt, niet leest. Je hebt een account op een Unix(achtige) server hebben; verschillende Linux smaken en Solaris 10 zijn getest. Je hebt geen root toegang nodig, aangenomen dat git, perl, en een openssh compatible ssh server al zijn geïnstalleerd. In de onderstaand voorbeelden zullen we het `gitolite` account gebruiken op een host genaamd `gitserver`. +Het installeren van Gitolite is zeer eenvoudig, zelfs als je de uitgebreide documentatie, dat erbij geleverd wordt, niet leest. Je hebt een account op een Unix(achtige) server nodig; verschillende Linux smaken en Solaris 10 zijn getest. Je hebt geen root toegang nodig, aangenomen dat git, perl, en een openssh compatible ssh server al zijn geïnstalleerd. In de onderstaande voorbeelden zullen we het `gitolite` account gebruiken op een host genaamd `gitserver`. -Gitolite is nogal ongebruikelijk in de zin van "server" software -- toegang gaat via ssh, en elke userid op de server is in potentie een "gitolite host". Het resultaat is, dat er een idee is van "installeren" van de software zelf, en dan het "opzetten" van een gebruiker als een "gitolist host". +Gitolite is nogal ongebruikelijk in de zin van "server" software -- toegang gaat via ssh, en elke userid op de server is in potentie een "gitolite host". Met als gevolg dat er een notie is van "installeren" van de software zelf, en dan het "opzetten" van een gebruiker als een "gitolist host". -Mensen zonder root toegang kunnen het installeren binnen hun eigen user id. Als laatste: gitlite kan geïnstalleerd worden door een script te starten *op het werkstation*, vanuit een bash-shell. (Zelfs de bash die meegeleverd wordt met msysgit volstaat, voor het geval je je dat afvroeg.) +Gitolite heeft 4 wijzen van installeren. Mensen die Fedora of Debian systemen gebruiken kunnen een RPM of DEB ophalen en deze installeren. Mensen met root toegang kunnen het handmatig installeren. Met deze twee methoden kan elke gebruiker op het systeem een "gitolite host" worden. + +Mensen zonder root toegang kunnen het installeren binnen hun eigen user id. En als laatste: gitlite kan geïnstalleerd worden door een script te starten *op het werkstation*, vanuit een bash-shell. (Zelfs de bash die meegeleverd wordt met msysgit volstaat, voor het geval je je dat afvroeg.) We zullen dit laatste in dit stuk beschrijven, voor de overige methoden verwijzen we je naar de documentatie. -Je begint met het verkrijgen van toegang op basis van een publieke sleutel, zodat je vanaf je werkstation op de server kan inloggen zonder het intypen van je wachtwoord. De volgende methode werkt op Linux; voor andere werkstation besturingssystemen moet je dit wellicht handmatig doen. We gaan er vanuit dat je al een sleutelpaar hebt gegenereerd met `ssh-keygen`. +Je begint met het verkrijgen van toegang naar je server op basis van een publieke sleutel, zodat je vanaf je werkstation op de server kan inloggen zonder het intypen van je wachtwoord. De volgende methode werkt op Linux; voor andere werkstation besturingssystemen moet je dit wellicht handmatig doen. We gaan er vanuit dat je al een sleutelpaar hebt gegenereerd met `ssh-keygen`. $ ssh-copy-id -i ~/.ssh/id_rsa gitolite@gitserver @@ -538,11 +540,11 @@ Vervolgens, clone je Gitolite van de hoofdsite van het project en roept de "easy $ cd gitolite/src $ ./gl-easy-install -q gitolite gitserver sitaram -En dat is het! Gitolite is nu geïnstalleerdop je server, en je hebt nu een gloednieuwe repository genaamd `gitolite-admin` in de home directory van jouw werkstation. Je beheert je gitolite setup door een wijziging aan te brengen in deze reporitory en deze te pushen. +En dat is het! Gitolite is nu geïnstalleerd op je server, en je hebt nu een gloednieuwe repository genaamd `gitolite-admin` in de home directory van jouw werkstation. Je beheert je gitolite setup door een wijziging aan te brengen in deze reporitory en deze te pushen. -Dat laatste commando produceert nogal een hoeveelheid uitvoer dat wellicht interessant is om te lezen. Ook wordt er, de eerste keer dat je het laat lopen, er een nieuwe sleutelpaar gemaakt; je moet een wachtwoord kiezen of Enter als je er geen wilt. Waarom een tweede sleutelpaar nodig is, en hoe deze wordt gebruikt, wordt uitgelegd in het "ssh troubleshooting" document dat bij Gitolite wordt meegeleverd. (Hey, de documentatie moet *ergens* goed voor zijn!) +Dat laatste commando produceert redelijk wat uitvoer, dat wellicht interessant is om te lezen. Ook wordt er, de eerste keer dat je het commando laat lopen, er een nieuwe sleutelpaar gemaakt; je moet een wachtwoord kiezen of Enter als je er geen wilt. Waarom een tweede sleutelpaar nodig is, en hoe deze wordt gebruikt, wordt uitgelegd in het "ssh troubleshooting" document dat bij Gitolite wordt meegeleverd. (Hey, de documentatie moet *ergens* goed voor zijn!) -Repositories genaamd `gitolite-admin` en `testing` worden standaard op de server aangemaakt. Als je een van beide lokaal wilt clonen (van een account die SSA console toegang heeft naar het gitolite account via *authorized_keys*) type je: +Repositories genaamd `gitolite-admin` en `testing` worden standaard op de server aangemaakt. Als je een van beide lokaal wilt clonen (van een account die SSH console toegang heeft naar het gitolite account via *authorized_keys*) type je: $ git clone gitolite:gitolite-admin $ git clone gitolite:testing @@ -558,7 +560,7 @@ Hoewel de standaard, snelle, installatie werkt voor de meeste mensen, zijn er ee ### Config bestand en Beheer van Toegangsregels ### -Op het moment dat de installatie afgerond is, schakel je over naar de `gitolite-admin` repository (staat in je HOME directory) en begin je rond te snuffelen om te zien wat je daar hebt: +Zodra de installatie afgerond is, schakel je over naar de `gitolite-admin` repository (die staat in je HOME directory) en begin je rond te snuffelen om te zien wat je daar hebt: $ cd ~/gitolite-admin/ $ ls @@ -580,7 +582,7 @@ Merk op dat "sitaram" (het laatste argument in het `gl-easy-install` commando da De syntax van het config bestand voor gitolite is ruimhartig van documentatie voorzien in `conf/example.conf`, dus we zullen alleen wat hoofdpunten benoemen. -Je kunt voor het gemak gebruikers of repositories groeperen. De groepnamen zijn vergelijkbaar met macros; als je ze definieert maakt het niet uit of het projecten of gebruikers zijn, dat onderscheid wordt pas gemaakt als je de "macro" gaat *gebruiken*. +Je kunt voor het gemak gebruikers of repositories groeperen. De groepnamen zijn vergelijkbaar met macros: als je ze definieert maakt het niet uit of het projecten of gebruikers zijn. Dat onderscheid wordt pas gemaakt als je de "macro" gaat *gebruiken*. @oss_repos = linux perl rakudo git gitolite @secret_repos = fenestra pear @@ -598,9 +600,9 @@ Je kunt de permissies beheren op het "ref" niveau. In het volgende voorbeeld kun RW refs/tags/rc[0-9] = @engineers RW+ = @admins -De expressie achter de `RW` of `RW+` is een zgn. regular expression (regex) waartegen de refname (ref) die wordt gepushed wordt vergeleken. Dus we noemen het natuurlijk een "refex"! En natuurlijk kan een refex veel krachtiger zijn dan hier wordt getoond, dus ga het niet overdrijven als je niet al te goed in de perl regexen zit. +De expressie achter de `RW` of `RW+` is een zgn. regular expression (regex) waartegen de refname (ref) die wordt gepushed wordt vergeleken. Dus we gaan we deze uiteraard een "refex" noemen! En natuurlijk kan een refex veel krachtiger zijn dan hier wordt getoond, dus ga het niet overdrijven als je niet al te goed in de perl regexen zit. -Zoals je wellicht al geraden hebt, prefixed Gitolite `refs/heads/` als een syntactische handigheid als de refex niet begint met `refs/`. +Zoals je wellicht al geraden hebt, gebruikt Gitolite de prefix `refs/heads/` als een syntactische handigheid indien de refex niet begint met `refs/`. Een belangrijke eigenschap van de syntax van het config bestand is dat alle regels van een repository niet op één plek hoeft te staan. Je kunt al het generieke spul bij elkaar houden, zoals de regels voor alle `oss_repos` zoals ze hier boven staan, en dan op een latere plaats specifieke regels voor specifieke gevallen, zoals hier: @@ -611,13 +613,13 @@ Deze regel wordt gewoon toegevoegd aan de set met regels voor de `gitolite` repo Je zou je op dit punt kunnen afvragen hoe de toegangsregels eigenlijk worden toegepast, laten we dat kort behandelen. -Er zijn twee niveaus van toegangsbeheer in gitolite. De eerste is op repository niveau. Als je lees (of schrijf)rechten hebt tot *enige* ref in de repository, dan heb je lees (of schrijf) rechten tot de repository. +Er zijn twee niveaus van toegangsbeheer in gitolite. De eerste is op repository niveau. Als je lees- of schrijfrechten hebt tot *enige* ref in de repository, dan heb je lees (of schrijf) rechten tot de repository. -Het tweede niveau, alleen van toepassing voor "schrijf" toegang, is per branch of tag binnen een repository. De gebruikersnaam, het type toegang wat wordt gevraagd (`W` of '+'), en de refname dat wordt gewijzigd (update) zijn bekend. De toegangsregels worden gecontroleerd in volgorde van voorkomst in het config bestand, en er wordt gekeken naar een treffer voor deze combinatie (maar onthoudt dat de refname middels een regex wordt vergeleken, niet een simpele string-vergelijking). Als er een treffer is, dan slaagt de push. Als er geen treffer wordt gevonden (fallthrough) dan wordt toegang geweigerd. +Het tweede niveau, alleen van toepassing voor "schrijf" toegang, is per branch of tag binnen een repository. De gebruikersnaam, het type toegang wat wordt gevraagd (`W` of '+'), en de refname dat wordt gewijzigd (geüpdate) zijn bekend. De toegangsregels worden gecontroleerd in volgorde van voorkomst in het config bestand, en er wordt gekeken naar een treffer voor deze combinatie (maar onthoudt dat de refname middels een regex wordt vergeleken, niet een simpele string-vergelijking). Als er een treffer is, dan slaagt de push. Als er geen treffer wordt gevonden (fallthrough) dan wordt toegang geweigerd. ### Geavanceerde Toegangs Controle met "deny" regels ### -Tot zover hebben we alleen permissies gezien uit het rijtje `R`, `RW` of `RW+`. Echter, gitolite kent een andere permissie: `-`, wat staat voor "deny" (ontken). Dit geeft je veel meer macht, tegen kosten van wat hogere complexiteit omdat een fallthrough nu niet de *enige* manier is waarop toegang kan worden geweigerd, wordt *de volgorde van regels belangrijk*! +Tot zover hebben we alleen permissies gezien uit het rijtje `R`, `RW` of `RW+`. Echter, gitolite kent een andere permissie: `-`, wat staat voor "deny" (ontken). Dit geeft je veel meer macht, tegen kosten van wat hogere complexiteit omdat een fallthrough nu niet de *enige* manier is waarop toegang kan worden geweigerd; nu wordt *de volgorde van regels belangrijk*! Stel dat, in de onderstaande situatie, we de techneuten in staat willen stellen elke branch te laten terugdraaien *behalve* master en integ. Dit is de manier om dat te doen: @@ -658,11 +660,11 @@ Gitolite laat je repositories specificeren met wildcards (eigenlijk perl regex e We ronden deze uiteenzetting af met een passe partout van andere eigenschappen, welke alle (en nog vele andere) tot in de kleinste detail zijn beschreven in de "faqs, tips, etc" en andere documenten. -**Logging**: Gitolite logt alle succesvolle toegangspogingen. Als je wat te los bent geweest in het toekennen van terugdraai permissies (`RW+`) en een of andere nozem heeft "master" vernaggelt, is de log-file een redder in de nood in de zin van snel en eenvoudig achterhalen van de SHA die verdwenen is. +**Logging**: Gitolite logt alle succesvolle toegangspogingen. Als je wat te los bent geweest in het toekennen van terugdraai permissies (`RW+`) en een of andere bijdehand heeft "master" vernaggelt, is de log-file een redder in de nood in de zin van snel en eenvoudig achterhalen van de SHA die verdwenen is. -**Git buiten reguliere PATH**: Een ontzettend handige eigenschap in gitolite is het ondersteunen van git buiten het regulier `$PATH` (dit komt vaker voor dan je zou denken, sommige bedrijfs omgevingen of zelfs sommige hosting providers weigeren dingen systeem-breed te installeren en je eindigt ermee dat je ze in je eigen directories zet). Normaalgesproken ben je gedwongen git aan de *client-side* op de een of andere manier te vertellen van deze niet-standaard locatie van de git binaries. Met gitolite hoe je alleen een verbose installatie te kiezen en `$GIT_PATH` in de "rc" bestanden in te vullen. Hierna geen wijzigingen aan de kant van de clients nodig :-) +**Git buiten reguliere PATH**: Een ontzettend handige eigenschap in gitolite is het ondersteunen van Git buiten het regulier `$PATH` (dit komt vaker voor dan je zou denken, sommige bedrijfs omgevingen of zelfs sommige hosting providers weigeren dingen systeem-breed te installeren en je eindigt ermee dat je ze in je eigen directories zet). Normaalgesproken ben je gedwongen Git aan de *client-side* op de een of andere manier te vertellen van deze niet-standaard locatie van de git binaries. Met gitolite hoe je alleen een verbose installatie te kiezen en `$GIT_PATH` in de "rc" bestanden in te vullen. Hierna geen wijzigingen aan de kant van de clients nodig :-) -**Rapportage van toegangsrechten**: Nog zo'n handige eigenschap is wat er gebeurt als je gewoon met ssh naar de server gaat. Gitolite laat zien welke repositories je toegang toe hebt en welke soort toegang dat dan wel is. Hier is een voorbeeld: +**Rapportage van toegangsrechten**: Nog zo'n handige eigenschap is wat er gebeurt als je gewoon met ssh naar de server gaat. Gitolite laat zien welke repositories je toegang toe hebt en welke soort toegang dat dan is. Hier is een voorbeeld: hello sitaram, the gitolite version here is v1.5.4-19-ga3397d4 the gitolite config gives you the following access: @@ -675,14 +677,15 @@ We ronden deze uiteenzetting af met een passe partout van andere eigenschappen, R shreelipi_converter -**Delegeringen**: Voor extreem grote installaties kan je de verantwoordelijkheid voor groepen van repositories delegeren aan verschilllende mensen en hen het beheer van die delen onafhankelijk laten regelen. Dit vermindert de werkdruk van de hoofd-beheerder, en maakt van hem minder een faalpunt. Deze eigenschap heeft zijn eigen docuentatie bestand in de `doc/` directory. +**Delegeren**: Voor extreem grote installaties kan je de verantwoordelijkheid voor groepen van repositories delegeren aan verschillende mensen en hen het beheer van die delen onafhankelijk laten regelen. Dit vermindert de werkdruk van de hoofd-beheerder, en maakt van hem minder een faalpunt. Deze eigenschap heeft zijn eigen documentatie in de `doc/` directory. -**Gitweb ondersteuning**: Gitolite ondersteunt gitweb op verschillende manieren. Je kunt aangeven welke repositories zichtbaar zijn via gitweb. Je kunt de "owner" (eigenaar) en "description" (omschrijving) voor gitweb vanuit de gitolite configuratie bestanden definiëren. Gitweb heeft een mechanisme beschikbaar waarmee toegang via HTTP wordt geïmplementeerd, deze kan je het "gecompileerde" config bestand van de gitolite config file laten gebruiken, wat inhoudt dat gitweb en gitolite dezelfde toegangsregels gebruikt (voor lees toegang). +**Gitweb ondersteuning**: Gitolite ondersteunt gitweb op verschillende manieren. Je kunt aangeven welke repositories zichtbaar zijn via gitweb. Je kunt de "owner" (eigenaar) en "description" (omschrijving) voor gitweb vanuit de gitolite configuratie bestanden definiëren. Gitweb heeft een mechanisme beschikbaar waarmee toegang via HTTP wordt geïmplementeerd, deze kan je het "gecompileerde" config bestand van de gitolite config file laten gebruiken, wat inhoudt dat gitweb en gitolite dezelfde toegangsregels gebruiken (voor lees toegang). +**Mirroring**: Gitolite kan je ondersteunen bij het beheren van meerdere mirrors, en het eenvoudig daartussen overschakelen als de primaire server uitvalt. ## Git Daemon ## -Voor publieke ongeauthenticeerde leestoegang tot je projecten zul je het HTTP protocol achter je willen laten, en overstappen op het Git protocol. De belangrijkste reden is snelheid. Het Git protocol is veel efficiënter en daarmee sneller dan het HTTP protocol, dus het zal je gebruikstijd besparen. +Voor publieke ongeauthenticeerde leestoegang tot je projecten zul je het HTTP protocol achter je willen laten, en overstappen op het Git protocol. De belangrijkste reden is snelheid. Het Git protocol is veel efficiënter en daarmee sneller dan het HTTP protocol, dus het zal je gebruikers tijd besparen. Nogmaals, dit is voor ongeauthenticeerde alleen-lezen toegang. Als je dit op een server buiten je firewall draait, zul je het alleen moeten gebruiken voor projecten die voor de hele wereld toegankelijk moeten zijn. Als de server waarop je het draait binnen je firewall staat, zou je het kunnen gebruiken voor projecten waarbij een groot aantal mensen of computers (continue integratie of bouwservers) alleen-lezen toegang moeten hebben, waarbij je niet voor iedereen een SSH sleutel wilt toevoegen. @@ -707,7 +710,7 @@ stop je dit script: /opt/git/ respawn -Omwille van veiligheidsredenen, wordt sterk aangeraden om deze daemon uit te voeren als gebruiker met alleen-lezen toegang op de repositories – je kunt dit makkelijk doen door een gebruiker 'git-ro' aan te maken en de daemon als deze uit te voeren. Om het eenvoudig te houden voeren we het als dezelfde 'git' gebruiker uit, als waarin Gitosis draait. +Omwille van veiligheidsredenen, wordt sterk aangeraden om deze daemon uit te voeren als gebruiker met alleen-lezen toegang op de repositories – je kunt dit makkelijk doen door een nieuwe gebruiker 'git-ro' aan te maken en de daemon als deze uit te voeren. Om het eenvoudig te houden voeren we het als dezelfde 'git' gebruiker uit, als waarin Gitosis draait. Als je de machine herstart, zal de Git daemon automatisch opstarten en herstarten als de server onderuit gaat. Om het te laten draaien zonder te herstarten, kun je dit uitvoeren: @@ -727,7 +730,7 @@ Als je besluit om Gitosis niet te gebruiken, maar je wilt toch een Git daemon in $ cd /path/to/project.git $ touch git-daemon-export-ok -De aanwezigheid van dat bestand vertelt Git dat het OK is om dit project zonder verificatie te serveren. +De aanwezigheid van dat bestand vertelt Git dat het OK is om dit project zonder authenticatie te serveren. Gitosis kan ook de projecten die GitWeb toont beheren. Eerst moet je zoiets als het volgende aan het `/etc/gitweb.conf` bestand toevoegen: @@ -742,40 +745,40 @@ 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 pushed, begint GitWeb automatisch je iphone project te tonen. ## Hosted Git ## -Als je niet al het werk wilt doen om je eigen Git server op te zetten, heb je meerdere opties om je Git project op een externe speciale hosting pagina te laten beheren. Dit biedt een aantal voordelen: een ge-hoste pagina is over het algemeen snel in te stellen, eenvoudig om projecten mee op te starten, en er komt geen serverbeheer en -onderhoud bij kijken. Zelfs als je je eigen server intern ingesteld hebt, zul je misschien een publieke host pagina voor je open source broncode willen – dat is over het algemeen makkelijker voor de open source commune te vinden en je er mee te helpen. +Als je niet al het werk wilt doen om je eigen Git server op te zetten, heb je meerdere opties om je Git project op een externe speciale hosting pagina te laten beheren. Dit biedt een aantal voordelen: een ge-hoste pagina is over het algemeen snel in te stellen, eenvoudig om projecten mee op te starten, en er komt geen serverbeheer en -onderhoud bij kijken. Zelfs als je je eigen server intern opgezet hebt, zul je misschien een publieke host pagina voor je open source broncode willen – dat is over het algemeen makkelijker voor de open source commune te vinden en je er mee te helpen. Vandaag de dag heb je een enorm aantal beheer opties om uit te kiezen, elk met verschillende voor- en nadelen. Om een bijgewerkte lijst te zien, ga dan kijken op de GitHosting pagina op de hoofd Git wiki: http://git.or.cz/gitwiki/GitHosting -Omdat we ze niet allemaal kunnen behandelen, en ik toevallig bij een ervan werk, zullen we deze paragraaf gebruiken het instellen van een account en het opzetten van een project op GitHub te doorlopen. Dit geeft je een idee van het benodigde werk. +Omdat we ze niet allemaal kunnen behandelen, en omdat ik toevallig bij een ervan werk, zullen we deze paragraaf gebruiken het instellen van een account en het opzetten van een project op GitHub te doorlopen. Dit geeft je een idee van het benodigde werk. -GitHub is veruit de grootste open source Git beheer pagina en het is ook een van de weinige die zowel publieke als privé beheer opties biedt, zodat je je open source en commerciele privé code op dezelfde plaats kunt bewaren. Sterker nog, we hebben GitHub gebruikt om privé samen te werken aan dit boek. +GitHub is verreweg de grootste open source Git beheer site en het is ook een van de weinige die zowel publieke als privé hosting opties biedt, zodat je je open source en commerciële privé code op dezelfde plaats kunt bewaren. Als voorbeeld: we hebben GitHub gebruikt om privé samen te werken aan dit boek. ### GitHub ### -GitHub verschilt een beetje van de meeste code-beheer pagina's in de manier waarop het de projecten een naamruimte geeft. In plaats dat het primair gebaseerd is op het project, stelt GitHub gebruikers centraal. Dat betekent dat als ik mijn `grit` project op GitHub beheer, je het niet zult vinden op `github.com/grit` maar in plaats daarvan op `github.com/schacon/grit`. Er is geen generieke versie van een project, wat een project toestaat om naadloos van de ene op de andere gebruiker over te gaan als de eerste auteur het project verlaat. +GitHub verschilt een beetje van de meeste code-beheer pagina's in de manier waarop het de projecten een benoemt. In plaats dat het primair gebaseerd is op het project, stelt GitHub gebruikers centraal. Dat betekent dat als ik mijn `grit` project op GitHub beheer, je het niet zult vinden op `github.com/grit` maar in plaats daarvan op `github.com/schacon/grit`. Er is geen allesoverheersende versie van een project, wat een project in staat stelt om naadloos van de ene op de andere gebruiker over te gaan als de eerste auteur het project verlaat. -GitHub is ook een commercieel bedrijf dat geld vraagt voor accounts die privé repositories beheren, maar iedereen kan snel een gratis account krijgen om zoveel open source projecten als ze willen te beheren. We zullen er snel doorheen lopen hoe je dat doet. +GitHub is ook een commercieel bedrijf dat geld vraagt voor accounts die privé repositories beheren, maar iedereen kan snel een gratis account krijgen om net zoveel open source projecten te beheren als ze willen. We zullen er snel doorheen lopen hoe je dat doet. ### Een Gebruikers Account Instellen ### -Het eerste dat je moet doen is een gratis gebruikers account instellen. Als je de Pricing and Signup pagina op `http://github.com/plans` bezoekt en de "Sign Up" knop aanklikt op het gratis account (zie figuur 4-2), dan wordt je naar de inteken pagina gebracht. +Het eerste dat je moet doen is een gratis gebruikers account aanvragen. Als je de Pricing and Signup pagina op `http://github.com/plans` bezoekt en de "Sign Up" knop aanklikt op het Free account (zie figuur 4-2), dan wordt je naar de inteken pagina gebracht. Insert 18333fig0402.png -Figuur 4-2. De GitHub inteken pagina. +Figuur 4-2. De GitHub plan pagina. -Hier moet je een gebruikersnaam kiezen die nog niet bezet is in het systeem, en een e-mail adres invullen dat bij het account hoort, en een wachtwoord (zie Figuur 4-3). +Hier moet je een gebruikersnaam kiezen die nog niet gebruikt is in het systeem, en een e-mail adres invullen dat bij het account hoort, en een wachtwoord (zie Figuur 4-3). Insert 18333fig0403.png Figuur 4-3. Het GitHub gebruikers inteken formulier. -Als je account beschikbaar hebt, is dit een goed moment om je publieke SSH sleutel ook toe te voegen. We hebben je eerder laten zien hoe je een nieuwe sleutel kunt genereren, in de "Eenvoudige Instellingen" sectie. Neem de inhoud van de publieke sleutel van dat paar, en plak het in het SSH publieke sleutel tekstveld. Door op de "explain ssh keys" link te klikken wordt je naar gedetaileerde instructies gebracht die je vertellen hoe dit te doen op alle veelgebruikte besturingssystemen. -Door op de "I agree, sign me up" knop te klikken wordt je naar je nieuwe gebruikers dashboard gebracht (zie Figuur 4-4). +Als je account beschikbaar is, is dit een goed moment om je publieke SSH sleutel ook toe te voegen. We hebben het genereren van een nieuwe sleutel eerder behandeld, in de "Je Publieke SSH Sleutel Genereren" paragraaf. Neem de inhoud van de publieke sleutel van dat paar, en plak het in het SSH publieke sleutel tekstveld. Door op de "explain ssh keys" link te klikken wordt je naar gedetaileerde instructies gebracht die je vertellen hoe dit te doen op alle veelvoorkomende besturingssystemen. +Door op de "I agree, sign me up" knop te klikken wordt je naar het dashboard van je nieuwe gebruikers gebracht (zie Figuur 4-4). Insert 18333fig0404.png Figuur 4-4. Het GitHub gebruikers dashboard. @@ -789,7 +792,7 @@ Start door op de "create a new one" link te klikken naast Your Repositories op h Insert 18333fig0405.png Figuur 4-5. Een nieuw repository aanmaken op GitHub. -Het enige dat je eigenlijk moet doen is een projectnaam opgeven, maar je kunt ook een beschrijving toevoegen. Wanneer je dat gedaan hebt, klik dan op de "Create Repository" knop. Nu heb je een nieuw repository op GitHub (zie Figuur 4-6). +Het enige dat je eigenlijk moet doen is een projectnaam opgeven, maar je kunt ook een beschrijving toevoegen. Wanneer je dat gedaan hebt, klik je op de "Create Repository" knop. Nu heb je een nieuw repository op GitHub (zie Figuur 4-6). Insert 18333fig0406.png Figuur 4-6. GitHub project hoofd informatie. @@ -810,14 +813,14 @@ Als je een lokaal Git repository hebt, voeg dan GitHub als remote toe en push je $ git remote add origin git@github.com:testinguser/iphone_project.git $ git push origin master -Nu wordt je project beheerd op GitHub, en kun je de URL aan iedereen geven waarmee je je project wilt delen. In dit geval is het `http://githup.com/testinguser/iphone_project`. Je kunt aan het begin van ieder van je project pagina's zien dat je twee Git URLs hebt (zie Figuur 4-8). +Nu wordt je project beheerd op GitHub, en kun je de URL aan iedereen geven waarmee je je project wilt delen. In dit geval is het `http://githup.com/testinguser/iphone_project`. Je kunt aan het begin van elk van je project pagina's zien dat je twee Git URLs hebt (zie Figuur 4-8). 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 Public Clone URL is een publieke alleen-lezen Git URL, waarmee iedereen het project kan clonen. Deel deze URL door 'm op je website neer te zetten of welke manier dan ook. -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 geupload hebt. Wanneer andere gebruikers deze project pagina bezoeken, zullen ze die URL niet zien – alleen de publieke. +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. ### Importeren vanuit Subversion ### @@ -832,12 +835,12 @@ Als je project erg groot is, niet standaard, of privé, dan zal dit process waar Laten we de rest van het team toevoegen. Als John, Josie en Jessica allemaal intekenen voor accounts op GitHub, en je wilt ze push toegang op je repository geven, kun je ze aan je project toevoegen als medewerkers. Door dat te doen zullen pushes vanaf hun publieke sleutels werken. -Klik de "edit" knop aan de bovenkant van het project, of de Admin tab, om de Admin pagina te bereiken van je GitHub project (zie Figuur 4-10). +Klik de "edit" knop of de Admin tab aan de bovenkant van het project, om de Admin pagina te bereiken van je GitHub project (zie Figuur 4-10). Insert 18333fig0410.png Figuur 4-10. GitHub administratie pagina. -Om een andere gebruiker schrijftoegang tot je project te geven, klik dan de "Add another collaborator" link. Er verschijnt een nieuw tekstveld, waarin je een gebruikersnaam kunt invullen. Op het moment dat je typt, komt er een hulp omhoog, waarin alle mogelijke overeenkomende gebruikersnamen staan. Als je de juiste gebruiker vind, klik dan de Add knop om die gebruiker als een medewerker aan je project toe te voegen (zie Figuur 4-11). +Om een andere gebruiker schrijftoegang tot je project te geven, klik dan de "Add another collaborator" link. Er verschijnt een nieuw tekstveld, waarin je een gebruikersnaam kunt invullen. Op het moment dat je typt, komt er een hulp tevoorschijn, waarin alle mogelijke overeenkomende gebruikersnamen staan. Als je de juiste gebruiker vindt, klik dan de Add knop om die gebruiker als een medewerker aan je project toe te voegen (zie Figuur 4-11). Insert 18333fig0411.png Figuur 4-11. Een medewerker aan je project toevoegen. @@ -847,20 +850,20 @@ Als je klaar bent met medewerkers toevoegen, dan zou je een lijst met de namen m Insert 18333fig0412.png Figuur 4-12. Een lijst met medewerkers aan je project. -Als je toegang van individuen moet intrekken, dan kun je de "revoke" link klikken, en dan wordt hun push toegang ingetrokken. Voor toekomstige projecten, kun je ook de medewerker groepen kopieeren door de permissies van een bestaand project te kopieeren. +Als je toegang van individuen moet intrekken, dan kun je de "revoke" link klikken, en dan wordt hun push toegang ingetrokken. Voor toekomstige projecten, kun je ook groepen medewerker kopiëren door de permissies van een bestaand project te kopiëren. ### Je Project ### -Nadat je je project gepushed hebt, of geimporteerd vanuit Subversion, heb je een hoofd project pagina die er uitziet zoals Figuur 4-13. +Nadat je je project gepushed 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 hoofpagina. -Als mensen je project bezoeken, zien ze deze pagina. Het bevat tabs naar de verschillende aspecten van je projecten. De Commits tab laat een lijst van commits in omgekeerde chronologische volgorde zien, vergelijkbaar met de output van het `git log` commando. De Network tab toont alle mensen die je project hebben geforked en bijgedragen hebben. De Downloads tab staat je toe project binaries te uploaden en naar tarballs en gezipte versies van ieder getagged punt in je project te linken. De Wiki tab voorziet in een wiki waar je documentatie kunt schrijven of andere informatie over je project. De Graphs tab heeft wat contributie visualisaties en statistieken over je project. De hoofd Source tab waarop je binnen komt toont de inhoud van de hoofdmap van je project en toont automatisch het README bestand eronder als je er een hebt. Deze tab toont ook een veld met de laatste commit informatie. +Als mensen je project bezoeken, zien ze deze pagina. Het bevat tabs naar de verschillende aspecten van je projecten. De Commits tab laat een lijst van commits in omgekeerde chronologische volgorde zien, vergelijkbaar met de output van het `git log` commando. De Network tab toont alle mensen die je project hebben geforked en bijgedragen hebben. De Downloads tab staat je toe project binaries te uploaden en naar tarballs en gezipte versies van ieder getagged punt in je project te linken. De Wiki tab voorziet in een wiki waar je documentatie kunt schrijven of andere informatie over je project. De Graphs tab heeft wat contributie visualisaties en statistieken over je project. De hoofd Source tab waarop je binnen komt, toont de inhoud van de hoofdmap van je project en toont automatisch het README bestand eronder als je er een hebt. Deze tab toont ook een veld met de laatste commit informatie. ### Projecten Forken ### -Als je aan een bestaand project waarop je geen push toegang hebt wilt bijdragen, dan moedigt GitHub het forken van een project toe. Als je op een project pagina belandt, die interessant lijkt en je wilt er een beetje op hacken, dan kun je de "fork" knop klikken aan de bovenkant van het project om GitHub dat project te laten kopieeren naar jouw gebruiker zodat je er naar kunt pushen. +Als je aan een bestaand project waarop je geen push toegang hebt wilt bijdragen, dan moedigt GitHub het forken van een project toe. Als je op een project pagina belandt, die interessant lijkt en je wilt er een beetje op hacken, dan kun je de "fork" knop klikken aan de bovenkant van het project om GitHub dat project te laten kopiëren naar jouw gebruiker zodat je er naar kunt pushen. Op deze manier hoeven projecten zich geen zorgen te maken over het toevoegen van medewerkers om ze push toegang te geven. Mensen kunnen een project forken en ernaar pushen, en de hoofdeigenaar van het project kan die wijzigingen pullen door ze als remotes toe te voegen en hun werk te mergen. @@ -882,6 +885,6 @@ Dat is alles wat we laten zien over GitHub, maar het is belangrijk om te zien ho Je hebt meerdere opties om een remote Git repository werkend te krijgen zodat je kunt samenwerken met anderen of je werk kunt delen. -Je eigen server draaien geeft je veel controle en staat je toe om de server binnen je firewall te draaien, maar zo'n server vraagt over het algemeen een redelijke hoeveelheid tijd om in te stellen en te onderhouden. Als je je gegevens op een beheerde server plaatst, is het eenvoudig in te stellen en te onderhouden; maar je moet in staat zijn je code op iemand anders zijn servers te bewaren, en sommige organisaties staan dit niet toe. +Je eigen server draaien geeft je veel controle en stelt je in staat om de server binnen je firewall te draaien, maar zo'n server vraagt over het algemeen een redelijke hoeveelheid tijd om in te stellen en te onderhouden. Als je je gegevens op een beheerde server plaatst, is het eenvoudig in te stellen en te onderhouden; maar je moet wel willen dat je code op de server van een derde opgeslagen is, en sommige organisaties staan dit niet toe. Het zou redelijk rechttoe rechtaan moeten zijn om te bepalen welke oplossing of combinatie van oplossingen van toepassing is op jou en je organisatie. From acf71489dd1cfe8455d9ec3cb6de85f47cdacab7 Mon Sep 17 00:00:00 2001 From: Ralph Haussmann Date: Mon, 20 Jan 2014 16:52:03 +0100 Subject: [PATCH 123/690] [de] Enhance section 9 --- de/09-git-internals/01-chapter9.markdown | 134 +++++++++++------------ 1 file changed, 67 insertions(+), 67 deletions(-) diff --git a/de/09-git-internals/01-chapter9.markdown b/de/09-git-internals/01-chapter9.markdown index d17dafdbc..6f92c1d00 100644 --- a/de/09-git-internals/01-chapter9.markdown +++ b/de/09-git-internals/01-chapter9.markdown @@ -3,15 +3,15 @@ -Möglicherweise hast Du dieses Kapitel hier direkt aufgeschlagen, vorherige Kapitel ausgelassen, oder bist hierher gelangt, nachdem Du alle vorherigen Kapitel gelesen hast. Wie auch immer, in diesem Kapitel wirst Du mit mit der internen Funktionsweise und der Implementierung von Git befassen. Meine eigene Erfahrung ist, dass das Lernen dieser Dinge unerlässlich ist, um zu verstehen, wie unheimlich mächtig und flexibel Git ist. Allerdings gibt es Leute, die der Ansicht sind, dass sie auch verwirrend und unnötig komplex für Anfänger sein können. Deshalb habe ich mich entschieden, dieses Kapitel an das Ende des Buches zu verlegen. Du kannst es, ganz wie es Dir beliebt, früher oder später einschieben. +Möglicherweise hast Du dieses Kapitel hier direkt aufgeschlagen, vorherige Kapitel ausgelassen, oder bist hierher gelangt, nachdem Du alle vorherigen Kapitel gelesen hast. Wie auch immer, in diesem Kapitel werden wir uns mit der internen Funktionsweise und der Implementierung von Git befassen. Meine eigene Erfahrung ist, dass das Lernen dieser Dinge unerlässlich ist, um zu verstehen, wie unheimlich mächtig und flexibel Git ist. Allerdings gibt es Leute, die der Ansicht sind, dass sie auch verwirrend und unnötig komplex für Anfänger sein können. Deshalb habe ich mich entschieden, dieses Kapitel an das Ende des Buches zu verlegen. Du kannst es, ganz wie es Dir beliebt, früher oder später einschieben. -Lass uns also loslegen. Zunächst will ich betonen, falls das bisher noch nicht klargeworden ist, dass Git im seinen Grundzügen ein Dateisystem ist, dessen Inhalte addressierbar sind und auf dem ein VCS-Interface aufgesetzt ist. Wir werden gleich genauer darauf eingehen, was das heißt. +Lass uns also loslegen. Zunächst will ich betonen, falls das bisher noch nicht klargeworden ist, dass Git im seinen Grundzügen ein Dateisystem ist, dessen Inhalte addressierbar sind und auf dem eine VCS-Schnittstelle aufgesetzt ist. Wir werden gleich genauer darauf eingehen, was das heißt. -In den frühen Tagen von Git (d.h. vor Version 1.5) war das Interface sehr viel komplexer, weil es diese Dateisystem-Eigenschaften stark betonte – im Gegensatz zu einem ausgearbeiteten VCS. In den letzten Jahren wurde das Interface dann stückweise verbessert und verfeinert, sodass es heute so einfach verständlich und einfach zu verwenden ist, wie alle möglichen vergleichbaren Systeme, die es gibt. Allerdings besteht scheinbar weiterhin das Vorurteil, das Git-Interface sei komplex und schwer zu erlernen. +In den frühen Tagen von Git (d.h. vor Version 1.5) war die Benutzerschnittstelle sehr viel komplexer, weil es die Dateisystem-Eigenschaften stark betonte – im Gegensatz zu einem herkömmlichen VCS. In den letzten Jahren wurde die Benutzerschnittstelle dann stückweise verbessert und verfeinert, sodass es heute so einfach verständlich und einfach zu verwenden ist, wie andere vergleichbare Systeme, die auf dem Markt erhältlich sind. Allerdings besteht scheinbar weiterhin das Vorurteil, das Git-Interface sei komplex und schwer zu erlernen. @@ -30,7 +30,7 @@ Die ersten acht Kapitel dieses Buches haben sich fast ausschließlich mit „Por -Wenn Du `git init` in einem neuen oder bereits bestehenden Verzeichnis ausführst, erzeugt Git das `.git`-Verzeichnis, das fast alle Dateien enthält, die Git intern speichert und ändert. Wenn Du eine Sicherheitskopie Deines Repositorys anlegen oder es duplizieren willst, dann reicht aus, dieses Verzeichnis zu kopieren. Dieses ganze Kapitel handelt praktisch nur von den Inhalten dieses Verzeichnisses – die so aussehen: +Wenn Du `git init` in einem neuen oder bereits bestehenden Verzeichnis ausführst, erzeugt Git das `.git`-Verzeichnis, das fast alle Dateien enthält, die Git intern speichert und ändert. Wenn Du eine Sicherheitskopie Deines Repositorys anlegen oder es duplizieren willst, dann reicht es aus, dieses Verzeichnis zu kopieren. Dieses ganze Kapitel handelt praktisch nur von den Inhalten dieses Verzeichnisses. Schauen wir es uns einmal an: $ ls HEAD @@ -49,7 +49,7 @@ Möglicherweise findest Du darin weitere Dateien. Obiges stammt aus einem mit `g -Damit bleiben vier wichtige Einträge übrig: die Dateien `HEAD` und `index` und die Verzeichnisse `objects` und `refs`. Dies sind die Kernkomponenten eines Git-Repositorys: Im `objects`-Verzeichnis befinden sich die Inhalte der Datenbank. Das `refs`-Verzeichnis enthält Referenzen auf Commit-Objekte (Branches) in dieser Datenbank. Die Datei `HEAD` zeigt auf denjeningen Branch, den Du gegenwärtig ausgecheckt hast, und in der Datei `index` verwaltet Git die Informationen der Staging-Area. Wir werden auf diese Elemente jetzt im einzelnen darauf eingehen, sodass Du nachvollziehen kannst, wie Git intern arbeitet. +Damit bleiben vier wichtige Einträge übrig: die Dateien `HEAD` und `index` und die Verzeichnisse `objects` und `refs`. Dies sind die Kernkomponenten eines Git-Repositorys. Im `objects`-Verzeichnis befinden sich die Inhalte der Datenbank. Das `refs`-Verzeichnis enthält Referenzen auf Commit-Objekte (Branches) in dieser Datenbank. Die Datei `HEAD` zeigt auf denjeningen Branch, den Du gegenwärtig ausgecheckt hast, und in der Datei `index` verwaltet Git die Informationen der Staging-Area. Wir werden auf diese Elemente jetzt im einzelnen darauf eingehen, sodass Du nachvollziehen kannst, wie Git intern arbeitet. ## Git Objekte ## @@ -57,7 +57,7 @@ Damit bleiben vier wichtige Einträge übrig: die Dateien `HEAD` und `index` und -Git ist ein Dateisystem, das Inhalte addressieren kann. Prima. Aber was heißt das? Es bedeutet, dass Git im Kern nichts anderes ist als ein einfacher Key-Value-Store („Schlüssel-Wert-Speicher“). Du kannst darin jede Art von Inhalt ablegen und Git wird einen Schlüssel dafür zurückgeben, den Du dann verwenden kannst, um diesen Inhalt jederzeit nachzuschlagen. Um das auszuprobieren, kannst Du den Plumbing-Befehl `hash-object` verwenden. Dieser nimmt einen Inhalt an, speichert ihn in Deinem `.git`-Verzeichnis und gibt Dir den Schlüssel zurück, unter dem der Inhalt gespeichert wurde. Dazu initialisierst Du als erstes ein neues Git-Repository und verifizierst, dass das `objects`-Verzeichnis leer ist: +Git ist ein Dateisystem, das Inhalte addressieren kann. Prima. Aber was heißt das? Es bedeutet, dass Git im Kern nichts anderes ist als ein einfacher Key-Value-Store („Schlüssel-Wert-Speicher“). Du kannst darin jede Art von Inhalt ablegen und Git wird einen Schlüssel dafür zurückgeben, den Du dann verwenden kannst, um diesen Inhalt jederzeit nachzuschlagen. Um das auszuprobieren, kannst Du den Plumbing-Befehl `hash-object` verwenden. Dieser nimmt Daten entgegen, speichert diese in Deinem `.git`-Verzeichnis und gibt Dir den Schlüssel zurück, unter dem der Inhalt gespeichert wurde. Dazu initialisierst Du als erstes ein neues Git-Repository und verifizierst, dass das `objects`-Verzeichnis leer ist: $ mkdir test $ cd test @@ -79,25 +79,25 @@ Git hat also ein Verzeichnis `objects` und darin die Unterverzeichnisse `pack` u -Die Option `-w` weist `git hash-object` an, das Objekt zu speichern. Andernfalls würde Dir der Befehl lediglich den Schlüssel mitteilen. `--stdin` weist den Befehl an, den Inhalt von aus der Standardeingabe zu lesen. Wenn Du diese Option weglässt, erwartet der Befehl zusätzlich einen Dateipfad. Die Ausgabe ist eine 40 Zeichen langer SHA-1-Hash, der eine Prüfsumme des gespeicherten Inhaltes darstellt (wir gehen auf diese Hashes gleich noch genauer ein). Git hat jetzt außerdem eine neue Datei in der Datenbank angelegt: +Die Option `-w` weist `git hash-object` an, das Objekt zu speichern. Andernfalls würde Dir der Befehl lediglich den Schlüssel mitteilen. `--stdin` weist den Befehl an, den Inhalt von der Standardeingabe einzulesen. Wenn Du diese Option weglässt, erwartet der Befehl zusätzlich einen Dateipfad. Die Ausgabe ist ein 40 Zeichen langer SHA-1-Hash, der eine Prüfsumme des gespeicherten Inhaltes darstellt (wir gehen auf diese Hashes gleich noch genauer ein). Git hat jetzt außerdem eine neue Datei in der Datenbank angelegt: $ find .git/objects -type f .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 -Du siehst im `objects` Verzeichnis genau eine Datei. Auf diese Weise Git speichert Inhalte anfänglich: in jeweils einer Datei pro Inhalt, referenziert durch den SHA-1-Hash des Inhaltes und seiner Kopfzeile. Der Name des Unterverzeichnis `d6` sind die ersten zwei Zeichen des SHA-1-Hashes und der Dateiname die verbleibenden 38 Zeichen. +Jetzt liegt im Verzeichnis `objects` genau eine Datei. Anfangs speichert Git den Inhalt auf diese Art und Weise: In jeweils einer einzelnen Datei werden die Daten gespeichert, referenziert durch den SHA-1-Hash des Inhaltes und seines Headers. Der Name des Unterverzeichnis `d6` entspricht den ersten zwei Zeichen des SHA-1-Hashes. Die verbleibenden 38 Zeichen werden als Dateiname verwendet. -Mit dem Befehl `git cat-file` kannst Du den jeweiligen Inhalt nachschlagen. Dieser Befehl ist so etwas wie ein Schweizer Taschenmesser, wenn es um Objekte in der Git-Datenbank geht. Wenn Du die Option `-p` übergibst, versucht `git cat-file`, die Art des Inhaltes herauszufinden und die Anzeige entsprechend lesbar zu formatieren: +Mit dem Befehl `git cat-file` kannst Du den jeweiligen Inhalt nachschlagen. Dieser Befehl ist so etwas wie ein Schweizer Taschenmesser, wenn es um Objekte in der Git-Datenbank geht. Wenn Du die Option `-p` übergibst, versucht `git cat-file`, die Art des Inhaltes herauszufinden und lesbar darzustellen: $ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4 test content -Auf diese Weise kannst Du also Inhalte zu Git hinzufügen und von dort wieder nachschlagen. Das klappt auch mit Dateiinhalten. Wenn Du beispielsweise eine einzelne Datei versionskontrollieren willst, lege die Datei zunächst an und speichere ihren Inhalt in der Datenbank: +Auf diese Weise kannst Du also Inhalte zu Git hinzufügen und von dort wieder auslesen. Das klappt auch mit Dateiinhalten. Wenn Du beispielsweise eine einzelne Datei versionieren willst, legst Du dazu die Datei zunächst an und speicherst ihren Inhalt in der Datenbank: $ echo 'version 1' > test.txt $ git hash-object -w test.txt @@ -148,7 +148,7 @@ Sich den SHA-1-Hash für jede Version merken zu müssen, ist allerdings nicht so -Als Nächstes schauen wir uns den Objekttyp „Tree“ (Baum) an, der es ermöglicht, Dateinamen zu speichern und Dateien zu gruppieren. Git speichert Inhalte in einer ähnlichen Weise wie das UNIX-Dateisystem, allerdings ein bisschen vereinfacht. Sie werden als Tree- und Blob-Objekte abgelegt, wobei die Trees mit UNIX-Verzeichnis-Einträgen korrespondieren und Blobs mehr oder weniger mit den inode-Einträgen bzw. Datei-Inhalten. Ein einzelnes Baum-Objekt enthält einen oder mehrere Einträge, von denen jeder ein SHA-1-Hash ist, der wiederum einen Blob oder einen Untertree referenziert. Jeder dieser Einträge verfügt außerdem über einen Modus, Typ und Dateinamen. Beispielsweise sieht das aktuelle Tree-Objekt im simplegit-Projekt möglicherweise so aus: +Als Nächstes schauen wir uns den Objekttyp „Tree“ (Baum) an, der es ermöglicht, Dateinamen zu speichern und Dateien zu gruppieren. Git speichert Inhalte in einer ähnlichen Weise wie das UNIX-Dateisystem, allerdings ein bisschen vereinfacht. Sie werden als Tree- und Blob-Objekte abgelegt, wobei die Trees mit UNIX-Verzeichnis-Einträgen korrespondieren und Blobs mehr oder weniger mit den Inode-Einträgen bzw. Datei-Inhalten. Ein einzelnes Baum-Objekt enthält einen oder mehrere Einträge, von denen jeder ein SHA-1-Hash ist, der wiederum einen Blob oder einen Untertree referenziert. Jeder dieser Einträge verfügt außerdem über einen Modus, Typ und Dateinamen. Beispielsweise sieht das aktuelle Tree-Objekt im simplegit-Projekt möglicherweise so aus: $ git cat-file -p master^{tree} 100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README @@ -157,7 +157,7 @@ Als Nächstes schauen wir uns den Objekttyp „Tree“ (Baum) an, der es ermögl -Die `master^{tree}`-Syntax spezifiziert, dass wir an dem Tree-Objekt interessiert sind, auf das der letzte Commit des `master`-Branches zeigt. Beachte, dass das Unterverzeichnis `lib` nicht auf ein Blob, sondern wiederum auf einen weiteren Baum zeigt. +Die `master^{tree}`-Syntax spezifiziert, dass wir an dem Tree-Objekt interessiert sind, auf das der letzte Commit des Branches `master` zeigt. Beachte, dass das Unterverzeichnis `lib` nicht auf ein Blob, sondern wiederum auf einen weiteren Baum zeigt. $ git cat-file -p 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 100644 blob 47c6340d6459e05787f644c2447d2595f5d3a54b simplegit.rb @@ -173,7 +173,7 @@ Bild 9-1. Vereinfachte Darstellung des Git-Datenmodels. -Du kannst auch Deine eigenen Tree-Objekte anlegen. Git erzeugt Trees normalerweise, indem es die Inhalte der Staging-Area nimmt und als ein Tree-Objekt speichert. D.h., um ein Tree-Objekt anzulegen, musst Du zunächst einen Index (d.h. eine Staging-Area) erzeugen, indem Du einige Dateien hinzufügst. Um einen einzelnen Eintrag in den Index zu schreiben – z.B. die erste version der Datei test.txt – kannst Du den Plumbing-Befehl `git update-index` verwenden, der eine frühere Version dieser Datei künstlich zu einer neuen Staging-Area hinzufügt. Du musst ihm die Option `--add` übergeben, weil die Datei bisher noch nicht in der Staging-Area enthalten ist (Du hast ja bisher noch überhaupt keine Staging-Area aufgesetzt), und die Option `--cacheinfo`, weil Du eine Datei hinzufügst, die sich nicht in Deinem Verzeichnis befindet, sondern in der Datenbank. Du gibst außerdem den Modus, SHA-1-Hash und den Dateinamen an: +Du kannst auch Deine eigenen Tree-Objekte anlegen. Git erzeugt Trees normalerweise, indem es die Inhalte der Staging-Area nimmt und als ein Tree-Objekt speichert. D.h., um ein Tree-Objekt anzulegen, musst Du zunächst einen Index (d.h. eine Staging-Area) aufbauen, indem Du einige Dateien hinzufügst. Um einen einzelnen Eintrag in den Index zu schreiben – z.B. die erste version der Datei test.txt – kannst Du den Plumbing-Befehl `git update-index` verwenden, der eine frühere Version dieser Datei künstlich zu einer neuen Staging-Area hinzufügt. Du musst ihm die Option `--add` übergeben, weil die Datei bisher noch nicht in der Staging-Area enthalten ist (Du hast ja bisher noch überhaupt keine Staging-Area aufgesetzt), und die Option `--cacheinfo`, weil Du eine Datei hinzufügst, die sich nicht in Deinem Verzeichnis befindet, sondern in der Datenbank. Du gibst außerdem den Modus, SHA-1-Hash und den Dateinamen an: $ git update-index --add --cacheinfo 100644 \ 83baae61804e65cc73a7201a7252750c76066a30 test.txt @@ -193,14 +193,14 @@ Jetzt kannst Du den Befehl `git write-tree` verwenden, um die Staging-Area als T -Um zu überprüfen, dass es wirklich ein Tree-Objekt gibt: +Um zu überprüfen, ob es sich wirklich um ein Tree-Objekt handelt: $ git cat-file -t d8329fc1cc938780ffdd9f94e0d364e0ea74f579 tree -Jetzt erzeugen wir einen neuen Tree mit der zweiten Version der Datei test.txt sowie eine neue Datei: +Jetzt erzeugen wir einen neuen Tree mit der zweiten Version der Datei test.txt sowie einer neuen Datei: $ echo 'new file' > new.txt $ git update-index test.txt @@ -218,7 +218,7 @@ Die Staging-Area enthält jetzt eine neue Version der Datei test.txt sowie die n -Beachte, dass das Tree-Objekt zwei Datei-Einträge hat und dass der SHA-1-Hash der Datei test.txt noch derselbe „Version 2“-Hash ist wie zuvor (`1f7a7a`). Fügen wir jetzt den ersten Tree als ein Unterverzeichnis in diesem hier ein. Du kannst einen Tree mit `git read-tree` in die Staging-Area einlesen. In diesem Fall können wir einen bereits existierenden Tree als einen Untertree zur Staging-Area hinzufügen, indem wir die Option `--prefix` verwenden: +Beachte, dass das Tree-Objekt beide Datei-Einträge hat und dass der SHA-1-Hash der Datei test.txt noch derselbe „Version 2“-Hash ist wie zuvor (`1f7a7a`). Fügen wir jetzt den ersten Tree als ein Unterverzeichnis in diesem hier ein. Du kannst einen Tree mit `git read-tree` in die Staging-Area einlesen. In diesem Fall können wir einen bereits existierenden Tree als einen Untertree zur Staging-Area hinzufügen, indem wir die Option `--prefix` verwenden: $ git read-tree --prefix=bak d8329fc1cc938780ffdd9f94e0d364e0ea74f579 $ git write-tree @@ -242,18 +242,18 @@ Bild 9-2. Die Datenstruktur des gegenwärtigen Git-Repositorys. -Du hast jetzt drei Trees, die verschiedene Snapshots Deines Projektes spezifizieren, die Du nachverfolgen willst. Das ursprüngliche Problem besteht aber weiterhin: Du musst dir alle drei SHA-1-Hashwerte merken, um wieder an die Snapshots zu kommen. Ebenso fehlen Dir die Informationen darüber, wer die Snapshots gespeichert hat, wann sie gespeichert wurden und warum. Dies sind die drei Hauptinformationen, die ein Commit-Objekt für uns speichert. +Du hast jetzt drei Trees, die verschiedene Snapshots Deines Projektes spezifizieren, die Du nachverfolgen willst. Das ursprüngliche Problem besteht aber weiterhin: Du musst Dir alle drei SHA-1-Hashwerte merken, um wieder an die Snapshots zu kommen. Ebenso fehlen Dir die Informationen darüber, wer die Snapshots gespeichert hat, wann sie gespeichert wurden und warum. Dies sind die drei Hauptinformationen, die ein Commit-Objekt für uns speichert. -Um ein Commit-Objekt anzulegen, verwendest Du den Befehl `git commit-tree`, spezifizierst den SHA-1-Hash eines einzelnen Trees und welche Commit-Objekte (sofern vorhanden) die direkten Vorgänger sind. Fangen wir damit an, den ersten Tree, den Du angelegt hast, zu committen: +Um ein Commit-Objekt anzulegen, verwendest Du den Befehl `git commit-tree`, spezifizierst den SHA-1-Hash eines einzelnen Trees und welche Commit-Objekte (sofern vorhanden) die direkten Vorgänger sind. Fangen wir damit an, den ersten Tree, den Du angelegt hast, einzuchecken: $ echo 'first commit' | git commit-tree d8329f fdf4fc3344e67ab068f836878b6c4951e3b15f3d -Du kannst diesen Commit jetzt mit `git cat-file` nachschlagen: +Du kannst Dir dann dieses neue Commit-Objekt mit `cat-file` anschauen: $ git cat-file -p fdf4fc3 tree d8329fc1cc938780ffdd9f94e0d364e0ea74f579 @@ -264,7 +264,7 @@ Du kannst diesen Commit jetzt mit `git cat-file` nachschlagen: -Das Format für ein Commit-Objekt ist einfach: es besteht aus dem obersten Tree für den Snapshot des Projektes zum gegebenen Zeitpunkt, die Autoren- und ggf. Committer-Information (jeweils entsprechend Deiner `user.name`- und `user.email`-Konfiguration) und dem Timestamp. Dann folgen eine leere Zeile und die Commit-Meldung. +Das Format für ein Commit-Objekt ist einfach: es besteht aus dem obersten Tree für den Snapshot des Projektes zum gegebenen Zeitpunkt, die Autoren- und ggf. Committer-Information (jeweils entsprechend Deiner `user.name`- und `user.email`-Konfiguration) und dem aktuellen Zeitstempel. Dann folgen eine leere Zeile und die Commit-Nachricht. @@ -277,7 +277,7 @@ Als Nächstes speichern wir die beiden anderen Commit-Objekte und referenzieren -Jedes der drei Commit-Objekte zeigt auf einen der drei Snapshot-Trees, die Du zuvor gespeichert hattest. Es mag Dich überraschen, aber Du hast jetzt bereits eine vollständige Git-Historie, die Du mit dem `git log` inspizieren kannst, indem Du den SHA-1-Hash des letzten Commits angibst: +Jedes der drei Commit-Objekte zeigt auf einen der drei Snapshot-Trees, die Du zuvor gespeichert hattest. Es mag Dich überraschen, aber Du hast jetzt bereits eine vollständige Git-Historie, die Du mit dem Befehl `git log` inspizieren kannst, indem Du den SHA-1-Hash des letzten Commits angibst: $ git log --stat 1a410e commit 1a410efbd13591db07496601ebc7a059dd55cfe9 @@ -326,7 +326,7 @@ Fantastisch, oder? Du hast jetzt sämtliche Low-Level-Operationen durchgeführt, -Wenn man all diese Zeiger auflöst, erhält man einen Objekt-Graphen wie den folgenden (Bild 9-3). +Wenn man all diese internen Zeiger nachverfolgt, erhält man einen Objekt-Graphen wie den folgenden (Bild 9-3). @@ -338,7 +338,7 @@ Bild 9-3. Alle Objekte in Deinem Git-Repository. -Wir haben kurz erwähnt, dass zusammen mit einem Inhalt ein Header gespeichert wird. Schauen wir uns also genauer an, wie genau Git Objekte speichert. Du wirst sehen, wie ein Blob-Objekt – in diesem Fall die Zeichenkette „what is up, doc?“ gespeichert wird. Dazu nuten wir den interaktiven Ruby-Modus, den Du mit dem `irb` Befehl starten kannst: +Ich habe bereits erwähnt, dass zusammen mit dem jeweiligen Inhalt ein Header gespeichert wird. Schauen wir uns also genauer an, wie genau Git Objekte speichert. Du wirst sehen, wie ein Blob-Objekt – in diesem Fall die Zeichenkette „what is up, doc?“ gespeichert wird. Dazu nutzen wir den interaktiven Ruby-Modus, den Du mit dem Befehl `irb` starten kannst: $ irb >> content = "what is up, doc?" @@ -353,7 +353,7 @@ Git erzeugt einen Header, der mit dem Objekttyp beginnt, in diesem Fall ist das -Git fügt diesen Header mit dem ursprünglichen Inhalt zusammen und kalkuliert aus dem Ergebnis die SHA-1-Prüfsumme (Hash). Du kannst einen SHA-1-Hash in Ruby berechnen, indem Du die SHA1-Digest-Bibliothek mit `require` einbindest und dann `Digest::SHA1.hexdigest()` mit der Zeichenkette ausführst: +Git fügt diesen Header mit dem ursprünglichen Inhalt zusammen und kalkuliert aus dem Ergebnis die SHA-1-Prüfsumme. Du kannst einen SHA-1-Hash in Ruby berechnen, indem Du die SHA1-Digest-Bibliothek mit `require` einbindest und dann `Digest::SHA1.hexdigest()` mit der Zeichenkette ausführst: >> store = header + content => "blob 16\000what is up, doc?" @@ -373,7 +373,7 @@ Git komprimiert den neuen Inhalt (d.h. inklusive des Headers) mit zlib. In Ruby -Schließlich schreibst Du den zlib-komprimierten Inhalt in eine Datei auf der Festplatte. Dazu bestimmst Du den Pfad, an den die Datei gespeichert wird (die ersten beiden Zeichen für das Unterverzeichnis und die verbleibenden 38 Zeichen für den Dateinamen). In Ruby kannst Du die Funktion `FileUtils.mkdir_p()` verwenden, um Unterverzeichnisse anzulegen, die noch nicht existieren. Dann öffnest die Datei mit `File.open()` und schreibst den komprimierten Inhalt mit `write()` in die Datei: +Schließlich schreibst Du den zlib-komprimierten Inhalt in eine Datei auf der Festplatte. Dazu bestimmst Du den Pfad, an den die Datei gespeichert wird (die ersten beiden Zeichen für das Unterverzeichnis und die verbleibenden 38 Zeichen für den Dateinamen). In Ruby kannst Du die Funktion `FileUtils.mkdir_p()` verwenden, um Unterverzeichnisse anzulegen, die noch nicht existieren. Dann öffnest Du die Datei mit `File.open()` und schreibst den komprimierten Inhalt mit `write()` in die Datei: >> path = '.git/objects/' + sha1[0,2] + '/' + sha1[2,38] => ".git/objects/bd/9dbf5aae1a3862dd1526723246b20206e5fc37" @@ -386,7 +386,7 @@ Schließlich schreibst Du den zlib-komprimierten Inhalt in eine Datei auf der Fe -Das ist alles – Du hast jetzt ein valides Git-Blob-Objekt geschrieben. Git-Objekte werden immer in dieser Weise gespeichert, lediglich mit verschiedenen Typen, d.h. anstelle der Zeichenkette „blob“ wird der Header mit „commit“ oder „tree“ anfangen. Außerdem sind Commit- und Tree-Inhalte auf eine sehr spezifische Weise formatiert, während Blobs beliebige Inhalte sein können. +Das ist alles – Du hast jetzt ein gültiges Blob-Objekt geschrieben. Git-Objekte werden immer in dieser Weise gespeichert, lediglich mit verschiedenen Typen, d.h. anstelle der Zeichenkette „blob“ wird der Header mit „commit“ oder „tree“ anfangen. Außerdem sind Commit- und Tree-Inhalte auf eine sehr spezifische Weise formatiert, während Blobs beliebige Inhalte sein können. ## Git-Referenzen ## @@ -397,7 +397,7 @@ Du kannst Befehle wie `git log 1a410e` ausführen, um die Commit-Historie zu ins -Diese Namen werden in Git intern als „references“ oder „refs“ bezeichnet. Du kannst diese Dateien, die SHA-1-Hashes enthalten, im Verzeichnis `.git/refs` finden. In unserem gegenwärtigen Projekt enthält dieses Verzeichnis noch keine Dateien, aber eine simple Verzeichnisstruktur: +Diese Namen werden in Git intern als „references“ oder „refs“ (also Referenz bzw. Verweis) bezeichnet. Du kannst diese Dateien, die SHA-1-Hashes enthalten, im Verzeichnis `.git/refs` finden. In unserem gegenwärtigen Projekt enthält dieses Verzeichnis noch keine Dateien, aber eine simple Verzeichnisstruktur: $ find .git/refs .git/refs @@ -452,14 +452,14 @@ Bild 9-4. Git-Verzeichnis-Objekte mit Branch-Head-Referenzen. -Wenn Du Befehle wie `git branch (branchname)` verwendest, führt Git intern im Wesentlichen den Befehl `update-ref` aus, um den SHA-1-Hash des letzten Commits des jeweils gegenwärtigen Branches mit dem gegebenen Namen zu referenzieren. +Wenn Du Befehle wie `git branch (Branch-Name)` verwendest, führt Git intern im Wesentlichen den Befehl `update-ref` aus, um den SHA-1-Hash des letzten Commits des jeweils gegenwärtigen Branches mit dem gegebenen Namen zu referenzieren. ### Der HEAD ### -Die Frage ist jetzt: Wenn Du `git branch (branchname)` ausführst, woher weiß Git den SHA-1 des letzten Commits? Die Antwort ist: aus der HEAD Datei. Diese Datei ist eine symbolische Referenz auf den jeweiligen Branch, auf dem Du Dich gerade befindest. Mit „symbolischer Referenz“ meine ich, dass sie (anders als eine „normale“ Referenz) keinen SHA-1-Hash enthält, sondern stattdessen auf eine andere Referenz zeigt. Wenn Du die Datei ansiehst, findest Du normalerweise etwas wie: +Die Frage ist jetzt: Wenn Du `git branch (Branch-Name)` ausführst, woher weiß Git den SHA-1 des letzten Commits? Die Antwort ist: aus der Datei HEAD. Diese Datei ist eine symbolische Referenz auf den jeweiligen Branch, auf dem Du Dich gerade befindest. Mit „symbolischer Referenz“ meine ich, dass sie (anders als eine „normale“ Referenz) keinen SHA-1-Hash enthält, sondern stattdessen auf eine andere Referenz zeigt. Wenn Du Dir die Datei ansiehst, findest Du normalerweise etwas wie: $ cat .git/HEAD ref: refs/heads/master @@ -537,7 +537,7 @@ Jetzt wendest Du den Befehl `git cat-file` auf diesen SHA-1-Hash an: -Beachte, dass der der Wert `object` auf den SHA-1 des Commits zeigt, den Du getaggt hast, und dass die `tags/v1.1` Referenz nicht direkt auf den Commit zeigt, sondern auf das Tag-Objekt. In Git kannst Du jedes beliebige Objekt taggen. Im Git-Quellcode z.B. befindet sich der öffentliche GPG-Schlüssel des Projektbetreibers als ein Blob-Objekt, sowie ein Tag, der darauf zeigt. Auf diese Weise kannst den Schlüssel so anzeigen, indem Du den folgenden Befehl im Git-Quellcode Repository ausführst: +Beachte, dass der der Wert `object` auf den SHA-1 des Commits zeigt, den Du getaggt hast. Weiterhin muss der Eintrag nicht auf einen Commit zeigen. In Git kann man jedes beliebige Objekt taggen. Im Git-Quellcode befindet sich beispielweise der öffentliche GPG-Schlüssel des Projektbetreibers als ein Blob-Objekt, sowie ein Tag, der darauf zeigt. Du kannst Dir den öffentlichen Schlüssel anzeigen lassen, indem du den folgenden Befehl im Git-Quellcode-Repository ausführst: $ git cat-file blob junio-gpg-pub @@ -550,7 +550,7 @@ Der Linux-Kernel hat auch ein Tag-Objekt, das nicht auf einen Commit zeigt – d -Der dritte Referenztyp ist die externe Referenz („remote reference“). Wenn Du einen externen Server („remote“) definierst und dorthin pushst, merkt sich Git den zuletzt gepushten Commit für jeden Branch im `refs/remotes` Verzeichnis. Bespielsweise fügst Du einen externen Server `origin` hinzu und pushst Deinen `master` Branch dorthin: +Der dritte Referenztyp ist die externe Referenz („remote reference“). Wenn Du einen externen Server („remote“) definierst und dorthin pushst, merkt sich Git den zuletzt gepushten Commit für jeden Branch im `refs/remotes` Verzeichnis. Bespielsweise fügst Du einen externen Server `origin` hinzu und pushst Deinen Branch `master` dorthin: $ git remote add origin git@github.com:schacon/simplegit-progit.git $ git push origin master @@ -563,7 +563,7 @@ Der dritte Referenztyp ist die externe Referenz („remote reference“). Wenn D -Dann kannst Du herausfinden, in welchem Zustand sich der `master`-Branch auf dem `origin`-Server zuletzt befand (d.h. als Du das letzte Mal mit ihm kommuniziert hast), indem Du die Datei `refs/remotes/origin/master` anschaust: +Dann kannst Du herausfinden, in welchem Zustand sich der Branch `master` auf dem Server `origin` zuletzt befand (d.h. als Du das letzte Mal mit ihm kommuniziert hast), indem Du Dir die Datei `refs/remotes/origin/master` anschaust: $ cat .git/refs/remotes/origin/master ca82a6dff817ec66f44342007202690a93763949 @@ -577,7 +577,7 @@ Externe Referenzen unterscheiden sich von Branches (`refs/heads`) hauptsächlich -Kommen wir noch einmal auf die Objekt-Datenbank zurück, die Du für Dein Test-Git-Repository angelegt hast. Im Moment müsstest Du 11 Objekte haben: 4 Blobs, 3 Trees, 3 Commits und 1 Tag: +Kommen wir noch einmal auf die Objekt-Datenbank zurück, die Du für Dein Test-Repository angelegt hast. Im Moment müsstest Du 11 Objekte haben: 4 Blobs, 3 Trees, 3 Commits und 1 Tag: $ find .git/objects -type f .git/objects/01/55eb4229851634a0f03eb265b69f5a2d56f341 # tree 2 @@ -674,7 +674,7 @@ Wenn Du das Objekt-Verzeichnis anschaust, siehst Du, dass die meisten Objekte je -Die verbleibenden Objekte sind diejenigen Blobs, die nicht von irgendeinem Commit referenziert werden – in diesem Fall sind das die Beispielblobs „what is up, doc?“ und „test content“, die wir zuvor gespeichert hatten: weil wir sie nie zu irgendeinem Commit hinzugefügt haben, werden sie als „dangling“ (wörtlich: herumbaumelnd) betrachtet und nicht im Packfile zusammengepackt. +Die verbleibenden Objekte sind diejenigen Blobs, die nicht von irgendeinem Commit referenziert werden – in diesem Fall sind das die Beispielblobs „what is up, doc?“ und „test content“, die wir zuvor gespeichert hatten. Weil wir sie nie zu irgendeinem Commit hinzugefügt haben, werden sie als „dangling“ (wörtlich: herumbaumelnd) betrachtet und nicht im Packfile zusammengepackt. @@ -721,7 +721,7 @@ Außerdem ist toll, dass ein Repository jederzeit neu gepackt werden kann. Git m -In diesem Buch haben wir bisher einfache Zuweisungen von externen Branches auf lokale Referenzen verwendet. Sie können aber auch durchaus komplex sein. Nehmen wir an, Du hast ein externes Repository wie folgt definiert: +In diesem Buch haben wir bisher einfache Zuweisungen von externen Branches auf lokale Referenzen verwendet. Sie können aber auch durchaus komplex sein. Nehmen wir an, Du hast ein Remote-Repository wie folgt definiert: $ git remote add origin git@github.com:schacon/simplegit-progit.git @@ -735,11 +735,11 @@ Das fügt eine Sektion in Deine `.git/config`-Datei hinzu, die Deinen lokalen Na -Das Format der Refspec besteht aus einem optionalen `+` gefolgt von `:`, wobei `` ein Muster für Referenzen auf der Remote-Seite ist, und `` angibt, wohin diese Referenzen lokal geschrieben werden. Das `+` weist Git an, die Referenz zu mergen, wenn sie nicht mit einem Fast-forward aktualisiert werden kann. +Das Format der Refspec besteht aus einem optionalen `+` gefolgt von `:`, wobei `` ein Muster für Referenzen auf der Remote-Seite ist, und `` angibt, wohin diese Referenzen lokal geschrieben werden. Das `+` weist Git an, die Referenz zu mergen, wenn sie nicht mit einem Fast-forward aktualisiert werden kann. -Der Standard, der von `git remote add` automatisch eingerichtet wird, besteht darin, dass Git automatisch alle Referenzen unter `refs/heads/` vom Server holt und sie lokal nach `refs/remotes/origin` speichert. D.h., wenn es auf dem Server einen `master`-Branch gibt, kannst Du auf das Log dieses Branches wie folgt zugreifen: +Der Standard, der von `git remote add` automatisch eingerichtet wird, besteht darin, dass Git automatisch alle Referenzen unter `refs/heads/` vom Server holt und sie lokal nach `refs/remotes/origin` speichert. D.h., wenn es auf dem Server einen Branch `master` gibt, kannst Du auf das Log dieses Branches wie folgt zugreifen: $ git log origin/master $ git log remotes/origin/master @@ -751,19 +751,19 @@ Diese Varianten sind allesamt äquivalent, weil Git sie jeweils zu `refs/remotes -Wenn Du stattdessen willst, dass Git jeweils nur den `master`-Branch herunterlädt und andere Branches auf dem Server ignoriert, kannst Du die `fetch`-Zeile wie folgt ändern: +Wenn Du stattdessen willst, dass Git jeweils nur den Branch `master` herunterlädt und andere Branches auf dem Server ignoriert, kannst Du die `fetch`-Zeile wie folgt ändern: fetch = +refs/heads/master:refs/remotes/origin/master -Dies ist allerdings lediglich der Standardwert der Refspec und Du kannst ihn auf der Kommandozeile jederzeit überschreiben. Um zum Beispiel nur den `master`-branch vom Server lokal als `origin/mymaster` zu speichern, kannst Du Folgendes ausführen: +Dies ist allerdings lediglich der Standardwert der Refspec und Du kannst ihn auf der Kommandozeile jederzeit überschreiben. Um zum Beispiel nur den Branch `master` vom Server lokal als `origin/mymaster` zu speichern, kannst Du Folgendes ausführen: $ git fetch origin master:refs/remotes/origin/mymaster -Du kannst auch mehrere Refspecs gleichzeitig spezifizieren. Z.B.: +Du kannst auch mehrere Refspecs gleichzeitig spezifizieren. Um mehrere Branches zu holen kannst du folgenden Befehl in die Kommandozeile eingeben: $ git fetch origin master:refs/remotes/origin/mymaster \ topic:refs/remotes/origin/topic @@ -792,7 +792,7 @@ Du kannst keine partiellen Glob-Muster verwenden, d.h. Folgendes wäre ungültig -Allerdings kannst Du Namensräume verwenden, um etwas Ähnliches zu erreichen. Nehmen wir an, Du hast ein QA-Team, das regelmäßig verschiedene Branches pusht, und Du willst nun den master-Branch und sämtliche Branches des QA-Teams, aber keine anderen Branches haben. Dann kannst Du eine Config-Sektion wie die folgende verwenden: +Allerdings kannst Du Namensräume verwenden, um etwas Ähnliches zu erreichen. Nehmen wir an, Du hast ein QA-Team, das regelmäßig verschiedene Branches pusht, und Du willst nun den Branch master und sämtliche Branches des QA-Teams, aber keine anderen Branches haben. Dann kannst Du eine Config-Sektion wie die folgende verwenden: [remote "origin"] url = git@github.com:schacon/simplegit-progit.git @@ -812,7 +812,7 @@ Wie aber legt das QA-Team die Branches im `qa/` Namensraum ab? Das geht, indem m -Wenn das QA-Team seinen `master` Branch in einem externen Repository als `qa/master` speichern will, kann es das wie folgt tun: +Wenn das QA-Team seinen Branch `master` in einem externen Repository als `qa/master` speichern will, kann es das wie folgt tun: $ git push origin master:refs/heads/qa/master @@ -827,7 +827,7 @@ Um Git so zu konfigurieren, dass diese Refspec jedes Mal automatisch für `git p -Auf diese Weise wird `git push origin` den lokalen Branch `master` als `qa/master` auf dem `origin` Server speichern. +Auf diese Weise wird `git push origin` den lokalen Branch `master` als `qa/master` auf dem Server `origin` speichern. ### Referenzen löschen ### @@ -840,7 +840,7 @@ Man kann Refspecs außerdem verwenden, um Referenzen aus einem externen Reposito -Das Refspec Format ist `:`. Wenn man den Teil `` weglässt, dann heißt das im obigen Beispiel, dass man den `topic` Branch auf dem `origin` Server auf „nichts“ setzt, d.h. also löscht. +Das Refspec Format ist `:`. Wenn man den Teil `` weglässt, dann heißt das im obigen Beispiel, dass man den Branch `topic` auf dem Server `origin` auf „nichts“ setzt, d.h. also löscht. ## Transfer-Protokolle ## @@ -854,31 +854,31 @@ Git kann Daten zwischen zwei Repositorys im Wesentlichen auf zwei Arten transpor -Das HTTP-Transfer-Protokoll von Git wird oft auch als „dummes“ Protokoll bezeichnet, weil es auf der Server-Seite keinen Git-spezifischen Code benötigt. Der `fetch`-Prozess besteht aus einer Reihe von GET-Requests, für die der Client Vorannahmen über das Layout des Git-Repositorys auf dem Server machen kann. Schauen wir uns den `http-fetch`-Prozess der `simplegit`-Bibliothek an: +Das HTTP-Transfer-Protokoll von Git wird oft auch als „dummes“ Protokoll bezeichnet, weil es auf der Server-Seite keinen Git-spezifischen Code benötigt. Der `fetch`-Prozess besteht aus einer Reihe von GET-Requests, für die der Client Vorannahmen über das Layout des Git-Repositorys auf dem Server machen kann. Schauen wir uns den `http-fetch`-Prozess der Bibliothek `simplegit` an: $ git clone http://github.com/schacon/simplegit-progit.git -Der Befehl lädt zunächst die `info/refs` Datei herunter. Diese Datei wird vom Befehl `update-server-info` geschrieben, den man als einen `post-receive`-Hook einrichten muss, damit das HTTP-Protokoll richtig funktionieren kann. +Der Befehl lädt zunächst die Datei `info/refs` herunter. Diese Datei wird vom Befehl `update-server-info` geschrieben, den man als einen `post-receive`-Hook einrichten muss, damit das HTTP-Protokoll richtig funktionieren kann. => GET info/refs ca82a6dff817ec66f44342007202690a93763949 refs/heads/master -Jetzt hat man eine Liste aller Referenzen und SHAs in diesem Repository. Als nächstes schaut man die HEAD-Referenz nach, um zu wissen, was ausgecheckt werden muss: +Jetzt hat man eine Liste aller Referenzen und SHA-Prüfsummen in diesem Repository. Als nächstes schaut man die HEAD-Referenz nach, um zu wissen, was ausgecheckt werden muss: => GET HEAD ref: refs/heads/master -D.h., wenn wir mit dem Prozess fertig sind, wir müssen den `master`-Branch auschecken. +D.h., wenn wir mit dem Prozess fertig sind, wir müssen den Branch `master` auschecken. -Wir können jetzt loslegen. Weil wir in der `info/refs` Datei der Commit `ca82a6` angegeben ist, fangen wir damit an, dieses Objekt herunterzuladen: +Wir können jetzt loslegen. Weil in der Datei `info/refs` der Commit `ca82a6` angegeben ist, fangen wir damit an, dieses Objekt herunterzuladen: => GET objects/ca/82a6dff817ec66f44342007202690a93763949 (179 bytes of binary data) @@ -897,7 +897,7 @@ Wir erhalten also ein Objekt zurück. Dieses Objekt ist im losen Format auf dem -Als Nächstes brauchen wir also zwei weitere Objekte: `cfda3b`, welches der Tree der Inhalte dieses Commits ist, und `085bb3`, den Commit-Parent: +Als Nächstes brauchen wir also zwei weitere Objekte: `cfda3b`, welches der Tree der Inhalte dieses Commits ist, und `085bb3`, welches der übergeordnete Commit ist: => GET objects/08/5bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 (179 bytes of data) @@ -911,7 +911,7 @@ Das gibt uns das nächste Commit-Objekt. Versuchen wir, das Tree-Objekt zu holen -Huch. Es sieht so aus, als ob der Tree nicht im losen Format auf dem Server gespeichert ist, weshalb wir einer 404-Antwort („Not found“) erhalten. Dafür kann es verschiedene Gründe geben. Das Objekt könnte in einem anderen, alternativen Repository liegen, oder es könnte sich in einem Packfile befinden. Git sucht deshalb zunächst nach alternativen Repositories: +Huch. Es sieht so aus, als ob der Tree nicht im losen Format auf dem Server gespeichert ist, weshalb wir eine 404-Antwort („Not found“) erhalten. Dafür kann es verschiedene Gründe geben. Das Objekt könnte in einem anderen, alternativen Repository liegen, oder es könnte sich in einem Packfile befinden. Git sucht deshalb zunächst nach alternativen Repositories: => GET objects/info/http-alternates (empty file) @@ -992,7 +992,7 @@ Nehmen wir z.B. an, Du führst `git push origin master` in Deinem Projekt aus un -Der `git-receive-pack`-Befehl antwortet dann mit jeweils einer Zeile pro Referenz, die er kennt – in diesem Fall sind das lediglich der `master`-Branch und dessen SHA. Die erste Zeile listet außerdem Features, die der Server beherrscht (in unserem Fall `report-status` und `delete-refs`). +Der `git-receive-pack`-Befehl antwortet dann mit jeweils einer Zeile pro Referenz, die er kennt – in diesem Fall sind das lediglich der Branch `master` und dessen SHA-Prüfsumme. Die erste Zeile listet außerdem Features, die der Server beherrscht (in unserem Fall `report-status` und `delete-refs`). @@ -1000,7 +1000,7 @@ Jede Zeile beginnt mit einem 4 Byte Hexadezimalzahl-Wert, der angibt, wie lang d -Nachdem Dein `send-pack`-Prozess jetzt den Zustand des Servers kennt, kann er als nächstes evaluieren, welche Commits lokal, aber nicht auf dem Server vorhanden sind. der `send-pack`-Prozess schickt diese Information für jede Referenz, auf die sich der `push`-Befehl bezieht, an den `receive-pack` Prozess. Wenn Du beispielsweise den `master`-Branch aktualisierst und einen `experiment`-Branch hinzufügst, dann könnte die Antwort auf `send-pack` so aussehen: +Nachdem Dein `send-pack`-Prozess jetzt den Zustand des Servers kennt, kann er als nächstes evaluieren, welche Commits lokal, aber nicht auf dem Server vorhanden sind. der `send-pack`-Prozess schickt diese Information für jede Referenz, auf die sich der `push`-Befehl bezieht, an den `receive-pack` Prozess. Wenn Du beispielsweise den Branch `master` aktualisierst und einen Branch `experiment` hinzufügst, dann könnte die Antwort auf `send-pack` so aussehen: 0085ca82a6dff817ec66f44342007202690a93763949 15027957951b64cf874c3557a0f3547bd83b3ff6 refs/heads/master report-status 00670000000000000000000000000000000000000000 cdfdb42577e2506715f8cfeacdbabc092bf63e8d refs/heads/experiment @@ -1025,7 +1025,7 @@ Wenn Du Daten herunterlädst, sind daran die Prozesse `fetch-pack` und `upload-p -Es gibt verschiedene Möglichkeiten, den `upload-pack`-Prozess auf dem Server zu starten: einerseits via SSH auf die gleiche Weise wie den `receive-pack`-Prozess. Und adnererseits über den Git-Daemon, der standardmäßig auf dem Server auf dem Port 9418 läuft. Der `fetch-pack`-Prozess schickt etwa Folgendes an den Daemon: +Es gibt verschiedene Möglichkeiten, den `upload-pack`-Prozess auf dem Server zu starten: einerseits via SSH auf die gleiche Weise wie den `receive-pack`-Prozess. Und andererseits über den Git-Daemon, der standardmäßig auf dem Server auf dem Port 9418 läuft. Der `fetch-pack`-Prozess schickt etwa Folgendes an den Daemon: 003fgit-upload-pack schacon/simplegit-progit.git\0host=myserver.com\0 @@ -1071,7 +1071,7 @@ Das ist ein sehr einfaches Beispiel. In komplexeren Fällen unterstützt der Cli -Gelegentlich will man ein bisschen aufräumen – ein Repository verdichten, ein importiertes Repository aufräumen oder verloren gegangene Daten wieder herstellen. Dieses Kapitel wird sich mit einigen derartigen Szenarien befassen. +Gelegentlich will man ein bisschen aufräumen – ein Repository komprimieren, ein importiertes Repository aufräumen oder verloren gegangene Daten wiederherstellen. Dieses Kapitel wird sich mit einigen derartigen Szenarien befassen. ### Wartung ### @@ -1102,7 +1102,7 @@ Wie schon erwähnt tut dies normalerweise gar nichts. Es müssen sich etwa 7.000 -Nachdem Du `git gc` ausgeführt hast, werden diese Dateien um der Effizienz willen aus dem `refs`-Verzeichnis entfernt und in eine Datei `.git/packed-refs` verschoben, die dann wie folgt aussieht: +Nachdem Du `git gc` ausgeführt hast, werden diese Dateien um der Effizienz willen aus dem Verzeichnis `refs` entfernt und in eine Datei `.git/packed-refs` verschoben, die dann wie folgt aussieht: $ cat .git/packed-refs # pack-refs with: peeled @@ -1114,7 +1114,7 @@ Nachdem Du `git gc` ausgeführt hast, werden diese Dateien um der Effizienz will -Wenn Du eine Referenz bearbeitest, lässt Git diese Datei unverändert und schreibt stattdessen eine neue Datei nach `refs/heads`. Um einen SHA für eine Referenz nachzuschlagen, schaut Git zunächst im `refs`-Verzeichnis und danach erst in der Datei `packed-refs` nach, falls nötig. Wenn eine Referenz also nicht im `refs`-Verzeichnis liegt, befindet sie sich wahrscheinlich in der Datei `packed-refs`. +Wenn Du eine Referenz bearbeitest, lässt Git diese Datei unverändert und schreibt stattdessen eine neue Datei nach `refs/heads`. Um eine SHA-Prüfsumme für eine Referenz nachzuschlagen, schaut Git zunächst im Verzeichnis `refs` und danach erst in der Datei `packed-refs` nach, falls nötig. Wenn eine Referenz also nicht im Verzeichnis `refs` liegt, befindet sie sich wahrscheinlich in der Datei `packed-refs`. @@ -1125,11 +1125,11 @@ Beachte, dass die letzte Zeile der Datei mit `^` anfängt. Das bedeutet, dass de -Irgendwann wird es vielleicht mal vorkommen, dass Du während der Arbeit mit Git einen Commit verlierst. Normalerweise passiert das, wenn Du versehentlich einen Branch löschst, an dem Du gearbeitet hattest und den Du noch brauchst. Oder Du führst `git reset --hard` aus und stellst fest, dass Du einige der Commits noch brauchst. Nehmen wir an, Du steckst in einer solchen Situation – wie kannst Du Deine Commits wiederherstellen? +Irgendwann wird es vielleicht mal vorkommen, dass Du während der Arbeit mit Git einen Commit verlierst. Normalerweise passiert das, wenn Du versehentlich einen Branch löschst, an dem Du gearbeitet hattest und den Du noch brauchst. Oder Du führst `git reset --hard` aus und stellst fest, dass Du einige der Commits noch brauchst. Nehmen wir an, Du steckst in einer solchen Situation – wie kannst Du Deine Commits dann wiederherstellen? -Das folgende Beispiel setzt zuerst den `master`-Branch auf einen älteren Commit zurück und stellt die verlorenen Commits dann wieder her. Zunächst schauen wir uns den gegenwärtigen Zustand des Repositories an: +Das folgende Beispiel setzt zuerst den Branch `master` auf einen älteren Commit zurück und stellt die verlorenen Commits dann wieder her. Zunächst schauen wir uns den gegenwärtigen Zustand des Repositorys an: $ git log --pretty=oneline ab1afef80fac8e34258ff41fc1b867c702daa24b modified repo a bit @@ -1140,7 +1140,7 @@ Das folgende Beispiel setzt zuerst den `master`-Branch auf einen älteren Commit -Jetzt setzen wir den `master`-Branch zurück auf den mittleren Commit. +Jetzt setzen wir den Branch `master` auf den mittleren Commit zurück: $ git reset --hard 1a410efbd13591db07496601ebc7a059dd55cfe9 HEAD is now at 1a410ef third commit @@ -1163,7 +1163,7 @@ In der Regel ist der schnellste Weg, solche Hashes zu finden, der Befehl `git re -Das zeigt also die beiden verloren gegangenen Commits an, die wir zuvor ausgecheckt hatten. Allerdings zeigt es auch nicht viel mehr Information. Um das Reflog in einer anderen, etwas nützlicheren Weise anzuzeigen, kannst Du `git log -g` verwenden. Das gibt das Reflog im gewohnten Log Format aus: +Das zeigt also die beiden verloren gegangenen Commits an, die wir zuvor ausgecheckt hatten. Allerdings zeigt es auch nicht viel mehr Information. Um das Reflog in einer anderen, etwas nützlicheren Weise anzuzeigen, kannst Du `git log -g` verwenden. Das gibt das Reflog im gewohnten Log-Format aus: $ git log -g commit 1a410efbd13591db07496601ebc7a059dd55cfe9 @@ -1197,7 +1197,7 @@ Es sieht also so aus, als sei der untere Commit derjenige, den Du verloren hast, -Sehr gut. Du hast jetzt einen neuen Branch `recover-branch`, der diejenigen Commits enthält, die sich zuvor in Deinem `master`-Branch befanden. Damit hast Du wieder Zugriff auf die beiden verloren gegangenen Commits. Als nächstes nehmen wir aber außerdem an, dass diese verlorenen Commits aus irgendeinem Grunde nicht im Reflog enthalten sind – Du kannst das z.B. simulieren, indem Du den Branch `recover-branch` und das Reflog löschst. Damit sind die beiden Commits jetzt von nirgendwo her mehr erreichbar: +Sehr gut. Du hast jetzt einen neuen Branch `recover-branch`, der diejenigen Commits enthält, die sich zuvor in Deinem Branch `master` befanden. Damit hast Du wieder Zugriff auf die beiden verloren gegangenen Commits. Als nächstes nehmen wir aber außerdem an, dass diese verlorenen Commits aus irgendeinem Grunde nicht im Reflog enthalten sind – Du kannst das z.B. simulieren, indem Du den Branch `recover-branch` und das Reflog löschst. Damit sind die beiden Commits jetzt von nirgendwo her mehr erreichbar: $ git branch -D recover-branch $ rm -Rf .git/logs/ @@ -1225,7 +1225,7 @@ Git ist in vielerlei Hinsicht unschlagbar, aber es gibt auch Features, die Probl -Hierin kann ein großes Problem bestehen, wenn Du Subversion oder Perforce-Repositorys nach Git konvertierst. Weil Du in diesen Systemen nicht die gesamte Historie herunterlädst, kann diese Art von Hinzufügung einige unangenehme Konsequenzen haben. Wenn Du Dein Repository aus einem anderen System importiert hast oder aus irgendeinem anderen Grunde findest, dass es sehr viel größer ist, als es eigentlich sein sollte, kannst Du große Objekte wie folgt suchen und entfernen. +Hierin kann ein großes Problem bestehen, wenn Du Subversion- oder Perforce-Repositorys nach Git konvertierst. Weil Du in diesen Systemen nicht die gesamte Historie herunterlädst, kann diese Art von Hinzufügung einige unangenehme Konsequenzen haben. Wenn Du Dein Repository aus einem anderen System importiert hast oder aus irgendeinem anderen Grunde findest, dass es sehr viel größer ist, als es eigentlich sein sollte, kannst Du große Objekte wie folgt suchen und entfernen. @@ -1233,7 +1233,7 @@ Sei Dir allerdings bewusst, dass diese Technik die Commit-Historie zerstört. Si -Um das zu demonstrieren, werden wir eine große Datei zu Deinem Test-Repository hinzufügen, sie dann im nächsten Commit löschen, in der Datenbank nachschlagen und sie schließlich dauerhaft aus dem Repository entfernen. Als erstes committe also eine große Datei in Dein Repository: +Um das zu demonstrieren, werden wir eine große Datei zu Deinem Test-Repository hinzufügen, sie dann im nächsten Commit löschen, in der Datenbank nachschlagen und sie schließlich dauerhaft aus dem Repository entfernen. Als erstes checke also eine große Datei in Dein Repository ein: $ curl http://kernel.org/pub/software/scm/git/git-1.6.3.1.tar.bz2 > git.tbz2 $ git add git.tbz2 @@ -1279,7 +1279,7 @@ Du kannst auch den Befehl `count-objects` laufen lassen, um einen schnellen Übe -Der `size-pack`-Eintrag zeigt die Größe der Packfiles in Kilobytes, d.h. Dein Repository braucht 2 MB. Vor dem letzten Commit lag dieser Wert eher bei 2 KB. D.h., die Datei wurde im letzten Commit eindeutig nicht aus der History entfernt. Jedes Mal, wenn jemand künftig dieses sehr kleine Repository clont, wird er die 2 MB mit herunterladen müssen – nur weil wir versehentlich diese große Datei hinzugefügt hatten. Also versuchen wir, sie endgültig loszuwerden. +Der `size-pack`-Eintrag zeigt die Größe der Packfiles in Kilobytes an, d.h. Dein Repository braucht 2 MB. Vor dem letzten Commit lag dieser Wert eher bei 2 KB. D.h., die Datei wurde im letzten Commit eindeutig nicht aus der History entfernt. Jedes Mal, wenn jemand künftig dieses sehr kleine Repository klont, wird er die 2 MB mit herunterladen müssen – nur weil wir versehentlich diese große Datei hinzugefügt hatten. Also versuchen wir, sie endgültig loszuwerden. @@ -1317,7 +1317,7 @@ Es geht also darum, alle Commits angefangen bei `6df76` neu zu schreiben, sodass -DieOption `--index-filter` ist ähnlich der Option `--tree-filter` aus Kapitel 6. Allerdings übergibt man in diesem Fall nicht einen Befehl, der die Dateien verändert, die sich jeweils ausgecheckt auf der Festplatte befinden. Stattdessen verändert man jeweils die Staging-Area bzw. den Index. Statt eine bestimmte Datei mit z.B: `rm file` zu entfernen, müssen wir also `git rm --cached` verwenden – denn wir wollen sie aus dem Index, nicht von der Festplatte löschen. Der Grund dafür ist einfach Geschwindigkeit: Git braucht nicht jede einzelne Revision auf die Festplatte auszuchecken, um den Filter anzuwenden. Auf diese Weise läuft der ganze Prozess sehr viel schneller. Man kann dieselbe Aufgabe aber auch mit `--tree-filter` erledigen, wenn man will. Die Option `--ignore-match` weist Git an, nicht mit einer Fehlermeldung abzubrechen, wenn die Datei, die wir löschen wollen, nicht vorhanden ist. Außerdem teilen wir `filter-branch` mit, die Historie nur von dem Commit `6df7640` an umzuschreiben. Andernfalls würde der Befehl von ganz vorn beginnen und unnötig länger brauchen. +Die Option `--index-filter` ist ähnlich der Option `--tree-filter` aus Kapitel 6. Allerdings übergibt man in diesem Fall nicht einen Befehl, der die Dateien verändert, die sich jeweils ausgecheckt auf der Festplatte befinden. Stattdessen verändert man jeweils die Staging-Area bzw. den Index. Statt eine bestimmte Datei mit z.B: `rm file` zu entfernen, müssen wir also `git rm --cached` verwenden – denn wir wollen sie aus dem Index, nicht von der Festplatte löschen. Der Grund dafür ist einfach Geschwindigkeit: Git braucht nicht jede einzelne Revision auf die Festplatte auszuchecken, um den Filter anzuwenden. Auf diese Weise läuft der ganze Prozess sehr viel schneller. Man kann dieselbe Aufgabe aber auch mit `--tree-filter` erledigen, wenn man will. Die Option `--ignore-match` weist Git an, nicht mit einer Fehlermeldung abzubrechen, wenn die Datei, die wir löschen wollen, nicht vorhanden ist. Außerdem teilen wir `filter-branch` mit, die Historie nur von dem Commit `6df7640` an umzuschreiben. Andernfalls würde der Befehl von ganz vorn beginnen und unnötig länger brauchen. @@ -1358,4 +1358,4 @@ Du solltest jetzt ein gutes Verständnis davon haben, was Git im Hintergrund tut -Git als ein Dateisystem, das Inhalte addressieren kann, ist ein äußerst mächtiges Werkzeug, das Du leicht für mehr als „nur“ als VCS einsetzen kannst. Ich hoffe, Du kannst Dein neugewonnenes Wissen der Git-Interna nutzen, um Deine eigene tolle Anwendung dieser Technologie zu implementieren und Dich wohler damit zu fühlen, Git auch in fortgeschrittener Weise zu benutzen. +Git als ein Dateisystem, das Inhalte addressieren kann, ist ein äußerst mächtiges Werkzeug, das Du leicht für mehr als „nur“ als VCS einsetzen kannst. Ich hoffe, Du kannst Dein neugewonnenes Wissen der Git Interna nutzen, um Deine eigene tolle Anwendung dieser Technologie zu implementieren und Dich wohler damit zu fühlen, Git auch in fortgeschrittener Weise zu benutzen. From cd58556a66d5edab4456447a8e00940c452d51a8 Mon Sep 17 00:00:00 2001 From: Cor Date: Thu, 16 Jan 2014 12:12:07 +0100 Subject: [PATCH 124/690] [nl] Language and wording corrections. Introducing characters from ASCII extended. --- nl/04-git-server/01-chapter4.markdown | 130 +++++++++++++------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/nl/04-git-server/01-chapter4.markdown b/nl/04-git-server/01-chapter4.markdown index 153825c95..a27d58789 100644 --- a/nl/04-git-server/01-chapter4.markdown +++ b/nl/04-git-server/01-chapter4.markdown @@ -1,22 +1,22 @@ # Git op de server # -Op dit punt zou je alledaagse taken waarvoor je Git zult gebruiken kunnen doen. Maar, om samen te kunnen werken in Git, zul je een remote repository moeten hebben. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden, omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers bij het repository kunnen, zelfs als jouw computer van het netwerk is — het hebben van een betrouwbaar gezamenlijk repository is vaak handig. Daarom heeft het hebben van een tussenliggend repository waarin je met iemand anders samenwerkt de voorkeur, en daar kun je dan naar pushen en pullen. We zullen dit repository de "Git server" noemen; maar je zult zien dat het over het algemeen maar een klein beetje systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. +Op dit punt zou je alledaagse taken waarvoor je Git zult gebruiken kunnen doen. Maar, om samen te kunnen werken in Git zul je een remote repository moeten hebben. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden, omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers de repository kunnen bereiken, zelfs als jouw computer van het netwerk is – het hebben van een betrouwbare gezamenlijke repository is vaak handig. Daarom heeft het hebben van een tussenliggende repository waarin je met iemand anders samenwerkt de voorkeur, en daaruit pushen en pullen. We zullen deze repository de `Git server` noemen, maar je zult zien dat het over het algemeen maar een klein beetje systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. -Een Git server draaien is eenvoudig. Als eerste kies je met welke protocollen je je server wilt laten communiceren. Het eerste gedeelte van dit hoofdstuk zullen we de beschikbare protocollen bespreken met de voor- en nadelen van elk. De volgende secties zullen veel voorkomende opstellingen bespreken, die van die protocollen gebruik maken en hoe je je server ermee kunt opzetten. Als laatste laten we een paar servers van derden zien, als je het niet erg vindt om je code op iemands server te zetten en niet het gedoe wilt hebben van het opzetten en onderhouden van je eigen server. +Een Git server draaien is eenvoudig. Als eerste kies je met welke protocollen je de server wilt laten communiceren. Het eerste gedeelte van dit hoofdstuk zullen we de beschikbare protocollen bespreken met de voor- en nadelen van elk. De volgende paragrafen zullen we veel voorkomende opstellingen bespreken, die van die protocollen gebruik maken en hoe je je server ermee kunt opzetten. Als laatste laten we een paar servers van derden zien, als je het niet erg vindt om je code op de server van een ander te zetten en niet het gedoe wilt hebben van het opzetten en onderhouden van je eigen server. -Als je geen interesse hebt om je eigen server te draaien, dan kun je de rest overslaan en direct naar het laatste gedeelte van het hoofdstuk gaan om wat mogelijkheden voor het instellen van online accounts te zien en dan door te gaan naar het volgende hoofdstuk, waar we alle zaken bespreken die komen kijken bij het werken met een gedistribueerde versie beheer omgeving. +Als je geen interesse hebt om je eigen server te draaien, dan kun je de direct naar de laatste paragraaf van dit hoofdstuk gaan om wat mogelijkheden van online accounts te zien en dan door te gaan naar het volgende hoofdstuk, waar we alle zaken bespreken die komen kijken bij het werken met een gedistribueerde versiebeheer omgeving. -Een remote repository is over het algemeen een _bare repository_ (kale repository) — een Git repository dat geen werkmap heeft. Omdat het repository alleen gebruikt wordt als een samenwerkingspunt, is er geen reden om een snapshot op de schijf te hebben; alleen de Git data. Een kale repository is eenvoudigweg de inhoud van de `.git` map in je project, en niets anders. +Een remote repository is over het algemeen een _bare repository_ (kale repository) – een Git repository dat geen werkmap heeft. Omdat de repository alleen gebruikt wordt als een samenwerkingspunt, is er geen reden om een snapshot op de schijf te hebben; alleen de Git data. Een kale repository is eenvoudigweg de inhoud van de `.git` map in je project, en niets meer. ## De protocollen ## -Git kan vier veel voorkomende netwerk protocollen gebruiken om data te transporteren: Lokaal, Beveiligde Shell (SSH), Git en HTTP. Hier laten we zien wat ze zijn, en in welke omstandigheden je ze wilt gebruiken (of juist niet). +Git kan vier veel voorkomende netwerk protocollen gebruiken om data te transporteren: Lokaal, Beveiligde Shell (SSH), Git en HTTP. Hier laten we zien wat deze zijn, en in welke omstandigheden je ze wilt gebruiken (of juist niet). -Het is belangrijk om te zien dat, met uitzondering van de HTTP protocollen, ze allemaal een werkende Git versie op de server geïnstalleerd moeten hebben. +Het is belangrijk om op te merken dat, met uitzondering van de HTTP protocollen, ze allemaal een werkende Git versie op de server geïnstalleerd moeten hebben. ### Lokaal protocol ### -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. +Het meest basale is het _lokale protocol_, waarbij het remote repository in een andere map op de schijf staat. Deze opzet wordt vaak gebruikt als iedereen in het team toegang heeft op een gedeeld bestandssyteem 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 op dezelfde computer staan, zodat de kans op een fataal verlies veel groter wordt. 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: @@ -26,29 +26,29 @@ Of je kunt dit doen: $ git clone file:///opt/git/project.git -Git werkt iets anders als je expliciet `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gebruikt om data te transporteren over een netwerk, wat over het algemeen een stuk minder efficiënte methode is om data te transporteren. De reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de extra referenties of objecten eruit gelaten — over het algemeen na een import van een ander versie beheer systeem of iets vergelijkbaars (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. +Git werkt iets anders als je explicite `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gesproken gebruikt om data te transporteren over een netwerk, wat over het algemeen een minder efficiënte methode is om data te transporteren. De reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de extra referenties of objecten eruit gelaten – over het algemeen na een import van een ander versiebeheer systeem of iets dergelijks (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. -Om een lokaal repository aan een bestaand Git project toe te voegen, kun je zoiets als dit uitvoeren: +Om een lokale repository aan een bestaand Git project toe te voegen, kun je zoiets als het volgende uitvoeren: $ git remote add local_proj /opt/git/project.git -Daarna kun je pushen en pullen van dat remote alsof je over een netwerk werkt. +Daarna kun je pushen en pullen van die remote alsof je over een netwerk werkt. #### De voordelen #### -De voordelen van bestands-gebaseerde repositories zijn dat ze eenvoudig zijn en ze maken gebruik van bestaande bestandspermissies en netwerk toegang. Als je al een gedeeld bestandssysteem hebt, waar je hele team al toegang tot heeft, dan is een repository opzetten heel gemakkelijk. Je stopt de kale repository ergens waar iedereen gedeelde toegang tot heeft, en stelt de lees- en schrijfrechten in zoals je dat bij iedere andere gedeelde map zou doen. In de volgende sectie "Git op een Server krijgen" bespreken we hoe je een kopie van een kale repository kunt exporteren voor dit doeleinde. +De voordelen van bestands-gebaseerde repositories zijn dat ze eenvoudig zijn en ze maken gebruik van bestaande bestandspermissies en netwerk toegang. Als je al een gedeeld bestandssysteem hebt, waar je hele team al toegang tot heeft, dan is een repository opzetten heel gemakkelijk. Je stopt de kale repository ergens waar iedereen gedeelde toegang tot heeft, en stelt de lees- en schrijfrechten in zoals je dat bij iedere andere gedeelde map zou doen. In de volgende paragraaf "Git op een Server Krijgen" bespreken we hoe je een kopie van een kale repository kunt exporteren voor dit doeleinde. -Dit is ook een fijne optie om snel werk van een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project aan het werk zijn, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan dat hij naar een remote server moet pushen, en jij er van moet pullen. +Dit is ook een prettige optie om snel werk van een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project werken, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan dat hij naar een remote server moet pushen, en jij er van moet pullen. #### De nadelen #### Een van de nadelen van deze methode is dat gedeelde toegang over het algemeen moeilijker op te zetten en te bereiken is vanaf meerdere locaties dan basaal netwerk toegang. Als je wilt pushen van je laptop als je thuis bent, dan moet je de remote schijf aankoppelen, wat moeilijk en langzaam kan zijn in vergelijking tot netwerk gebaseerde toegang. -Het is ook belangrijk om te melden dat het niet noodzakelijk de snelste optie is, als je een gedeeld koppelpunt of iets dergelijks gebruikt. Een lokale repository is alleen snel als je snelle toegang tot de data hebt. Een repository op NFS is vaak langzamer dan het repository via SSH op dezelfde server, wat Git toelaat om vanaf lokale schijven te werken op ieder systeem. +Het is ook belangrijk om te vermelden dat het niet altijd de snelste optie is, als je een gedeeld koppelpunt (mount) of iets dergelijks gebruikt. Een lokale repository is alleen snel als je snelle toegang tot de data hebt. Een repository op NFS is vaak langzamer dan een repository via SSH op dezelfde server omdat dit Git in staat stelt om op lokale schijven te werken vanaf ieder systeem. ### Het SSH protocol ### -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. +Waarschijnlijk het meest voorkomende protocol voor Git is SSH. Met als reden dat toegang met SSH tot servers in veel plaatsen al geconfigureerd is – en als dat niet het geval is, dan is het eenvoudig 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 ongeïnitieerden, dan heb je nog steeds SSH nodig voor je eigen schrijftoegang. SSH is ook een geauthenticieerd 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 klonen, kun je een ssh:// URL opgeven zoals: @@ -62,28 +62,28 @@ Je kunt ook de gebruiker niet opgeven, en Git neemt aan dat je de gebruiker bedo #### De voordelen #### -Er zijn vele voordelen om SSH te gebruiken. De eerste is dat je het eigenlijk wel moet gebruiken als je geverifieerde schrijftoegang op je repository via een netwerk wilt. Het tweede is dat het relatief eenvoudig in te stellen is — SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel besturingssystemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig — alle data transporten zijn versleuteld en geverifieerd. En als laatste is SSH efficiënt, zoals het Git en lokale protocol, waarbij de data zo compact mogelijk wordt gemaakt voordat het getransporteerd wordt. +Er zijn vele voordelen om SSH te gebruiken. De eerste is dat je het eigenlijk wel moet gebruiken als je geauthenticeerde schrijftoegang op je repository via een netwerk wilt. Het tweede is dat het relatief eenvoudig in te stellen is – SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig – alle data transporten zijn versleuteld en geauthenticeerd. En als laatste is SSH efficiënt, net zoals het Git en lokale protocol, de data wordt zo compact mogelijk gemaakt voordat het getransporteerd wordt. #### De nadelen #### -Het negatieve aspect van SSH is dat je er geen anonieme toegang over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken, zelfs als het alleen lezen is, zodat SSH toegang niet bevorderlijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, dan kan SSH misschien het enige protocol zijn waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. +Het negatieve aspect van SSH is dat je er geen anonieme toegang over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken, zelfs als het alleen lezen is, zodat SSH toegang niet bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, dan is SSH misschien het enige protocol waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. ### 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-daemon-export-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. +Het volgende is het Git protocol. Dit is een aparte daemon, die met Git meegeleverd wordt; het luistert op een toegewezen poort (9418), en verleent een vergelijkbare dienst als het SSH protocol, maar dan zonder enige authenticatie. Om een repository beschikbaar te stellen over het Git protocol, moet je het `git-export-daemon-ok` bestand aanmaken – de daemon zal een repository zonder dit bestand erin niet verspreiden – maar buiten dat is er geen beveiliging. Oftewel: de Git repository is er om gecloned te kunnen worden door iedereen, of het is er 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 authenticatie kan, als je de push toegang aan zet, 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 #### -Het Git protocol is het snelste dat beschikbaar is. Als je veel verkeer serveert voor een publiek project, of een zeer groot project dat geen authenticatie nodig heeft voor leestoegang, dan is het waarschijnlijk dat je een Git daemon wilt instellen om je project te serveren. Het maakt van hetzelfde data-transport mechanisme gebruik als het SSH protocol, maar dan zonder de extra belasting van versleuteling en verificatie. +Het Git protocol is het snelste dat beschikbaar is. Als je veel verkeer verwerkt voor een publiek project, of een zeer groot project dat geen gebruikersauthenticatie nodig heeft voor leestoegang, dan is het waarschijnlijk dat je een Git daemon wilt inrichten om je project te verspreiden. Het maakt van hetzelfde data-transport mechanisme gebruik als het SSH protocol, maar dan zonder de extra belasting van versleuteling en authenticatie. #### De nadelen #### -Het nadeel van het Git protocol is het gebrek van toegangscontrole. Het is over het algemeen onwenselijk dat het Git protocol de enige toegang tot je project is. Over het algemeen zul je het samen met SSH toegang gebruiken voor de paar ontwikkelaars die push (schrijf-)toegang hebben en de rest laat je `git://` voor alleen leestoegang gebruiken. -Het is waarschijnlijk ook het meest ingewikkelde protocol om in te stellen. Het moet een eigen daemon hebben, die speciaal ontworpen is — we zullen er een instellen in het “Gitosis” gedeelte van dit hoofdstuk — het gebruikt `xinetd` configuratie of iets dergelijks, wat niet altijd eenvoudig is. Het heeft ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat bedrijfsfirewalls altijd toestaan. Achter grote bedrijfsfirewalls, is deze obscure poort meestal geblokkeerd. +Het nadeel van het Git protocol is het gebrek aan authenticatie. Het is over het algemeen onwenselijk dat het Git protocol de enige toegang tot je project is. Meestal zul je het samen met SSH toegang gebruiken voor de paar ontwikkelaars die push (schrijf-)toegang hebben en de rest laat je `git://` voor alleen leestoegang gebruiken. +Het is waarschijnlijk ook het meest ingewikkelde protocol om in te stellen. Het moet een eigen daemon hebben, die speciaal voor die situatie ingericht is – we zullen er een instellen in het "Gitosis" gedeelte van dit hoofdstuk – het gebruikt `xinetd` configuratie of iets dergelijks, wat ook niet altijd eenvoudig is op te zetten. Het heeft ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat in bedrijfsfirewalls is opengezet. Bij firewalls van grote bedrijven, is deze obscure poort meestal geblokkeerd. ### 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 klonen. 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 waar je de repository op gezet hebt ook je repository clonen. 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 @@ -95,26 +95,26 @@ Dat is alles. De `post-update` hook, die standaard bij Git zit, voert het noodza $ git clone http://example.com/gitproject.git -In dit geval, gebruiken we het `/var/www/htdocs` pad wat gebruikelijk is voor Apache opstellingen, maar je kunt iedere statische webserver gebruiken — stop de kale repository in haar pad. De Git data wordt geserveerd als standaard statische bestanden (zie hoofdstuk 9 voor details over hoe het precies geserveerd wordt). +In dit specifieke geval gebruiken we het `/var/www/htdocs` pad wat gebruikelijk is voor Apache opstellingen, maar je kunt iedere statische webserver gebruiken – stop de kale repository in haar pad. De Git data wordt geserveerd als standaard statische bestanden (zie hoofdstuk 9 voor details over hoe het precies geserveerd wordt). -Het ook is mogelijk om Git over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en erom vraagt dat je complexe WebDAV vereisten instelt. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek beschrijven. Als je geïnteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Het fijne van Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken, zonder specifieke Git eigenschappen; dus je kunt deze functionaliteit gebruiken als je web-hosting provider WebDAV ondersteunt voor schrijf vernieuwingen aan je webpagina. +Het ook is mogelijk om Git over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en het vraagt dat je complexe WebDAV instellingen opzet. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek beschrijven. Als je geïnteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Een fijn ding aan Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken, zonder specifieke Git funtionaliteit; dus je kunt deze functionaliteit gebruiken als je web-hosting provider WebDAV ondersteunt voor het maken van wijzigingen aan je webpagina. #### De voordelen #### -Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren zorgt voor een eenvoudige manier om de wereld leestoegang te geven aan je Git repository. Het kost slechts een paar minuten om te doen. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te serveren, een normale Apache server kan gemiddeld duizenden bestanden serveren per seconde — is het moeilijk om zelfs een kleine server te overbelasten. +Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren zorgt voor een eenvoudige manier om de wereld leestoegang te geven tot je Git repository. Het kost slechts een paar minuten om te doen. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te verspreiden - een normale Apache server kan gemiddeld duizenden bestanden zenden per seconde - is het moeilijk om zelfs een kleine server te overbelasten. -Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat betekend dat je het transport kunt versleutelen; of je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat moeten gebruiken. Als je over het algemeen zo ver gaat, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan een betere oplossing in jouw specifieke geval om gesigneerde SSL certificaten of andere HTTP-gebaseerde verificatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. +Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat inhoudt dat je het transport kunt versleutelen; je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat laat gebruiken. Normaal gesproken als je je deze moeite wilt getroosten, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan een betere oplossing in jouw specifieke geval zijn om gesigneerde SSL certificaten of andere HTTP-gebaseerde authenticatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. -Een ander fijn ding is dat HTTP zo'n veel voorkomend protocol is dat bedrijfsfirewalls vaak zo ingesteld zijn dat ze verkeer via deze poort toelaten. +Een andere prettige bijkomstigheid is dat HTTP een dusdanig veel voorkomend protocol is dat bedrijfsfirewalls vaak zo ingesteld zijn dat ze verkeer via deze poort toestaan. #### 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 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. +Het nadeel van je repository verspreiden 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 veel hogere netwerk belasting en transport volume via HTTP dan met elk van de andere netwerk protocollen. Omdat het niet zo ingewikkeld 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 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: +Om een initiële Git server op te zetten, moet je een bestaande repository naar 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: $ git clone --bare my_project my_project.git Initialized empty Git repository in /opt/projects/my_project.git/ @@ -125,11 +125,11 @@ Dit is ongeveer gelijk aan $ cp -Rf my_project/.git my_project.git -Er zijn een paar kleine verschillen in het configuratie bestand; maar voor jouw doeleinde ligt dit dicht bij hetzelfde. Het neemt de Git repository zelf, zonder een werkmap, en maakt een map aan specifiek alleen voor dat ding. +Er zijn een paar kleine verschillen in het configuratie bestand, maar het komt op hetzelfde neer. Het neemt de Git repository zelf, zonder een werkmap, en maakt een map aan specifiek hiervoor. ### Het bare repository op een server zetten ### -Nu dat je een kale kopie van je repository hebt, is het enige dat je moet doen het op een server zetten en je protocollen instellen. Stel dat je een server ingesteld hebt, die `git.example.com` heet, waar je SSH toegang op hebt, en waar je al je Git repositories wilt opslaan onder de `/opt/git` map. Je kunt je nieuwe repository instellen door je kale repository ernaartoe te kopiëren: +Nu je een kale kopie van je repository hebt, is het enige dat je moet doen het op een server zetten en je protocollen instellen. Stel dat je een server ingesteld hebt, die `git.example.com` heet, waar je SSH toegang op hebt, en waar je al je Git repositories wilt opslaan onder de `/opt/git` map. Je kunt je nieuwe repository beschikbaar stellen door je kale repository ernaartoe te kopieeren: $ scp -r my_project.git user@git.example.com:/opt/git @@ -137,7 +137,7 @@ Op dit punt kunnen andere gebruikers, die SSH toegang hebben tot dezelfde server $ git clone user@git.example.com:/opt/git/my_project.git -Als een gebruiker in een server SSH-ed en schrijftoegang heeft tot de `/opt/git/my_project.git` map, dan hebben ze automatisch ook push toegang. Git zal automatisch correcte groep schrijfrechten aan een repository toevoegen als je het `git init` commando met de `--shared` optie uitvoert. +Als een gebruiker met SSH op een server inlogt en schrijftoegang heeft tot de `/opt/git/my_project.git` map, dan hebben ze automatisch ook push toegang. Git zal automatisch de correcte groep schrijfrechten aan een repository toekennen als je het `git init` commando met de `--shared` optie uitvoert. $ ssh user@git.example.com $ cd /opt/git/my_project.git @@ -145,9 +145,9 @@ Als een gebruiker in een server SSH-ed en schrijftoegang heeft tot de `/opt/git/ Je ziet hoe eenvoudig het is om een Git repository te nemen, een kale versie aan te maken, en het op een server plaatsen waar jij en je medewerkers SSH toegang tot hebben. Nu ben je klaar om aan hetzelfde project samen te werken. -Het is belangrijk om te zien dat dit letterlijk alles is wat je moet doen om een bruikbare Git server te draaien waarop meerdere mensen toegang hebben — voeg alleen een paar SSH accounts toe op een server, en stop een kale repository ergens waar al die gebruikers lees- en schrijftoegang tot hebben. Je bent er klaar voor — je hebt niets anders nodig. +Het is belangrijk om op te merken dat dit letterlijk alles is wat je moet doen om een bruikbare Git server te draaien waarop meerdere mensen toegang hebben – voeg alleen een paar SSH accounts toe op een server, en stop een kale repository ergens waar al die gebruikers lees- en schrijftoegang toe hebben. Je bent er klaar voor – je hebt niets anders nodig. -In de volgende secties zul je zien hoe je meer ingewikkelde opstellingen kunt maken. Deze bespreking zal het niet hoeven aanmaken van gebruikersaccounts voor elke gebruiker omvatten, publieke leestoegang tot repositories, grafische web interfaces, de Gitosis applicatie gebruiken en meer. Maar, hou in gedachten dat om samen te kunnen werken met mensen op een privéproject, alles wat je _nodig_ hebt een SSH server en een kale repository is. +In de volgende paragrafen zul je zien hoe je meer ingewikkelde opstellingen kunt maken. Deze bespreking zal het niet hoeven aanmaken van gebruikers accounts voor elke gebruiker, publieke leestoegang tot repositories, grafische web interfaces, de Gitosis applicatie gebruiken en meer omvatten. Maar, hou in gedachten dat om samen te kunnen werken met mensen op een privé project, alles wat je _nodig_ hebt is een SSH server en een kale repository. ### Kleine opstellingen ### @@ -155,20 +155,20 @@ Als je met een kleine groep bent of net begint met Git in je organisatie en slec #### SSH toegang #### -Als je reeds een server hebt waar al je ontwikkelaars SSH toegang op hebben, dan is het over het algemeen het gemakkelijkst om je eerste repository daar in te stellen, omdat je dan bijna niets hoeft te doen (zoals beschreven in de vorige sectie). Als je meer complexe toegangscontrole wilt op je repositories, dan kun je ze instellen met de normale bestandssysteem permissies van het besturingssysteem dat op je server draait. +Als je reeds een server hebt waar al je ontwikkelaars SSH toegang op hebben, dan is het over het algemeen het eenvoudigste om je eerste repository daar in te stellen, omdat je dan bijna niets hoeft te doen (zoals beschreven in de vorige paragraaf). Als je meer complexe toegangscontrole wilt op je repositories, dan kun je ze instellen met de normale bestandssysteem permissies van het operating systeem dat op je server draait. -Als je je repositories op een server wilt zetten, die geen accounts heeft voor iedereen in je team die je schrijftoegang wilt geven, dan moet je SSH toegang voor ze instellen. We gaan er vanuit dat je een server hebt waarmee je dit kunt doen, je reeds een SSH server geïnstalleerd hebt, en dat de manier is waarop je toegang hebt tot de server. +Als je je repositories op een server wilt zetten, die geen accounts heeft voor iedereen in je team die je schrijftoegang wilt geven, dan moet je SSH toegang voor ze instellen. We gaan er vanuit dat je een server hebt waarmee je dit kunt doen, dat je reeds een SSH server geïnstalleerd hebt, en dat de manier is waarop je toegang hebt tot de server. -Er zijn een paar manieren waarop je iedereen in je team toegang kunt geven. De eerste is voor iedereen accounts aanmaken, wat rechttoe rechtaan is maar omslachtig kan zijn. Je wilt misschien niet `adduser` uitvoeren en tijdelijke wachtwoorden voor iedere gebruiker instellen. +Er zijn een paar manieren waarop je iedereen in je team toegang kunt geven. De eerste is voor iedereen accounts aanmaken, wat rechttoe rechtaan is maar bewerkelijk kan zijn. Je wilt vermoedelijk niet `adduser` uitvoeren en tijdelijke wachtwoorden instellen voor iedere gebruiker. -Een tweede methode is een enkele 'git' gebruiker aanmaken op de machine, aan iedere gebruiker die schijftoegang moet hebben vragen of ze je een publieke SSH sleutel sturen, en die sleutel toevoegen aan het `~/.ssh/authorized_keys` bestand van je nieuwe 'git' gebruiker. Vanaf dat punt zal iedereen toegang hebben op die machine via de 'git' gebruiker. Dit tast de commit data op geen enkele manier aan — de SSH gebruiker waarmee je inlogd zal de commits die je opgeslagen hebt niet beïnvloeden. +Een tweede methode is een 'git' gebruiker aan te maken op de machine, aan iedere gebruiker die schijftoegang moet hebben vragen of ze je een publieke SSH sleutel sturen, en die sleutel toevoegen aan het `~/.ssh/authorized_keys` bestand van je nieuwe 'git' gebruiker. Vanaf dat moment zal iedereen toegang hebben op die machine via de 'git' gebruiker. Dit tast de commit data op geen enkele manier aan – de SSH gebruiker waarmee je inlogt zal de commits die je opgeslagen hebt niet beïnvloeden. -Een andere manier waarop je het kunt doen is je SSH server laten verifiëren vanaf een LDAP server of een andere gecentraliseerde authenticatie bron, die je misschien al ingesteld hebt. Zolang iedere gebruiker een shell toegang heeft op de machine, zou ieder SSH authenticatie mechanisme dat je kunt bedenken moeten werken. +Een andere manier waarop je het kunt doen is je SSH server laten authenticeren middels een LDAP server of een andere gecentraliseerde authenticatie bron, die je misschien al ingesteld hebt. Zolang iedere gebruiker shell toegang kan krijgen op de machine, zou ieder SSH authenticatie mechanisme dat je kunt bedenken moeten werken. ## Je publieke SSH sleutel genereren ## -Dat gezegd hebbende, zijn er vele Git servers die authenticeren met een publieke SSH sleutel. Om een publieke sleutel te hebben, zal iedere gebruiker in je systeem er een moeten genereren als ze er nog geen hebben. Dit proces is bij alle besturingssystemen vergelijkbaar. -Als eerste moet je controleren dat je er niet al een hebt. Standaard staan de SSH sleutels van de gebruikers in hun eigen `~/.ssh` map. Je kunt makkelijk nagaan of je al een sleutel hebt door naar die map te gaan en de inhoud te tonen: +Dat gezegd hebbende, zijn er vele Git servers die authenticeren met een publieke SSH sleutel. Om een publieke sleutel te hebben, zal iedere gebruiker in je systeem er een moeten genereren als ze er nog geen hebben. Dit proces is bij alle operating systemen vergelijkbaar. +Als eerste moet je controleren dat je er niet al een hebt. Standaard staan de SSH sleutels van de gebruikers in hun eigen `~/.ssh` map. Je kunt makkelijk nagaan of je al een sleutel hebt door naar die map te gaan en de inhoud te bekijken: $ cd ~/.ssh $ ls @@ -187,7 +187,7 @@ Je bent op zoek naar een aantal bestanden genaamd iets en iets.pub, waarbij het The key fingerprint is: 43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local -Eerst bevestigt het de locatie waar je de sleutel wilt opslaan (`.ssh/id_rsa`), en vervolgens vraagt het tweemaal om een wachtzin, die je leeg kunt laten als je geen wachtwoord wilt intypen op het moment dat je de sleutel gebruikt. +Eerst bevestigt het de lokatie waar je de sleutel wilt opslaan (`.ssh/id_rsa`), en vervolgens vraagt het tweemaal om een wachtwoord, die je leeg kunt laten als je geen wachtwoord wilt intypen op het moment dat je de sleutel gebruikt. Iedere gebruiker die dit doet, moet zijn sleutel sturen naar jou of degene die de Git server beheert (aangenomen dat je een SSH server gebruikt die publieke sleutels vereist). Het enige dat ze hoeven doen is de inhoud van het `.pub` bestand kopiëren en e-mailen. De publieke sleutel ziet er ongeveer zo uit: @@ -203,7 +203,7 @@ Voor een uitgebreide tutorial over het aanmaken van een SSH sleutel op meerdere ## De server instellen ## -Laten we het instellen van SSH toegang aan de server kant eens doorlopen. In dit voorbeeld zul je de `authorized_keys` methode gebruiken om je gebruikers te verifiëren. We gaan er ook vanuit dat je een standaard Linux distributie gebruikt zoals Ubuntu. Als eerste creëer je een 'git' gebruiker een een `.ssh` map voor die gebruiker. +Laten we het instellen van SSH toegang aan de server kant eens doorlopen. In dit voorbeeld zul je de `authorized_keys` methode gebruiken om je gebruikers te authenticeren. We gaan er ook vanuit dat je een standaard Linux distributie gebruikt zoals Ubuntu. Als eerste maak je een 'git' gebruiker aan en een `.ssh` map voor die gebruiker. $ sudo adduser git $ su git @@ -220,20 +220,20 @@ Daarna moet je een aantal publieke SSH sleutels van ontwikkelaars aan het `autho O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq dAv8JggJICUvax2T9va5 gsg-keypair -Je voegt ze slechts toe aan je `authorized_keys` bestand: +Je voegt ze eenvoudigweg toe aan je `authorized_keys` bestand: $ 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 -Nu kun je een leeg repository voor ze instellen door `git init` uit te voeren met de `--bare` optie, wat het repository initialiseert zonder een werkmap: +Nu kun je een lege repository voor ze instellen door `git init` uit te voeren met de `--bare` optie, wat de repository initialiseert zonder een werkmap: $ cd /opt/git $ mkdir project.git $ cd project.git $ git --bare init -Daarna kunnen John, Josie of Jessica de eerste versie van hun project in de repository pushen door het als een remote toe te voegen en naar een branch te pushen. Let op dat iemand met een shell op de machine zal moeten inloggen en een kale repository moet creëren, iedere keer als je een project wilt toevoegen. Laten we `gitserver` als hostnaam gebruiken voor de server waar je je 'git' gebruiker en repository hebt ingesteld. Als je het intern gaat draaien, en je de DNS instelt zodat `gitserver` naar die server wijst, dan kun je de commando's vrijwel ongewijzigd gebruiken: +Daarna kunnen John, Josie of Jessica de eerste versie van hun project in de repository pushen door het als een remote toe te voegen en naar een branch te pushen. Let op dat iemand met een shell op de machine zal moeten inloggen en een kale repository moet creëren, iedere keer als je een project wilt toevoegen. Laten we `gitserver` als hostnaam gebruiken voor de server waar je de 'git' gebruiker en repository hebt ingesteld. Als je het binnenshuis draait, en je de DNS instelt zodat `gitserver` naar die server wijst, dan kun je de commando's vrijwel ongewijzigd gebruiken: # op Johns computer $ cd myproject @@ -243,14 +243,14 @@ 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 klonen en wijzigingen even gemakkelijk terug pushen: +Vanaf dat moment kunnen de anderen het clonen en wijzigingen even gemakkelijk terug pushen: $ git clone git@gitserver:/opt/git/project.git $ vim README $ git commit -am 'fix for the README file' $ git push origin master -Met deze methode kun je snel een lees/schrijf Git server draaiend krijgen voor een handvol ontwikkelaars. +Met deze methode kun je snel een lees/schrijf Git server draaiend krijgen voor een handjevol ontwikkelaars. Als een extra voorzorgsmaatregel kun je de 'git' gebruiker makkelijk beperken tot het doen van alleen Git activiteiten, met een gelimiteerde shell applicatie genaamd `git-shell` die bij Git geleverd wordt. Als je dit als login shell voor je 'git' gebruiker instelt, dan kan de 'git' gebruiker geen normale shell toegang hebben op je server. Specificeer `git-shell` in plaats van bash of csh voor je gebruikers login shell om dit te gebruiken. Om dit te doen zul je waarschijnlijk het `/etc/passwd` bestand aan moeten passen: @@ -273,9 +273,9 @@ Nu kan de 'git' gebruiker de SSH connectie alleen gebruiken om Git repositories ## Publieke toegang ## -Wat als je anonieme leestoegang op je project wil? Misschien wil je geen intern privéproject serveren, maar een open source project. Of misschien heb je een serie geautomatiseerde bouwservers of continue integratie servers die vaak wijzigen, en wil je niet doorlopend SSH sleutels hoeven genereren — je wil gewoon eenvoudige leestoegang toevoegen. +Wat als je anonieme leestoegang op je project wil? Misschien wil je geen intern privé project beheren, maar een open source project. Of misschien heb je een aantal geautomatiseerde bouwservers of continue integratie servers die vaak wijzigen, en wil je niet doorlopend SSH sleutels hoeven genereren – je wil gewoon eenvoudige leestoegang toevoegen. -Waarschijnlijk is de eenvoudigste manier voor kleinschalige opstellingen om een statische webserver in te stellen, waarbij de document root naar de plaats van je Git repositories wijst, en dan die `post-update` haak aanzetten waar we het in de eerste sectie van dit hoofdstuk over gehad hebben. Laten we eens uitgaan van het vorige voorbeeld. Stel dat je je repositories in de `/opt/git` map hebt staan, en er draait een Apache server op je machine. Nogmaals, je kunt hiervoor iedere web server gebruiken: maar als voorbeeld zullen we wat basis Apache configuraties laten zien, die je een idee kunnen geven van wat je nodig hebt. +Waarschijnlijk is de eenvoudigste manier voor kleinschalige opstellingen om een statische webserver in te stellen, waarbij de document root naar de plaats van je Git repositories wijst, en dan de `post-update` haak aanzetten waar we het in de eerste paragraaf van dit hoofdstuk over gehad hebben. Laten we eens uitgaan van het voorgaande voorbeeld. Stel dat je je repositories in de `/opt/git` map hebt staan, en er draait een Apache server op je machine. Nogmaals, je kunt hiervoor iedere web server gebruiken: maar als voorbeeld zullen we wat basis Apache configuraties laten zien, die je een idee kunnen geven van wat je nodig hebt. Eerst moet je de haak aanzetten: @@ -293,7 +293,7 @@ Wat doet deze `post-update` haak? Het ziet er ongeveer zo uit: 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: +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 wildcard DNS ingesteld hebt om `*.gitserver` door te sturen naar waar je dit alles draait: ServerName git.gitserver @@ -304,7 +304,7 @@ Vervolgens moet je een VirtualHost toevoeging in je Apache configuratie aanmaken -Je zult ook de Unix gebruikers groep van de `/opt/git` mappen moeten instellen op `www-data` zodat je web server leestoegang heeft op de repositories, omdat de Apache instantie die het CGI script uitvoert (standaard) als die gebruiker draait: +Je zult ook de Unix gebruikers groep van de `/opt/git` mappen moeten instellen op `www-data` zodat je web server leestoegang hebt op de repositories, omdat de Apache instantie die het CGI script uitvoert (standaard) als die gebruiker draait: $ chgrp -R www-data /opt/git @@ -312,11 +312,11 @@ Als je Apache herstart, dan zou je je repositories onder die map moeten kunnen k $ git clone http://git.gitserver/project.git -Op deze manier kun je HTTP-gebaseerde toegang voor ieder van je projecten voor een groot aantal gebruikers in slechts een paar minuten instellen. Een andere eenvoudige optie om publieke ongeverifieerde toegang in te stellen is een Git daemon starten, alhoewel dat vereist dat je het proces als daemon uitvoert – we beschrijven deze optie in de volgende sectie als je een voorkeur hebt voor die route. +Op deze manier kun je HTTP-gebaseerde toegang voor elk van je projecten voor een groot aantal gebruikers in slechts een paar minuten instellen. Een andere eenvoudige optie om publieke ongeauthenticeerde toegang in te stellen is een Git daemon te starten, alhoewel dat vereist dat je het proces als daemon uitvoert – we beschrijven deze optie in de volgende paragraaf als je een voorkeur hebt voor deze variant. ## GitWeb ## -Nu dat je basis lees/schrijf en alleen-lezen toegang tot je project hebt, wil je misschien een eenvoudige web-gebaseerde visualiseerder instellen. Git levert een CGI script genaamd GitWeb mee, dat veelal voor hiervoor gebruikt wordt. Je kunt GitWeb in gebruik zien bij sites zoals `http://git.kernel.org` (zie Figuur 4-1). +Nu je basis lees/schrijf en alleen-lezen toegang tot je project hebt, wil je misschien een eenvoudige web-gebaseerde visualisatie instellen. Git levert een CGI script genaamd GitWeb mee, dat veelal voor hiervoor gebruikt wordt. Je kunt GitWeb in gebruik zien bij sites zoals `http://git.kernel.org` (zie Figuur 4-1). Insert 18333fig0401.png Figuur 4-1. De GitWeb web-gebaseerde gebruikers interface. @@ -327,11 +327,11 @@ Als je wil zien hoe GitWeb er op jouw project uitziet, dan heeft Git een command [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] -Dat start een HTTPD server op poort 1234 op en start automatisch een web browser op die met die pagina opent. Het is dus makkelijk voor jou. Als je klaar bent en de server wilt afsluiten, dan kun je hetzelfde commando uitvoeren met de `--stop` optie: +Dat start een HTTPD server op poort 1234 op en start automatisch een web browser op die met die pagina opent. Het is dus makkelijk voor je. Als je klaar bent en de server wilt afsluiten, dan kun je hetzelfde commando uitvoeren met de `--stop` optie: $ git instaweb --httpd=webrick --stop -Als je de web interface doorlopend op een server wilt draaien voor je team of voor een open source project dat je serveert, dan moet je het CGI script instellen zodat het door je normale web server geserveerd wordt. Sommige Linux distributies hebben een `gitweb` pakket dat je misschien kunt installeren via `apt` of `yum`, dus misschien wil je dat eerst proberen. We zullen zeer vlot door een handmatige GitWeb installatie heenlopen. Eerst moet je de Git broncode pakken, waar GitWeb bij zit, en het persoonlijke CGI script genereren: +Als je de web interface doorlopend op een server wilt draaien voor je team of voor een open source project dat je verspreid, dan moet je het CGI script instellen zodat het door je normale web server geserveerd wordt. Sommige Linux distributies hebben een `gitweb` pakket dat je misschien kunt installeren via `apt` of `yum`, dus misschien kan je dat eerst proberen. We zullen snel door een handmatige GitWeb installatie heenlopen. Eerst moet je de Git broncode pakken waar GitWeb bij zit, en het aangepaste CGI script genereren: $ git clone git://git.kernel.org/pub/scm/git/git.git $ cd git/ @@ -339,7 +339,7 @@ Als je de web interface doorlopend op een server wilt draaien voor je team of vo prefix=/usr gitweb/gitweb.cgi $ sudo cp -Rf gitweb /var/www/ -Let op dat je het commando moet vertellen waar het je Git repositories kan vinden met de `GITWEB_PROJECTROOT` variabele. Nu moet je zorgen dat de Apache server CGI gebruikt voor dat script, waarvoor je een VirtualHost kunt toevoegen: +Merk op dat je het commando moet vertellen waar het je Git repositories kan vinden met de `GITWEB_PROJECTROOT` variabele. Nu moet je zorgen dat de Apache server CGI gebruikt voor dat script, waarvoor je een VirtualHost kunt toevoegen: ServerName gitserver @@ -354,17 +354,18 @@ 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 klonen en te fetchen. +Nogmaals, GitWeb kan geserveerd worden met iedere web server die in staat is CGI te verwerken; 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. ## Gitosis ## -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. +De publieke sleutels van alle gebruikers in een `authorized_keys` bestand bewaren voor toegang werkt slechts korte tijd goed. Als je honderden gebruikers hebt, dan is het bewerkelijk om dat proces te volgen. 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 pusht, 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 verzameling scripts die je helpen het `authorized_keys` bestand te beheren alsmede eenvoudig 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 beheert de informatie in dat project; en als je het pushed, dan herconfigureert Gitosis de server op basis van dat project, wat best wel 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. +Gitosis installeren is niet de makkelijkste taak ooit, maar het is ook niet te moeilijk. Het is het makkelijkste om er een Linux server voor te gebruiken – deze voorbeelden gebruiken een standaard Ubuntu 8.10 server. +>>>>>>> [nl] Language and wording corrections. Introducing characters from ASCII -Gitosis vereist wat Python applicaties, dus moet je eerst het Python setuptools pakket installeren, wat Ubuntu meelevert als python-setuptools: +Gitosis vereist enkele Python applicaties, dus moet je eerst het Python setuptools pakket installeren, wat Ubuntu beschikbaar stelt als python-setuptools: $ apt-get install python-setuptools @@ -378,7 +379,7 @@ Daarmee worden een aantal uitvoerbare bestanden geïnstalleerd, die Gitosis zal $ ln -s /opt/git /home/git/repositories -Gitosis zal je sleutels voor je beheren, dus je moet het huidige bestand verwijderen, de sleutels later opnieuw toevoegen en Gitosis het `authorized_keys` bestand automatisch laten beheren. Voor nu verplaatsen we het `authorized_keys` bestand: +Gitosis zal je sleutels voor je beheren, dus je moet het huidige bestand verwijderen, om de sleutels later opnieuw toe te voegen en Gitosis het `authorized_keys` bestand automatisch laten beheren. Voor nu verplaatsen we het `authorized_keys` bestand: $ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak @@ -396,8 +397,7 @@ Nu wordt het tijd om Gitosis te initialiseren. Je doet dit door het `gitosis-ini Initialized empty Git repository in /opt/git/gitosis-admin.git/ Reinitialized existing Git repository in /opt/git/gitosis-admin.git/ -Dit staat de gebruiker met die sleutel toe de hoofd Git repository, die de Gitosis installatie beheert, aan te passen. Daarna zul je met de hand het execute -bit op het `post-update` script moeten instellen voor je nieuwe beheer repository. +Dit staat de gebruiker met die sleutel toe de hoofd Git repository, die de Gitosis installatie beheert, aan te passen. Daarna zul je met de hand het execute bit op het `post-update` script moeten instellen voor je nieuwe beheer repository. $ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update From 19f45e5e110736dc8c9304d1aaab8f93f28d9408 Mon Sep 17 00:00:00 2001 From: Cor Date: Fri, 17 Jan 2014 15:03:53 +0100 Subject: [PATCH 125/690] [nl] added diacritical characters. Added (start of) gitolite translation. --- nl/04-git-server/01-chapter4.markdown | 278 +++++++++++++------------- 1 file changed, 136 insertions(+), 142 deletions(-) diff --git a/nl/04-git-server/01-chapter4.markdown b/nl/04-git-server/01-chapter4.markdown index a27d58789..9b2901a18 100644 --- a/nl/04-git-server/01-chapter4.markdown +++ b/nl/04-git-server/01-chapter4.markdown @@ -1,24 +1,24 @@ # Git op de server # -Op dit punt zou je alledaagse taken waarvoor je Git zult gebruiken kunnen doen. Maar, om samen te kunnen werken in Git zul je een remote repository moeten hebben. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden, omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers de repository kunnen bereiken, zelfs als jouw computer van het netwerk is – het hebben van een betrouwbare gezamenlijke repository is vaak handig. Daarom heeft het hebben van een tussenliggende repository waarin je met iemand anders samenwerkt de voorkeur, en daaruit pushen en pullen. We zullen deze repository de `Git server` noemen, maar je zult zien dat het over het algemeen maar een klein beetje systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. +Op dit punt zou je alledaagse taken waarvoor je Git zult gebruiken kunnen doen. Maar, om samen te kunnen werken in Git zul je een remote repository moeten hebben. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden, omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers de repository kunnen bereiken, zelfs als jouw computer van het netwerk is – het hebben van een betrouwbare gezamenlijke repository is vaak handig. De voorkeursmethode om met iemand samen te werken is om een tussenliggende repository in te richten waar beide partijen toegang to hebben en om daar naartoe te pushen en vandaan te pullen. We zullen deze repository de `Git server` noemen, maar je zult zien dat het over het algemeen maar een klein beetje systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. -Een Git server draaien is eenvoudig. Als eerste kies je met welke protocollen je de server wilt laten communiceren. Het eerste gedeelte van dit hoofdstuk zullen we de beschikbare protocollen bespreken met de voor- en nadelen van elk. De volgende paragrafen zullen we veel voorkomende opstellingen bespreken, die van die protocollen gebruik maken en hoe je je server ermee kunt opzetten. Als laatste laten we een paar servers van derden zien, als je het niet erg vindt om je code op de server van een ander te zetten en niet het gedoe wilt hebben van het opzetten en onderhouden van je eigen server. +Een Git server draaien is eenvoudig. Als eerste kies je met welke protocollen je de server wilt laten communiceren. Het eerste gedeelte van dit hoofdstuk zullen we de beschikbare protocollen bespreken met de voor- en nadelen van elk. De daarop volgende paragrafen zullen we een aantal veel voorkomende opstellingen bespreken die van die protocollen gebruik maken en hoe je je server ermee kunt opzetten. Als laatste laten we een paar servers van derden zien, als je het niet erg vindt om je code op de server van een ander te zetten en niet het gedoe wilt hebben van het opzetten en onderhouden van je eigen server. -Als je geen interesse hebt om je eigen server te draaien, dan kun je de direct naar de laatste paragraaf van dit hoofdstuk gaan om wat mogelijkheden van online accounts te zien en dan door te gaan naar het volgende hoofdstuk, waar we alle zaken bespreken die komen kijken bij het werken met een gedistribueerde versiebeheer omgeving. +Als je niet van plan bent om je eigen server te draaien, dan kun je de direct naar de laatste paragraaf van dit hoofdstuk gaan om wat mogelijkheden van online accounts te zien en dan door gaan naar het volgende hoofdstuk, waar we diverse zaken bespreken die komen kijken bij het werken met een gedistribueerde versiebeheer omgeving. -Een remote repository is over het algemeen een _bare repository_ (kale repository) – een Git repository dat geen werkmap heeft. Omdat de repository alleen gebruikt wordt als een samenwerkingspunt, is er geen reden om een snapshot op de schijf te hebben; alleen de Git data. Een kale repository is eenvoudigweg de inhoud van de `.git` map in je project, en niets meer. +Een remote repository is over het algemeen een _bare repository_ (kale repository) – een Git repository dat geen werkmap heeft. Omdat de repository alleen gebruikt wordt als een samenwerkingspunt, is er geen reden om een snapshot op de schijf te hebben; het is alleen de Git data. Een kale repository is eenvoudigweg de inhoud van de `.git` map in je project, en niets meer. ## De protocollen ## -Git kan vier veel voorkomende netwerk protocollen gebruiken om data te transporteren: Lokaal, Beveiligde Shell (SSH), Git en HTTP. Hier laten we zien wat deze zijn, en in welke omstandigheden je ze wilt gebruiken (of juist niet). +Git kan vier veel voorkomende netwerk protocollen gebruiken om data te transporteren: Lokaal, Beveiligde Shell (Secure Shell, SSH), Git en HTTP. Hier bespreken we wat deze zijn, en in welke omstandigheden je ze zou willen gebruiken (of juist niet). Het is belangrijk om op te merken dat, met uitzondering van de HTTP protocollen, ze allemaal een werkende Git versie op de server geïnstalleerd moeten hebben. ### Lokaal protocol ### -Het meest basale is het _lokale protocol_, waarbij het remote repository in een andere map op de schijf staat. Deze opzet wordt vaak gebruikt als iedereen in het team toegang heeft op een gedeeld bestandssyteem 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 op dezelfde computer staan, zodat de kans op een fataal verlies veel groter wordt. +Het simpelste is het _Lokale protocol_, waarbij de remote repository in een andere directory op de schijf staat. Deze opzet wordt vaak gebruikt als iedereen in het team toegang heeft op een gedeeld bestandssyteem zoals een NFS mount, of in het weinig voorkomende geval dat iedereen op dezelfde computer werkt. Het laatste zou niet ideaal zijn, want dan zouden alle repositories op dezelfde computer staan, zodat een fataal verlies van gegevens veel groter wordt. -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: +Als je een gedeeld bestandssyteem hebt, dan kun je clonen, pushen en pullen van een op een lokaal bestand aanwezige 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 het volgende uitvoeren: $ git clone /opt/git/project.git @@ -26,29 +26,29 @@ Of je kunt dit doen: $ git clone file:///opt/git/project.git -Git werkt iets anders als je explicite `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gesproken gebruikt om data te transporteren over een netwerk, wat over het algemeen een minder efficiënte methode is om data te transporteren. De reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de extra referenties of objecten eruit gelaten – over het algemeen na een import van een ander versiebeheer systeem of iets dergelijks (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. +Git werkt iets anders als je explicite `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gesproken gebruikt om data te transporteren over een netwerk, wat over het algemeen een minder efficiënte methode is om gegevens over te dragen. De belangrijkste reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de vreemde refenties of objecten eruit gelaten – over het algemeen na een import uit een ander versiebeheer systeem of iets dergelijks (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. -Om een lokale repository aan een bestaand Git project toe te voegen, kun je zoiets als het volgende uitvoeren: +Om een lokale repository aan een bestaand Git project toe te voegen, kun je iets als het volgende uitvoeren: $ git remote add local_proj /opt/git/project.git -Daarna kun je pushen en pullen van die remote alsof je over een netwerk werkt. +Daarna kun je op gelijke wijze pushen naar, en pullen van die remote als je over een netwerk zou doen. #### De voordelen #### -De voordelen van bestands-gebaseerde repositories zijn dat ze eenvoudig zijn en ze maken gebruik van bestaande bestandspermissies en netwerk toegang. Als je al een gedeeld bestandssysteem hebt, waar je hele team al toegang tot heeft, dan is een repository opzetten heel gemakkelijk. Je stopt de kale repository ergens waar iedereen gedeelde toegang tot heeft, en stelt de lees- en schrijfrechten in zoals je dat bij iedere andere gedeelde map zou doen. In de volgende paragraaf "Git op een Server Krijgen" bespreken we hoe je een kopie van een kale repository kunt exporteren voor dit doeleinde. +De voordelen van bestands-gebaseerde repositories zijn dat ze eenvoudig zijn en ze maken gebruik van bestaande bestandspermissies en netwerk toegang. Als je al een gedeeld bestandssysteem hebt, waar het hele team al toegang toe heeft, dan is een repository opzetten heel gemakkelijk. Je stopt de kale repository ergens waar iedereen gedeelde toegang tot heeft, en stelt de lees- en schrijfrechten in zoals je dat bij iedere andere gedeelde directory zou doen. In de volgende paragraaf "Git op een Server Krijgen" bespreken we hoe je een kopie van een kale repository kunt exporteren voor dit doeleinde. -Dit is ook een prettige optie om snel werk van een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project werken, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan dat hij naar een remote server moet pushen, en jij er van moet pullen. +Dit is ook een prettige optie om snel werk uit een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project werken, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan dat hij naar een remote server moet pushen, en jij er van moet pullen. #### De nadelen #### -Een van de nadelen van deze methode is dat gedeelde toegang over het algemeen moeilijker op te zetten en te bereiken is vanaf meerdere locaties dan basaal netwerk toegang. Als je wilt pushen van je laptop als je thuis bent, dan moet je de remote schijf aankoppelen, wat moeilijk en langzaam kan zijn in vergelijking tot netwerk gebaseerde toegang. +Een van de nadelen van deze methode is dat gedeelde toegang over het algemeen moeilijker op te zetten en te bereiken is vanaf meerdere lokaties dan simpele netwerk toegang. Als je wilt pushen van je laptop als je thuis bent, dan moet je de remote schijf aankoppelen, wat moeilijk en langzaam kan zijn als je het vergelijkt met netwerk gebaseerde toegang. -Het is ook belangrijk om te vermelden dat het niet altijd de snelste optie is, als je een gedeeld koppelpunt (mount) of iets dergelijks gebruikt. Een lokale repository is alleen snel als je snelle toegang tot de data hebt. Een repository op NFS is vaak langzamer dan een repository via SSH op dezelfde server omdat dit Git in staat stelt om op lokale schijven te werken vanaf ieder systeem. +Het is ook belangrijk om te vermelden dat het niet altijd de snelste optie is, als je een gedeeld koppelpunt (mount) of iets dergelijks gebruikt. Een lokale repository is alleen snel als je snelle toegang tot de data hebt. Een repository op NFS is vaak langzamer dan een repository via SSH op dezelfde server omdat dit Git in staat stelt om op lokale schijven te werken op elk van de betrokken systemen. ### Het SSH protocol ### -Waarschijnlijk het meest voorkomende protocol voor Git is SSH. Met als reden dat toegang met SSH tot servers in veel plaatsen al geconfigureerd is – en als dat niet het geval is, dan is het eenvoudig 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 ongeïnitieerden, dan heb je nog steeds SSH nodig voor je eigen schrijftoegang. SSH is ook een geauthenticieerd protocol; en omdat het overal voorkomt, is het over het algemeen eenvoudig om in te stellen en te gebruiken. +Waarschijnlijk het meest voorkomende protocol voor Git is SSH. De reden hiervoor is dat toegang met SSH tot servers in veel plaatsen al geconfigureerd is – en als dat niet het geval is, dan is het eenvoudig 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 ongeïnitieerde massas, dan heb je nog steeds SSH nodig voor je eigen schrijfcommandos. SSH is ook een geauthenticieerd protocol; en omdat het alom aanwezig is, is het over het algemeen eenvoudig om in te stellen en te gebruiken. Om een Git repository via SSH te klonen, kun je een ssh:// URL opgeven zoals: @@ -58,19 +58,19 @@ Of je geeft geen protocol op — Git gaat uit van SSH als je niet expliciet bent $ git clone user@server:project.git -Je kunt ook de gebruiker niet opgeven, en Git neemt aan dat je de gebruiker bedoelt waarmee je op het moment bent ingelogd. +Je kunt ook de gebruiker weglaten, en Git gebruikt gegevens van de gebruiker waarmee je op dat moment bent ingelogd. #### De voordelen #### -Er zijn vele voordelen om SSH te gebruiken. De eerste is dat je het eigenlijk wel moet gebruiken als je geauthenticeerde schrijftoegang op je repository via een netwerk wilt. Het tweede is dat het relatief eenvoudig in te stellen is – SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig – alle data transporten zijn versleuteld en geauthenticeerd. En als laatste is SSH efficiënt, net zoals het Git en lokale protocol, de data wordt zo compact mogelijk gemaakt voordat het getransporteerd wordt. +Er zijn vele voordelen om SSH te gebruiken. Ten eerste moet je het eigenlijk wel gebruiken als je geauthenticeerde schrijftoegang op je repository via een netwerk wilt. Ten tweede is het relatief eenvoudig in te stellen – SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig – alle data transporten zijn versleuteld en geauthenticeerd. En als laatste is SSH efficiënt, net zoals het Git en lokale protocol, de gegevens worden zo compact mogelijk gemaakt voordat het getransporteerd wordt. #### De nadelen #### -Het negatieve aspect van SSH is dat je er geen anonieme toegang over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken, zelfs als het alleen lezen is, zodat SSH toegang niet bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, dan is SSH misschien het enige protocol waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. +Het negatieve aspect van SSH is dat je er geen anonieme toegang naar je repository over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken, zelfs als het alleen lezen is, zodat SSH toegang niet bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, dan is SSH misschien het enige protocol waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. ### Het Git protocol ### -Het volgende is het Git protocol. Dit is een aparte daemon, die met Git meegeleverd wordt; het luistert op een toegewezen poort (9418), en verleent een vergelijkbare dienst als het SSH protocol, maar dan zonder enige authenticatie. Om een repository beschikbaar te stellen over het Git protocol, moet je het `git-export-daemon-ok` bestand aanmaken – de daemon zal een repository zonder dit bestand erin niet verspreiden – maar buiten dat is er geen beveiliging. Oftewel: de Git repository is er om gecloned te kunnen worden door iedereen, of het is er 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 authenticatie kan, als je de push toegang aan zet, 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 specifieke daemon, die met Git meegeleverd wordt; het luistert op een toegewezen poort (9418), en verleent een vergelijkbare dienst als het SSH protocol, maar dan zonder enige vorm van authenticatie. Om een repository beschikbaar te stellen over het Git protocol, moet je een `git-export-daemon-ok` bestand aanmaken – de daemon zal een repository zonder dit bestand erin niet verspreiden – maar daarbuiten is er geen beveiliging. De Git repository beschikbaar om gecloned te kunnen worden door iedereen, of het is het niet. Dit betekent dat er over het algemeen geen pushing is via dit protocol. Je kunt push toegang aanzetten, maar gegeven het gebrek aan authenticatie kan als je de push toegang aan zet iedereen die de URL van jouw project op het internet vindt, pushen naar jouw project. We volstaan met te zeggen dat dit zelden de bedoeling kan zijn. #### De voordelen #### @@ -79,7 +79,7 @@ Het Git protocol is het snelste dat beschikbaar is. Als je veel verkeer verwerkt #### De nadelen #### Het nadeel van het Git protocol is het gebrek aan authenticatie. Het is over het algemeen onwenselijk dat het Git protocol de enige toegang tot je project is. Meestal zul je het samen met SSH toegang gebruiken voor de paar ontwikkelaars die push (schrijf-)toegang hebben en de rest laat je `git://` voor alleen leestoegang gebruiken. -Het is waarschijnlijk ook het meest ingewikkelde protocol om in te stellen. Het moet een eigen daemon hebben, die speciaal voor die situatie ingericht is – we zullen er een instellen in het "Gitosis" gedeelte van dit hoofdstuk – het gebruikt `xinetd` configuratie of iets dergelijks, wat ook niet altijd eenvoudig is op te zetten. Het heeft ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat in bedrijfsfirewalls is opengezet. Bij firewalls van grote bedrijven, is deze obscure poort meestal geblokkeerd. +Het is waarschijnlijk ook het meest ingewikkelde protocol om in te richten. Het moet een eigen daemon hebben, die speciaal voor die situatie ingericht is – we zullen er een instellen in het "Gitosis" gedeelte van dit hoofdstuk – het gebruikt `xinetd` configuratie of iets vergelijkbaars, wat ook niet altijd eenvoudig is op te zetten. Daarbij is ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat in bedrijfsfirewalls is opengezet. Bij firewalls van grote bedrijven, is deze ongebruikelijke poort meestal dichtgezet. ### Het HTTP/S protocol ### @@ -91,30 +91,30 @@ 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 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 +Dat is alles. De `post-update` hook, die standaard bij Git geleverd wordt, voert het noodzakelijke commando uit (`git update-server-info`) om HTTP fetching en cloning goed werkend te krijgen en houden. Dit commando wordt uitgevoerd als je via SSH naar deze repository pushed; en andere mensen kunnen clonen met behulp van zoiets als $ git clone http://example.com/gitproject.git -In dit specifieke geval gebruiken we het `/var/www/htdocs` pad wat gebruikelijk is voor Apache opstellingen, maar je kunt iedere statische webserver gebruiken – stop de kale repository in haar pad. De Git data wordt geserveerd als standaard statische bestanden (zie hoofdstuk 9 voor details over hoe het precies geserveerd wordt). +In dit specifieke voorbeeld gebruiken we het `/var/www/htdocs` pad wat gebruikelijk is voor Apache opstellingen, maar je kunt iedere statische webserver gebruiken – stop de kale repository in het betreffende pad. De Git data wordt geserveerd als standaard statische bestanden (zie hoofdstuk 9 voor details over hoe het precies geserveerd wordt). -Het ook is mogelijk om Git over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en het vraagt dat je complexe WebDAV instellingen opzet. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek beschrijven. Als je geïnteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Een fijn ding aan Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken, zonder specifieke Git funtionaliteit; dus je kunt deze functionaliteit gebruiken als je web-hosting provider WebDAV ondersteunt voor het maken van wijzigingen aan je webpagina. +Het is mogelijk om Git ook over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en het vraagt dat je complexe WebDAV instellingen inricht. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek beschrijven. Als je geïnteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Het aardige van Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken, zonder specifieke Git funtionaliteit, dus je kunt deze functionaliteit gebruiken als je web-hosting provider WebDAV ondersteunt voor het maken van wijzigingen aan je webpagina. #### De voordelen #### -Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren zorgt voor een eenvoudige manier om de wereld leestoegang te geven tot je Git repository. Het kost slechts een paar minuten om te doen. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te verspreiden - een normale Apache server kan gemiddeld duizenden bestanden zenden per seconde - is het moeilijk om zelfs een kleine server te overbelasten. +Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren is alles wat er moet gebeuren om de wereld leestoegang te geven tot je Git repository. Het neemt maar een paar minuten van je tijd. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te verspreiden - een normale Apache server kan gemiddeld duizenden bestanden zenden per seconde - is het moeilijk om zelfs een kleine server te overbelasten. -Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat inhoudt dat je het transport kunt versleutelen; je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat laat gebruiken. Normaal gesproken als je je deze moeite wilt getroosten, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan een betere oplossing in jouw specifieke geval zijn om gesigneerde SSL certificaten of andere HTTP-gebaseerde authenticatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. +Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat inhoudt dat je het transport kunt versleutelen; je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat laat gebruiken. Normaal gesproken als je je deze moeite wilt getroosten, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan in jouw specifieke geval een betere oplossing zijn om gesigneerde SSL certificaten of andere HTTP-gebaseerde authenticatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. Een andere prettige bijkomstigheid is dat HTTP een dusdanig veel voorkomend protocol is dat bedrijfsfirewalls vaak zo ingesteld zijn dat ze verkeer via deze poort toestaan. #### De nadelen #### -Het nadeel van je repository verspreiden 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 veel hogere netwerk belasting en transport volume via HTTP dan met elk van de andere netwerk protocollen. Omdat het niet zo ingewikkeld 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 verspreiden 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 veel hogere netwerk belasting en transport volume via HTTP dan met elk van de andere netwerk protocollen. Omdat het niet zo ingewikkeld is om alleen de data te versturen die je nodig hebt – er wordt geen dynamisch werk door de server gedaan in deze uitwisselingen – 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 naar 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 een Git server initieel op te zetten, moet je een bestaande repository naar 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 conventie eindigen de namen van kale repository mappen met `.git`, zoals: $ git clone --bare my_project my_project.git Initialized empty Git repository in /opt/projects/my_project.git/ @@ -127,13 +127,13 @@ Dit is ongeveer gelijk aan Er zijn een paar kleine verschillen in het configuratie bestand, maar het komt op hetzelfde neer. Het neemt de Git repository zelf, zonder een werkmap, en maakt een map aan specifiek hiervoor. -### Het bare repository op een server zetten ### +### De Kale Repository op een Server Zetten ### -Nu je een kale kopie van je repository hebt, is het enige dat je moet doen het op een server zetten en je protocollen instellen. Stel dat je een server ingesteld hebt, die `git.example.com` heet, waar je SSH toegang op hebt, en waar je al je Git repositories wilt opslaan onder de `/opt/git` map. Je kunt je nieuwe repository beschikbaar stellen door je kale repository ernaartoe te kopieeren: +Nu je een kale kopie van je repository hebt, is het enige dat je moet doen het op een server zetten en je protocollen instellen. Laten we aannemen dat je een server ingericht hebt, die `git.example.com` heet, waar je SSH toegang op hebt, en waar je al je Git repositories wilt opslaan onder de `/opt/git` map. Je kunt je nieuwe repository beschikbaar stellen door je kale repository ernaartoe te kopiëren: $ 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 klonen door dit uit te voeren: +Vanaf dat moment 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: $ git clone user@git.example.com:/opt/git/my_project.git @@ -143,11 +143,11 @@ Als een gebruiker met SSH op een server inlogt en schrijftoegang heeft tot de `/ $ cd /opt/git/my_project.git $ git init --bare --shared -Je ziet hoe eenvoudig het is om een Git repository te nemen, een kale versie aan te maken, en het op een server plaatsen waar jij en je medewerkers SSH toegang tot hebben. Nu ben je klaar om aan hetzelfde project samen te werken. +Je ziet hoe eenvoudig het is om een Git repository te nemen, een kale versie aan te maken, en het op een server plaatsen waar jij en je medewerkers SSH toegang tot hebben. Nu zijn jullie klaar om aan hetzelfde project samen te werken. -Het is belangrijk om op te merken dat dit letterlijk alles is wat je moet doen om een bruikbare Git server te draaien waarop meerdere mensen toegang hebben – voeg alleen een paar SSH accounts toe op een server, en stop een kale repository ergens waar al die gebruikers lees- en schrijftoegang toe hebben. Je bent er klaar voor – je hebt niets anders nodig. +Het is belangrijk om op te merken dat dit letterlijk alles is wat je moet doen om een bruikbare Git server te draaien waarop meerdere mensen toegang hebben – maak alleen een paar accounts met SSH toegang aan op een server, en stop een kale repository ergens waar al die gebruikers lees- en schrijftoegang toe hebben. Je bent er klaar voor – je hebt niets anders nodig. -In de volgende paragrafen zul je zien hoe je meer ingewikkelde opstellingen kunt maken. Deze bespreking zal het niet hoeven aanmaken van gebruikers accounts voor elke gebruiker, publieke leestoegang tot repositories, grafische web interfaces, de Gitosis applicatie gebruiken en meer omvatten. Maar, hou in gedachten dat om samen te kunnen werken met mensen op een privé project, alles wat je _nodig_ hebt is een SSH server en een kale repository. +In de volgende paragrafen zul je zien hoe je meer ingewikkelde opstellingen kunt maken. Deze bespreking zal het niet hoeven aanmaken van gebruikers accounts voor elke gebruiker, publieke leestoegang tot repositories, grafische web interfaces, het gebruik van de Gitosis applicatie en meer omvatten. Maar, hou in gedachten dat om samen te kunnen werken met mensen op een privé project, alles wat je _nodig_ hebt een SSH server is en een kale repository. ### Kleine opstellingen ### @@ -155,27 +155,26 @@ Als je met een kleine groep bent of net begint met Git in je organisatie en slec #### SSH toegang #### -Als je reeds een server hebt waar al je ontwikkelaars SSH toegang op hebben, dan is het over het algemeen het eenvoudigste om je eerste repository daar in te stellen, omdat je dan bijna niets hoeft te doen (zoals beschreven in de vorige paragraaf). Als je meer complexe toegangscontrole wilt op je repositories, dan kun je ze instellen met de normale bestandssysteem permissies van het operating systeem dat op je server draait. +Als je al een server hebt waar al je ontwikkelaars SSH toegang op hebben, dan is het over het algemeen het eenvoudigste om je eerste repository daar op te zetten, omdat je dan bijna niets hoeft te doen (zoals beschreven in de vorige paragraaf). Als je meer complexe toegangscontrole wilt op je repositories, dan kun je ze instellen met de normale bestandssysteem permissies van het operating systeem dat op je server draait. -Als je je repositories op een server wilt zetten, die geen accounts heeft voor iedereen in je team die je schrijftoegang wilt geven, dan moet je SSH toegang voor ze instellen. We gaan er vanuit dat je een server hebt waarmee je dit kunt doen, dat je reeds een SSH server geïnstalleerd hebt, en dat de manier is waarop je toegang hebt tot de server. +Als je je repositories op een server wilt zetten, die geen accounts heeft voor iedereen in je team die je schrijftoegang wilt geven, dan moet je SSH toegang voor ze opzetten. We gaan er vanuit dat je een server hebt waarmee je dit kunt doen, dat je reeds een SSH server geïnstalleerd hebt, en dat de manier is waarop je toegang hebt tot de server. Er zijn een paar manieren waarop je iedereen in je team toegang kunt geven. De eerste is voor iedereen accounts aanmaken, wat rechttoe rechtaan is maar bewerkelijk kan zijn. Je wilt vermoedelijk niet `adduser` uitvoeren en tijdelijke wachtwoorden instellen voor iedere gebruiker. -Een tweede methode is een 'git' gebruiker aan te maken op de machine, aan iedere gebruiker die schijftoegang moet hebben vragen of ze je een publieke SSH sleutel sturen, en die sleutel toevoegen aan het `~/.ssh/authorized_keys` bestand van je nieuwe 'git' gebruiker. Vanaf dat moment zal iedereen toegang hebben op die machine via de 'git' gebruiker. Dit tast de commit data op geen enkele manier aan – de SSH gebruiker waarmee je inlogt zal de commits die je opgeslagen hebt niet beïnvloeden. +Een tweede methode is een generieke 'git' gebruiker aan te maken op de machine, aan iedere gebruiker die schijftoegang moet hebben vragen of ze je een publieke SSH sleutel sturen, en die sleutel toevoegen aan het `~/.ssh/authorized_keys` bestand van die nieuwe 'git' gebruiker. Vanaf dat moment zal iedereen toegang hebben op die machine via de 'git' gebruiker. Dit tast de commit data op geen enkele manier aan – de SSH gebruiker waarmee je inlogt zal de commits die je opgeslagen hebt niet beïnvloeden. -Een andere manier waarop je het kunt doen is je SSH server laten authenticeren middels een LDAP server of een andere gecentraliseerde authenticatie bron, die je misschien al ingesteld hebt. Zolang iedere gebruiker shell toegang kan krijgen op de machine, zou ieder SSH authenticatie mechanisme dat je kunt bedenken moeten werken. +Een andere manier waarop je het kunt doen is je SSH server laten authenticeren middels een LDAP server of een andere gecentraliseerde authenticatie bron, die misschien al ingericht is. Zolang iedere gebruiker shell toegang kan krijgen op de machine, zou ieder SSH authenticatie mechanisme dat je kunt bedenken moeten werken. ## Je publieke SSH sleutel genereren ## -Dat gezegd hebbende, zijn er vele Git servers die authenticeren met een publieke SSH sleutel. Om een publieke sleutel te hebben, zal iedere gebruiker in je systeem er een moeten genereren als ze er nog geen hebben. Dit proces is bij alle operating systemen vergelijkbaar. -Als eerste moet je controleren dat je er niet al een hebt. Standaard staan de SSH sleutels van de gebruikers in hun eigen `~/.ssh` map. Je kunt makkelijk nagaan of je al een sleutel hebt door naar die map te gaan en de inhoud te bekijken: +Dat gezegd hebbende, zijn er vele Git servers die authenticeren met een publieke SSH sleutel. Om een publieke sleutel te hebben, zal iedere gebruiker in je systeem er een moeten genereren als ze er nog geen hebben. Dit proces is bij alle operating systemen vergelijkbaar. Als eerste moet je controleren of je er niet al een hebt. Standaard staan de SSH sleutels van de gebruikers in hun eigen `~/.ssh` map. Je kunt makkelijk nagaan of je al een sleutel hebt door naar die map te gaan en de inhoud te bekijken: $ cd ~/.ssh $ ls authorized_keys2 id_dsa known_hosts config id_dsa.pub -Je bent op zoek naar een aantal bestanden genaamd iets en iets.pub, waarbij het `iets` meestal zoiets is als `id_dsa` of `id_rsa`. Het `.pub` bestand is je publieke sleutel en het andere bestand is je private sleutel. Als je deze bestanden niet hebt (of als je zelfs geen `.ssh` map hebt), dan kun je ze aanmaken door een applicatie genaamd `ssh-keygen` uit te voeren, wat meegeleverd wordt met het SSH pakket op Linux/Mac systemen en meegeleverd wordt met het MSysGit pakket op Windows: +Je bent op zoek naar een aantal bestanden genaamd iets en iets.pub, waarbij het `iets` meestal zoiets is als `id_dsa` of `id_rsa`. Het `.pub` bestand is je publieke sleutel en het andere bestand is je private sleutel. Als je deze bestanden niet hebt (of als je zelfs geen `.ssh` map hebt), dan kun je ze aanmaken door een applicatie genaamd `ssh-keygen` uit te voeren, deze wordt met het SSH pakket op Linux/Mac systemen meegeleverd en met het MSysGit pakket op Windows: $ ssh-keygen Generating public/private rsa key pair. @@ -187,7 +186,7 @@ Je bent op zoek naar een aantal bestanden genaamd iets en iets.pub, waarbij het The key fingerprint is: 43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local -Eerst bevestigt het de lokatie waar je de sleutel wilt opslaan (`.ssh/id_rsa`), en vervolgens vraagt het tweemaal om een wachtwoord, die je leeg kunt laten als je geen wachtwoord wilt intypen op het moment dat je de sleutel gebruikt. +Eerst wordt de lokatie waar je de sleutel wordt opgeslagen (`.ssh/id_rsa`) aangegeven, en vervolgens vraagt het tweemaal om een wachtwoord, die je leeg kunt laten als je geen wachtwoord wilt intypen op het moment dat je de sleutel gebruikt. Iedere gebruiker die dit doet, moet zijn sleutel sturen naar jou of degene die de Git server beheert (aangenomen dat je een SSH server gebruikt die publieke sleutels vereist). Het enige dat ze hoeven doen is de inhoud van het `.pub` bestand kopiëren en e-mailen. De publieke sleutel ziet er ongeveer zo uit: @@ -199,18 +198,18 @@ Iedere gebruiker die dit doet, moet zijn sleutel sturen naar jou of degene die d mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx NrRFi9wrf+M7Q== schacon@agadorlaptop.local -Voor een uitgebreide tutorial over het aanmaken van een SSH sleutel op meerdere besturingssystemen, zie de GitHub handleiding over SSH sleutels op `http://github.com/guides/providing-your-ssh-key`. +Voor een uitgebreide tutorial over het aanmaken van een SSH sleutel op meerdere operating systemen, verwijzen ze je naar de GitHub handleiding over SSH sleutels op `http://github.com/guides/providing-your-ssh-key`. -## De server instellen ## +## De Server Opzetten ## -Laten we het instellen van SSH toegang aan de server kant eens doorlopen. In dit voorbeeld zul je de `authorized_keys` methode gebruiken om je gebruikers te authenticeren. We gaan er ook vanuit dat je een standaard Linux distributie gebruikt zoals Ubuntu. Als eerste maak je een 'git' gebruiker aan en een `.ssh` map voor die gebruiker. +Laten we het opzetten van SSH toegang aan de server kant eens doorlopen. In dit voorbeeld zul je de `authorized_keys` methode gebruiken om je gebruikers te authenticeren. We gaan er ook vanuit dat je een standaard Linux distributie gebruikt zoals Ubuntu. Als eerste maak je een 'git' gebruiker aan en een `.ssh` map voor die gebruiker. $ sudo adduser git $ su git $ cd $ mkdir .ssh -Daarna moet je een aantal publieke SSH sleutels van ontwikkelaars aan het `authorized_keys` bestand toevoegen voor die gebruiker. Laten we aannemen dat je een aantal sleutels per e-mail ontvangen hebt en ze hebt opgeslagen in tijdelijke bestanden. Nogmaals, de sleutels zien er ongeveer zo uit: +Vervolgens moet je een aantal publieke SSH sleutels van ontwikkelaars aan het `authorized_keys` bestand toevoegen voor die gebruiker. Laten we aannemen dat je een aantal sleutels per e-mail ontvangen hebt en ze hebt opgeslagen in tijdelijke bestanden. Nogmaals, de sleutels zien er ongeveer zo uit: $ cat /tmp/id_rsa.john.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4L @@ -233,7 +232,7 @@ Nu kun je een lege repository voor ze instellen door `git init` uit te voeren me $ cd project.git $ git --bare init -Daarna kunnen John, Josie of Jessica de eerste versie van hun project in de repository pushen door het als een remote toe te voegen en naar een branch te pushen. Let op dat iemand met een shell op de machine zal moeten inloggen en een kale repository moet creëren, iedere keer als je een project wilt toevoegen. Laten we `gitserver` als hostnaam gebruiken voor de server waar je de 'git' gebruiker en repository hebt ingesteld. Als je het binnenshuis draait, en je de DNS instelt zodat `gitserver` naar die server wijst, dan kun je de commando's vrijwel ongewijzigd gebruiken: +Daarna kunnen John, Josie of Jessica de eerste versie van hun project in de repository pushen door het als een remote toe te voegen en een branch te pushen. Merk op dat iemand met een shell op de machine zal moeten inloggen en een kale repository moet creëren voor elke keer dat je een project wilt toevoegen. Laten we `gitserver` als hostnaam gebruiken voor de server waar je de 'git' gebruiker en repository hebt aangemaakt. Als je het binnenshuis draait, en je de DNS instelt zodat `gitserver` naar die server wijst, dan kun je de commando's vrijwel ongewijzigd gebruiken: # op Johns computer $ cd myproject @@ -250,7 +249,7 @@ Vanaf dat moment kunnen de anderen het clonen en wijzigingen even gemakkelijk te $ git commit -am 'fix for the README file' $ git push origin master -Met deze methode kun je snel een lees/schrijf Git server draaiend krijgen voor een handjevol ontwikkelaars. +Op deze manier kun je snel een lees/schrijf Git server draaiend krijgen voor een handjevol ontwikkelaars. Als een extra voorzorgsmaatregel kun je de 'git' gebruiker makkelijk beperken tot het doen van alleen Git activiteiten, met een gelimiteerde shell applicatie genaamd `git-shell` die bij Git geleverd wordt. Als je dit als login shell voor je 'git' gebruiker instelt, dan kan de 'git' gebruiker geen normale shell toegang hebben op je server. Specificeer `git-shell` in plaats van bash of csh voor je gebruikers login shell om dit te gebruiken. Om dit te doen zul je waarschijnlijk het `/etc/passwd` bestand aan moeten passen: @@ -273,11 +272,11 @@ Nu kan de 'git' gebruiker de SSH connectie alleen gebruiken om Git repositories ## Publieke toegang ## -Wat als je anonieme leestoegang op je project wil? Misschien wil je geen intern privé project beheren, maar een open source project. Of misschien heb je een aantal geautomatiseerde bouwservers of continue integratie servers die vaak wijzigen, en wil je niet doorlopend SSH sleutels hoeven genereren – je wil gewoon eenvoudige leestoegang toevoegen. +Wat als je anonieme leestoegang op je project wil? Misschien wil je geen intern privé project beheren, maar een open source project. Of misschien heb je een aantal geautomatiseerde bouwservers of continue integratie servers die vaak wisselen, en wil je niet doorlopend SSH sleutels hoeven genereren – je wil gewoon eenvoudige anonieme leestoegang toevoegen. -Waarschijnlijk is de eenvoudigste manier voor kleinschalige opstellingen om een statische webserver in te stellen, waarbij de document root naar de plaats van je Git repositories wijst, en dan de `post-update` haak aanzetten waar we het in de eerste paragraaf van dit hoofdstuk over gehad hebben. Laten we eens uitgaan van het voorgaande voorbeeld. Stel dat je je repositories in de `/opt/git` map hebt staan, en er draait een Apache server op je machine. Nogmaals, je kunt hiervoor iedere web server gebruiken: maar als voorbeeld zullen we wat basis Apache configuraties laten zien, die je een idee kunnen geven van wat je nodig hebt. +Waarschijnlijk is de eenvoudigste manier voor kleinschalige opstellingen om een statische webserver in te stellen, waarbij de document root naar de plaats van je Git repositories wijst, en dan de `post-update` haak aanzetten waar we het in de eerste paragraaf van dit hoofdstuk over gehad hebben. Laten we eens uitgaan van het voorgaande voorbeeld. Stel dat je je repositories in de `/opt/git` map hebt staan, en er draait een Apache server op je machine. Nogmaals, je kunt hiervoor iedere web server gebruiken: maar als voorbeeld zullen we wat simpele Apache configuraties laten zien, die je het idee weergeven van wat je nodig hebt. -Eerst moet je de haak aanzetten: +Eerst moet je de haak inschakelen: $ cd project.git $ mv hooks/post-update.sample hooks/post-update @@ -285,7 +284,7 @@ Eerst moet je de haak aanzetten: Als je een lagere versie dan 1.6 van Git gebruikt, dan is het `mv` commando niet nodig — Git is recentelijk pas begonnen met de namen van de haak voorbeelden op .sample te laten eindigen. -Wat doet deze `post-update` haak? Het ziet er ongeveer zo uit: +Wat doet deze `post-update` haak? Het ziet er eigenlijk als volgt uit: $ cat .git/hooks/post-update #!/bin/sh @@ -293,7 +292,7 @@ Wat doet deze `post-update` haak? Het ziet er ongeveer zo uit: 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 wildcard DNS ingesteld hebt om `*.gitserver` door te sturen naar waar je dit alles draait: +Vervolgens moet je een VirtualHost regel in je Apache configuratie aanmaken, met de document root als de hoofdmap van je Git projecten. Hier nemen we aan dat je wildcard DNS ingesteld hebt om `*.gitserver` door te sturen naar waar je dit alles draait: ServerName git.gitserver @@ -304,7 +303,7 @@ Vervolgens moet je een VirtualHost toevoeging in je Apache configuratie aanmaken -Je zult ook de Unix gebruikers groep van de `/opt/git` mappen moeten instellen op `www-data` zodat je web server leestoegang hebt op de repositories, omdat de Apache instantie die het CGI script uitvoert (standaard) als die gebruiker draait: +Je zult ook de Unix gebruikers groep van de `/opt/git` mappen moeten zetten op `www-data` zodat je web server leestoegang hebt op de repositories, omdat de Apache instantie het CGI script (standaard) uitvoert als die gebruiker draait: $ chgrp -R www-data /opt/git @@ -312,26 +311,26 @@ Als je Apache herstart, dan zou je je repositories onder die map moeten kunnen k $ git clone http://git.gitserver/project.git -Op deze manier kun je HTTP-gebaseerde toegang voor elk van je projecten voor een groot aantal gebruikers in slechts een paar minuten instellen. Een andere eenvoudige optie om publieke ongeauthenticeerde toegang in te stellen is een Git daemon te starten, alhoewel dat vereist dat je het proces als daemon uitvoert – we beschrijven deze optie in de volgende paragraaf als je een voorkeur hebt voor deze variant. +Op deze manier kun je HTTP-gebaseerde toegang voor elk van je projecten voor een groot aantal gebruikers in slechts een paar minuten regelen. Een andere eenvoudige optie om publieke ongeauthenticeerde toegang in te stellen is een Git daemon te starten, alhoewel dat vereist dat je het proces als daemon uitvoert – we beschrijven deze optie in de volgende paragraaf als je een voorkeur hebt voor deze variant. ## GitWeb ## -Nu je basis lees/schrijf en alleen-lezen toegang tot je project hebt, wil je misschien een eenvoudige web-gebaseerde visualisatie instellen. Git levert een CGI script genaamd GitWeb mee, dat veelal voor hiervoor gebruikt wordt. Je kunt GitWeb in gebruik zien bij sites zoals `http://git.kernel.org` (zie Figuur 4-1). +Nu je gewone lees/schrijf en alleen-lezen toegang tot je project hebt, wil je misschien een eenvoudige web-gebaseerde visualisatie instellen. Git levert een CGI script genaamd GitWeb mee, dat normaalgesproken hiervoor gebruikt wordt. Je kunt GitWeb in actie zien bij sites zoals `http://git.kernel.org` (zie Figuur 4-1). Insert 18333fig0401.png Figuur 4-1. De GitWeb web-gebaseerde gebruikers interface. -Als je wil zien hoe GitWeb er op jouw project uitziet, dan heeft Git een commando waarmee je een tijdelijke instantie op kunt starten als je een lichtgewicht server op je systeem hebt zoals `lighttpd` of `webrick`. Op Linux machines is `lighttpd` vaak geïnstalleerd, dus je kunt het misschien draaiend krijgen door `git instaweb` in te typen in je project map. Als je op een Mac werkt: Leopard heeft Ruby voorgeïnstalleerd, dus `webrick` zou je beste gok kunnen zijn. Om `instaweb` met een server anders dan lighttpd te starten, kun je het uitvoeren met de `--httpd` optie. +Als je wil zien hoe GitWeb er voor jouw project uitziet, dan heeft Git een commando waarmee je een tijdelijke instantie op kunt starten als je een lichtgewicht server op je systeem hebt zoals `lighttpd` of `webrick`. Op Linux machines is `lighttpd` vaak geïnstalleerd, dus je kunt het misschien draaiend krijgen door `git instaweb` in te typen in je project map. Als je op een Mac werkt: Leopard heeft Ruby voorgeïnstalleerd, dus `webrick` zou je de meeste kans geven. Om `instaweb` met een server anders dan lighttpd te starten, moet je het uitvoeren met de `--httpd` optie. $ 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] -Dat start een HTTPD server op poort 1234 op en start automatisch een web browser op die met die pagina opent. Het is dus makkelijk voor je. Als je klaar bent en de server wilt afsluiten, dan kun je hetzelfde commando uitvoeren met de `--stop` optie: +Dat start een HTTPD server op poort 1234 op en start automatisch een web browser die op die pagina opent. Het is dus makkelijk voor je. Als je klaar bent en de server wilt afsluiten, dan kun je hetzelfde commando uitvoeren met de `--stop` optie: $ git instaweb --httpd=webrick --stop -Als je de web interface doorlopend op een server wilt draaien voor je team of voor een open source project dat je verspreid, dan moet je het CGI script instellen zodat het door je normale web server geserveerd wordt. Sommige Linux distributies hebben een `gitweb` pakket dat je misschien kunt installeren via `apt` of `yum`, dus misschien kan je dat eerst proberen. We zullen snel door een handmatige GitWeb installatie heenlopen. Eerst moet je de Git broncode pakken waar GitWeb bij zit, en het aangepaste CGI script genereren: +Als je de web interface doorlopend op een server wilt draaien voor je team of voor een open source project dat je verspreid, dan moet je het CGI script instellen zodat het door je normale web server geserveerd wordt. Sommige Linux distributies hebben een `gitweb` pakket dat je zou kunnen installeren via `apt` of `yum`, dus wellicht kan je dat eerst proberen. We zullen snel door een handmatige GitWeb installatie heen lopen. Eerst moet je de Git broncode pakken waar GitWeb bij zit, en het aangepaste CGI script genereren: $ git clone git://git.kernel.org/pub/scm/git/git.git $ cd git/ @@ -354,18 +353,17 @@ Merk op dat je het commando moet vertellen waar het je Git repositories kan vind -Nogmaals, GitWeb kan geserveerd worden met iedere web server die in staat is CGI te verwerken; 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 web server die in staat is CGI te verwerken. Als je iets anders prefereert zou het niet moeilijk moeten zijn dit in te stellen. Vanaf dit moment 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. ## Gitosis ## -De publieke sleutels van alle gebruikers in een `authorized_keys` bestand bewaren voor toegang werkt slechts korte tijd goed. Als je honderden gebruikers hebt, dan is het bewerkelijk om dat proces te volgen. Je moet iedere keer in de server inloggen, en er is geen toegangscontrole – iedereen in het bestand heeft lees- en schrijftoegang op ieder project. +De publieke sleutels van alle gebruikers in een `authorized_keys` bestand bewaren voor toegang werkt slechts korte tijd goed. Als je honderden gebruikers hebt, dan is het te bewerkelijk om dat proces te blijven volgen. 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 verzameling scripts die je helpen het `authorized_keys` bestand te beheren alsmede eenvoudig 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 beheert de informatie in dat project; en als je het pushed, dan herconfigureert Gitosis de server op basis van dat project, wat best wel stoer is. +Op dat moment zou je kunnen overwegen een veelgebruikt software project genaamd Gitosis te gaan gebruiken. Gitosis is in feite een verzameling scripts die je helpen het `authorized_keys` bestand te beheren alsmede eenvoudig toegangscontrole te implementeren. Het interessante hieraan 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 beheert de informatie in dat project en als je het pushed, dan herconfigureert Gitosis de server op basis van dat project, wat best wel slim bedacht is. -Gitosis installeren is niet de makkelijkste taak ooit, maar het is ook niet te moeilijk. Het is het makkelijkste om er een Linux server voor te gebruiken – deze voorbeelden gebruiken een standaard Ubuntu 8.10 server. ->>>>>>> [nl] Language and wording corrections. Introducing characters from ASCII +Gitosis installeren is niet de makkelijkste taak ooit, maar het is ook niet al te moeilijk. Het is het makkelijkste om er een Linux server voor te gebruiken – deze voorbeelden gebruiken een standaard Ubuntu 8.10 server. -Gitosis vereist enkele Python applicaties, dus moet je eerst het Python setuptools pakket installeren, wat Ubuntu beschikbaar stelt als python-setuptools: +Gitosis vereist enkele Python tools, dus moet je eerst het Python setuptools pakket installeren, wat Ubuntu beschikbaar stelt als python-setuptools: $ apt-get install python-setuptools @@ -375,15 +373,15 @@ Vervolgens kloon en installeer je Gitosis van de hoofdpagina van het project: $ cd gitosis $ sudo python setup.py install -Daarmee worden een aantal uitvoerbare bestanden geïnstalleerd, die Gitosis zal gebruiken. Daarna wil Gitosis zijn repositories onder `/home/git` stoppen, wat prima is. Maar je hebt je repositories al in `/opt/git` geconfigureerd, dus in plaats van alles te herconfigureren maken we een symbolische link aan: +Daarmee worden een aantal bestanden geïnstalleerd, die Gitosis zal gebruiken. Daarna wil Gitosis zijn repositories onder `/home/git` stoppen, wat prima is. Maar je hebt je repositories al in `/opt/git` geconfigureerd, dus in plaats van alles te herconfigureren maken we een symbolische link aan: $ ln -s /opt/git /home/git/repositories -Gitosis zal je sleutels voor je beheren, dus je moet het huidige bestand verwijderen, om de sleutels later opnieuw toe te voegen en Gitosis het `authorized_keys` bestand automatisch laten beheren. Voor nu verplaatsen we het `authorized_keys` bestand: +Gitosis zal de sleutels voor je beheren, dus je moet het huidige bestand verwijderen, om de sleutels later opnieuw toe te voegen en Gitosis het `authorized_keys` bestand automatisch laten beheren. Voor nu verplaatsen we het `authorized_keys` bestand: $ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak -Nu moet je je shell terugzetten voor de 'git' gebruiker, als je het veranderd hebt naar het `git-shell` commando. Mensen zullen nog steeds niet in staat zijn in te loggen, maar Gitosis zal dat voor je beheren. Dus, laten we deze regel veranderen in je `/etc/passwd` bestand +Nu moet je de shell terugzetten voor de 'git' gebruiker, als je het veranderd hebt naar het `git-shell` commando. Mensen zullen nog steeds niet in staat zijn in te loggen, Gitosis zal dat voor je beheren. Dus, laten we deze regel veranderen in je `/etc/passwd` bestand git:x:1000:1000::/home/git:/usr/bin/git-shell @@ -397,11 +395,11 @@ Nu wordt het tijd om Gitosis te initialiseren. Je doet dit door het `gitosis-ini Initialized empty Git repository in /opt/git/gitosis-admin.git/ Reinitialized existing Git repository in /opt/git/gitosis-admin.git/ -Dit staat de gebruiker met die sleutel toe de hoofd Git repository, die de Gitosis installatie beheert, aan te passen. Daarna zul je met de hand het execute bit op het `post-update` script moeten instellen voor je nieuwe beheer repository. +Dit staat de gebruiker met die sleutel toe de hoofd Git repository, die de Gitosis setup regelt, aan te passen. Daarna zul je met de hand het execute bit op het `post-update` script moeten aanzetten voor je nieuwe beheer repository. $ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update -Je bent nu klaar om te gaan. Als je alles juist hebt ingesteld, kun je nu met SSH in je server loggen als de gebruiker waarvoor je de publieke sleutel hebt toegevoegd om Gitosis te initialiseren. Je zou dan zoiets als dit moeten zien: +Je bent nu klaar voor de start. Als je alles juist hebt ingesteld, kun je nu met SSH in je server loggen als de gebruiker waarvoor je de publieke sleutel hebt toegevoegd om Gitosis te initialiseren. Je zou dan zoiets als dit moeten zien: $ ssh git@gitserver PTY allocation request failed on channel 0 @@ -421,7 +419,7 @@ Nu heb je een map genaamd `gitosis-admin`, die twee hoofd gedeeltes heeft: ./keydir ./keydir/scott.pub -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. +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 de repositories hebben – één bestand per gebruiker. De naam van het bestand in `keydir` (in het vorige voorbeeld, `scott.pub`) zal anders zijn in jouw geval – 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 gekloonde `gitosis-admin` project mogen bevatten: @@ -432,9 +430,9 @@ Als je naar het `gitosis.conf` bestand kijkt, zou het alleen informatie over het writable = gitosis-admin members = scott -Het laat je zien dat de gebruiker 'scott' — de gebruiker met wiens publieke sleutel je Gitosis geïnitialiseerd hebt — de enige is die toegang heeft tot het `gitosis-admin` project. +Het laat je zien dat de gebruiker 'scott' – de gebruiker met wiens publieke sleutel je Gitosis geïnitialiseerd hebt – de enige is die toegang heeft tot het `gitosis-admin` project. -Laten we een nieuw project voor je toevoegen. Je voegt een nieuwe sectie genaamd `mobile` toe, waar je de ontwikkelaars in je mobile team neerzet, en de projecten waar deze ontwikkelaars toegang tot moeten hebben. Omdat 'scott' op het moment de enige gebruiker in het systeem is, zul je hem als enig lid toevoegen en zul je een nieuw project genaamd `iphone_project` toevoegen om mee te beginnen: +Laten we nu een nieuw project voor je toevoegen. Je voegt een nieuwe sectie genaamd `mobile` toe, waar je de ontwikkelaars in het mobile team neerzet, en de projecten waar deze ontwikkelaars toegang tot moeten hebben. Omdat 'scott' op het moment de enige gebruiker in het systeem is, zul je hem als enig lid toevoegen en voeg je een nieuw project genaamd `iphone_project` toe om mee te beginnen: [group mobile] writable = iphone_project @@ -466,7 +464,7 @@ Je kunt je eerste push naar het nieuwe `iphone_project` doen door je server als Merk op dat je geen pad hoeft te specificeren (sterker nog, het wel doen zal niet werken), alleen een dubbele punt en dan de naam van het project — Gitosis zal het voor je vinden. -Je wil samen met je vrienden aan dit project werken, dus je zult hun publieke sleutels weer toe moeten voegen. Maar in plaats van ze handmatig aan het `~/.ssh/authorized_keys` bestand op je server toe te voegen, voeg je ze, één sleutel per bestand, aan de `keydir` map toe. Hoe je de sleutels noemt bepaalt hoe je aan de gebruikers refereert in het `gitosis.conf` bestand. Laten we de publieke sleutels voor John, Josie en Jessica toevoegen: +Je wil samen met je vrienden aan dit project werken, dus je zult hun publieke sleutels weer toe moeten voegen. Maar in plaats van ze handmatig aan het `~/.ssh/authorized_keys` bestand op je server toe te voegen, voeg je ze één sleutel per bestand, aan de `keydir` map toe. Hoe je de sleutels noemt bepaalt hoe je aan de gebruikers refereert in het `gitosis.conf` bestand. Laten we de publieke sleutels voor John, Josie en Jessica toevoegen: $ cp /tmp/id_rsa.john.pub keydir/john.pub $ cp /tmp/id_rsa.josie.pub keydir/josie.pub @@ -490,7 +488,7 @@ Gitosis heeft ook eenvoudige toegangscontrole. Als je wilt dat John alleen lees readonly = iphone_project members = john -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: +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 alle verschillende gebruikers en projecten mogen bevatten. Je kunt ook een andere groep als een van de leden specificeren (met @ als voorvoegsel), waarmee de groepsleden automatisch worden overerfd: [group mobile_committers] members = scott josie jessica @@ -503,67 +501,64 @@ Nu kan John het project klonen 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 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. +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. ## Gitolite ## -Let op: de laatste versie van deze sectie van het Progit boek is altijd beschikbaar in [gitolite documentation][gldpg]. De auteur wil ook nederig vaststellen dat, ondanks dat deze sectie accuraat is, en *kan* (en vaak *is*) gebruikt worden om gitolite te installeren zonder verdere documentatie te lezen; het uit noodzaak niet compleet is, en niet de enorme hoeveelheid documentatie die bij gitolite komt kan vervangen. +Merk op: de laatste versie van deze paragraaf in het ProGit boek is altijd beschikbaar binnen de [gitolite documentation][gldpg]. De auteur geeft ook nederig aan dat, hoewel deze paragraaf accuraat is, het *kan* (en vaak ook *is*) gebruikt om gitolie te installeren zonder enige andere documentatie te lezen, dat het niet gegarandeerd compleet is, en het zeker niet de gehele enorme hoeveelheid documentatie kan vervangen dat meegeleverd wordt met gitolite. [gldpg]: http://github.com/sitaramc/gitolite/blob/pu/doc/progit-article.mkd -Git is erg populair geworden in bedrijfsomgevingen, die veelal extra eisen hebben in termen van toegangscontrole. Gitolite was oorspronkelijk gemaakt om met die eisen te helpen, maar het blijkt dat het net zo bruikbaar is in de open source wereld: het Fedora project beheert de toegang tot hun pakket beheer repositories (ongeveer 10.000 stuks!) met behulp van gitolite, en dit is waarschijnlijk ook de grootste gitolite installatie. +Git begint erg populair te worden in het bedrijfsleven, die de neiging hebben nog wat additionele eisen te hebben op het gebied van toegangscontrole. Gitolite was oorspronkelijk gemaakt om bij het vervullen van deze eisen te helpen, maar het blijkt dat het even bruikbaar is in de wereld van de open source: het Fedora Project beheert toegang tot hun package beheer repositories (meer dan 10.000 daarvan!) met gitolite, en het is waarschijnlijk daarbij ook nog eens de grootste gitolite installatie waar dan ook. -Gitolite staat je toe om de toegang niet alleen per repository te specificeren, maar ook per branch of tag binnen elk repository. Dat wil zeggen dat je in kunt stellen dat bepaalde mensen (of groepen van mensen) alleen kunnen pushen naar bepaalde "refs" (branches of tags), maar niet naar andere. +Gitolite stelt je in staat de permissies niet alleen per repository, maar ook per branch of tag naam binnen elke repository. Dus, je kunt aangeven dat bepaalde mensen (of groepen van mensen) alleen maar bepaalde "refs" (branches of tags) kunnen pushen maar niet andere. -### Installeren ### +### Installatie ### -Het installeren van Gitolite is erg eenvoudig, zelfs als je niet alle uitgebreide documentatie leest die erbij zit. Je hebt een account om een of andere Unix server nodig; diverse Linux smaken en Solaris 10 zijn getest. Je hebt geen root toegang nodig, aangenomen dat git, perl, en een met openssh verenigbare server reeds geïnstalleerd zijn. In de voorbeelden hieronder zullen we het `gitolite` account gebruiken op een host genaamd `gitserver`. +Het installeren van Gitolite is zeer eenvoudig, zelfs als je de uitgebreide documentatie, dat erbij geleverd wordt, niet leest. Je hebt een account op een Unix(achtige) server hebben; verschillende Linux smaken en Solaris 10 zijn getest. Je hebt geen root toegang nodig, aangenomen dat git, perl, en een openssh compatible ssh server al zijn geïnstalleerd. In de onderstaand voorbeelden zullen we het `gitolite` account gebruiken op een host genaamd `gitserver`. -Gitolite is wat ongebruikelijk voor wat betreft "server" software -- toegang gaat via ssh, en dus is ieder gebuikers id een potentiële "gitolite host". Bij gevolg zijn er begrippen als het "installeren" van de software, en dan het "instellen" van een gebruiker als een "gitolite host". +Gitolite is nogal ongebruikelijk in de zin van "server" software -- toegang gaat via ssh, en elke userid op de server is in potentie een "gitolite host". Het resultaat is, dat er een idee is van "installeren" van de software zelf, en dan het "opzetten" van een gebruiker als een "gitolist host". -Gitolite kan op 4 manieren geïnstalleerd worden. Mensen die Fedora of Debian systemen gebruiken, kunnen een RPM of DEB krijgen en dat installeren. Mensen met root toegang kunnen het handmatig installeren. Bij deze twee methoden kan iedere gebruiker op het systeem een "gitolite host" worden. +Mensen zonder root toegang kunnen het installeren binnen hun eigen user id. Als laatste: gitlite kan geïnstalleerd worden door een script te starten *op het werkstation*, vanuit een bash-shell. (Zelfs de bash die meegeleverd wordt met msysgit volstaat, voor het geval je je dat afvroeg.) -Mensen zonder root toegang kunnen het binnen hun eigen gebruikerid installeren. Tenslotte kan gitolite geïnstalleerd worden door het uitvoeren van een script *op het werkstation*, vanuit een bash shell. (Zelfs de bash shell die bij msysgit zit voldoet, mocht je het je afvragen). +We zullen dit laatste in dit stuk beschrijven, voor de overige methoden verwijzen we je naar de documentatie. -We zullen deze laatste methode in dit artikel beschrijven; kijk alstublieft in de documentatie voor de andere methoden. - -Je begint met het verkrijgen van toegang op je server op basis van een publieke sleutel, zodat je in kunt loggen vanaf je werkstation zonder een wachtwoord prompt te krijgen. De volgende methode werkt op Linux; voor andere werkstation OSsen zul je dit misschien handmatig moeten doen. We gaan er vanuit dat je reeds een sleutelpaar gegeneerd hebt met behulp van `ssh-keygen`. +Je begint met het verkrijgen van toegang op basis van een publieke sleutel, zodat je vanaf je werkstation op de server kan inloggen zonder het intypen van je wachtwoord. De volgende methode werkt op Linux; voor andere werkstation besturingssystemen moet je dit wellicht handmatig doen. We gaan er vanuit dat je al een sleutelpaar hebt gegenereerd met `ssh-keygen`. $ ssh-copy-id -i ~/.ssh/id_rsa gitolite@gitserver -Dit zal je vragen naar het wachtwoord van het gitolite account, en dan toegang met een publieke sleutel instellen. Dit is **essentieel** voor het installatiescript, dus controleer dat je een commando kan uitvoeren zonder een wachtwoord prompt te krijgen: +Dit zal je vragen naar een wachtwoord naar het gitolite account, en dan de publieke sleutel toegang opzetten. Dit is **absoluut noodzakelijk** voor het installatiescript, dus controleer dit om er zeker van te zijn dat je een commando kan laten lopen zonder een wachtwoord te hoeven in typen. $ ssh gitolite@gitserver pwd /home/gitolite -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): +Vervolgens, clone je Gitolite van de hoofdsite van het project en roept de "easy install" script aan (het derde argument is jouw naam zoals je deze in de resulterende gitolite-admin repository wilt laten verschijnen): $ git clone git://github.com/sitaramc/gitolite $ cd gitolite/src $ ./gl-easy-install -q gitolite gitserver sitaram -En dan ben je klaar! Gitolite is nu geïnstalleerd op de server, en je hebt nu een splinternieuw repository genaamd `gitolite-admin` in de home directory van je werkstation. Je kunt je gitolite installatie beheren door wijzigingen te doen in dit repository en te pushen. +En dat is het! Gitolite is nu geïnstalleerdop je server, en je hebt nu een gloednieuwe repository genaamd `gitolite-admin` in de home directory van jouw werkstation. Je beheert je gitolite setup door een wijziging aan te brengen in deze reporitory en deze te pushen. -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!) +Dat laatste commando produceert nogal een hoeveelheid uitvoer dat wellicht interessant is om te lezen. Ook wordt er, de eerste keer dat je het laat lopen, er een nieuwe sleutelpaar gemaakt; je moet een wachtwoord kiezen of Enter als je er geen wilt. Waarom een tweede sleutelpaar nodig is, en hoe deze wordt gebruikt, wordt uitgelegd in het "ssh troubleshooting" document dat bij Gitolite wordt meegeleverd. (Hey, de documentatie moet *ergens* goed voor zijn!) -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: +Repositories genaamd `gitolite-admin` en `testing` worden standaard op de server aangemaakt. Als je een van beide lokaal wilt clonen (van een account die SSA console toegang heeft naar het gitolite account via *authorized_keys*) type je: $ git clone gitolite:gitolite-admin $ git clone gitolite:testing - -Om dezelfde repos van ieder ander account te klonen: + +Om deze zelfde repositories te clonen van een willekeurige ander account: $ git clone gitolite@servername:gitolite-admin $ git clone gitolite@servername:testing +### De Installatie Aanpassen ### -### De installatie aanpassen ### - -Hoewel de standaard, snelle, installatie voor de meeste mensen werkt, zijn er manieren om de installatie aan te passen als dat nodig is. Als je het `-q` argument weglaat, krijg je een "spraakzame" installatiemodus -- met gedetailleerde informatie van wat de installatie aan het doen is bij iedere stap. De spraakzame modus laat je ook bepaalde parameters van de server-kant instellen, zoals de locatie van de echte repositories, door een "rc" bestand dat de server gebruikt aan te passen. Dit "rc" bestand is behoorlijk van commentaar voorzien, dus je zou eenvoudig in staat moeten zijn om de wijzigingen te maken die je wilt, op te slaan, en te vervolgen. Dit bestand bevat ook instellingen die je kunt aanpassen om sommige geavanceerde opties van gitolite aan of uit te zetten. +Hoewel de standaard, snelle, installatie werkt voor de meeste mensen, zijn er een aantal manieren om de installatie aan te passen als dat nodig is. Als je het `-q` argument weg laat, krijg je een "verbose" installatie wijze -- gedetaileerde informatie over wat de installatie aan het doen is bij elke stap. De verbose wijze staat je ook toe om bepaalde server-side parameters aan te passen, zoals de locatie van de eigenlijke repositories, door het wijzigen van een "rc" bestand dat de server gebruikt. Dit "rc" bestand is ruimhartig van commentaar voorzien dus je zou in staat moeten zijn om elke wijziging die je nodig vindt vrij snel te maken, op te slaan en door te gaan. Dit bestand bevat ook enkele instellingen die je kunt aanpassen om de meer geavanceerde functies van gitolite aan of uit te zetten. -### Configuratiebestand en Toegangsregels ### +### Config bestand en Beheer van Toegangsregels ### -Als de installatie klaar is, kun je wijzigen naar het `gitolite-admin` repository (dat in je HOME directory geplaatst is) en er in rondkijken om te zien wat je hebt: +Op het moment dat de installatie afgerond is, schakel je over naar de `gitolite-admin` repository (staat in je HOME directory) en begin je rond te snuffelen om te zien wat je daar hebt: $ cd ~/gitolite-admin/ $ ls @@ -581,11 +576,11 @@ Als de installatie klaar is, kun je wijzigen naar het `gitolite-admin` repositor repo testing RW+ = @all -Let op dat "sitaram" (het laatste argument voor het `gl-easy-install` commando dat je eerder invoerde) lees- en schrijftoegang heeft op het `gitolite-admin` repository, en een publieke sleutelbestand heeft met dezelfde naam. +Merk op dat "sitaram" (het laatste argument in het `gl-easy-install` commando dat je eerder gegeven hebt) lees en schrijf rechten heeft op de `gitolite-admin` repository en een publiek sleutelbestand met dezelfde naam. -De syntax voor het gitolite configuratie bestand is ruim beschreven in `conf/example.conf`, dus daarom noemen we hier alleen de hoogtepunten. +De syntax van het config bestand voor gitolite is ruimhartig van documentatie voorzien in `conf/example.conf`, dus we zullen alleen wat hoofdpunten benoemen. -Je kunt voor het gemak gebruikers of repos groeperen. De groepnamen zijn net als macros; als je ze definieert, maakt het niet eens uit of ze projecten zijn of gebruikers; dat onderscheid wordt alleen gemaakt als je de "macro" *gebruikt*. +Je kunt voor het gemak gebruikers of repositories groeperen. De groepnamen zijn vergelijkbaar met macros; als je ze definieert maakt het niet uit of het projecten of gebruikers zijn, dat onderscheid wordt pas gemaakt als je de "macro" gaat *gebruiken*. @oss_repos = linux perl rakudo git gitolite @secret_repos = fenestra pear @@ -595,7 +590,7 @@ Je kunt voor het gemak gebruikers of repos groeperen. De groepnamen zijn net als @engineers = sitaram dilbert wally alice @staff = @admins @engineers @interns -Je kunt permissies instellen op "ref" niveau. In het volgende voorbeeld mogen stagiaires alleen naar de "int" branch pushen. Engineers mogen pushen naar iedere branch waarvan de naam begint met "eng-", en tags die beginnen met "rc" gevolgd door een cijfer. En de admins mogen alles (inclusief rewind) doen op iedere ref. +Je kunt de permissies beheren op het "ref" niveau. In het volgende voorbeeld kunnen stagieres (interns) alleen maar naar de "int" branch pushen. Techneuten (engineers) kunnen naar elke branch pushen waarvan de naam begint met "eng-", en tags die beginnen met "rc" gevolgd door een getal. En de admins kunnen alles (inclusief terugdraaien) naar elke ref. repo @oss_repos RW int$ = @interns @@ -603,38 +598,38 @@ 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 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. +De expressie achter de `RW` of `RW+` is een zgn. regular expression (regex) waartegen de refname (ref) die wordt gepushed wordt vergeleken. Dus we noemen het natuurlijk een "refex"! En natuurlijk kan een refex veel krachtiger zijn dan hier wordt getoond, dus ga het niet overdrijven als je niet al te goed in de perl regexen zit. -En, zoals je waarschijnlijk al geraden had, zet Gitolite `refs/heads/` er als een syntactisch gemak voor als de refex niet begint met `refs/`. +Zoals je wellicht al geraden hebt, prefixed Gitolite `refs/heads/` als een syntactische handigheid als de refex niet begint met `refs/`. -Een belangrijke eigenschap van de syntax van het configuratiebestand is dat niet alle regels voor een repository op een plaats moeten staan. Je kunt alle overeenkomstige dingen bij elkaar houden, zoals alle regels voor `oss_repos` die hierboven getoond wordt, en dan specifieke regels voor specifieke gevallen verderop toevoegen, zoals: +Een belangrijke eigenschap van de syntax van het config bestand is dat alle regels van een repository niet op één plek hoeft te staan. Je kunt al het generieke spul bij elkaar houden, zoals de regels voor alle `oss_repos` zoals ze hier boven staan, en dan op een latere plaats specifieke regels voor specifieke gevallen, zoals hier: repo gitolite RW+ = sitaram -Die regel zal alleen maar toegevoegd worden aan de set regels voor het `gitolite` repository. +Deze regel wordt gewoon toegevoegd aan de set met regels voor de `gitolite` repository. -Op dit punt zul je je misschien afvragen hoe de toegangsregels feitelijk toegepast worden, dus laten we dat kort bespreken. +Je zou je op dit punt kunnen afvragen hoe de toegangsregels eigenlijk worden toegepast, laten we dat kort behandelen. -Er zijn twee lagen van toegang in gitolite. De eerste is op het niveau van het repository; als je lees (of schrijf) toegang hebt op *een* ref in het repository, dan heb je lees (of schrijf) toegang tot het repository. +Er zijn twee niveaus van toegangsbeheer in gitolite. De eerste is op repository niveau. Als je lees (of schrijf)rechten hebt tot *enige* ref in de repository, dan heb je lees (of schrijf) rechten tot de repository. -De tweede laag, die alleen van toepassing is op "schrijf" toegang, is per branch of tag binnen een repository. De gebruikersnaam, de toegang die geprobeerd wordt (`W` of `+`), en de refnaam die aangepast wordt zijn bekend. De toegangsregels worden nagekeken in volgorde van verschijning in het configuratiebestand, waarbij gezocht wordt naar een passende vergelijking voor deze combinatie (maar onthoudt dan de refnaam gepast wordt met een regex, niet slechts met tekst). Als een overeenkomst gevonden wordt, dan slaagt de push. Als de vergelijking er doorheen valt wordt toegang geweigerd. +Het tweede niveau, alleen van toepassing voor "schrijf" toegang, is per branch of tag binnen een repository. De gebruikersnaam, het type toegang wat wordt gevraagd (`W` of '+'), en de refname dat wordt gewijzigd (update) zijn bekend. De toegangsregels worden gecontroleerd in volgorde van voorkomst in het config bestand, en er wordt gekeken naar een treffer voor deze combinatie (maar onthoudt dat de refname middels een regex wordt vergeleken, niet een simpele string-vergelijking). Als er een treffer is, dan slaagt de push. Als er geen treffer wordt gevonden (fallthrough) dan wordt toegang geweigerd. -### Geavanceerde Toegangscontrole met "afwijzing" regels ### +### Geavanceerde Toegangs Controle met "deny" regels ### -Tot dusver hebben we alleen permissies gezien die `R`, `RW`, of `RW+` zijn. Maar, gitolite staat ook een andere permissie toe: `-`, wat voor "afwijzing" staat. Dit geeft je veel meer kracht, ten koste van wat complexiteit, omdat nu er doorheen vallen niet de *enige* manier is waarop toegang geweigerd wordt, de *volgorde van de regels doet er nu ook toe*! +Tot zover hebben we alleen permissies gezien uit het rijtje `R`, `RW` of `RW+`. Echter, gitolite kent een andere permissie: `-`, wat staat voor "deny" (ontken). Dit geeft je veel meer macht, tegen kosten van wat hogere complexiteit omdat een fallthrough nu niet de *enige* manier is waarop toegang kan worden geweigerd, wordt *de volgorde van regels belangrijk*! -Stel dat we in bovenstaande situatie willen toestaan dat engineers alle branches *behalve* master en integ mogen terugdraaien. Zo doe je dat: +Stel dat, in de onderstaande situatie, we de techneuten in staat willen stellen elke branch te laten terugdraaien *behalve* master en integ. Dit is de manier om dat te doen: RW master integ = @engineers - master integ = @engineers RW+ = @engineers -Nogmaals, je volgt eenvoudig de regels vanaf de bovenkant totdat je een overeenkomst vindt voor je toegangsmodus, of een afwijzing. Een push zonder rewind op master of integ wordt toegestaan door de eerste regel. Een rewind push naar die refs komt niet overeen met de eerste regel, valt door naar de tweede, en wordt daarom afgewezen. Iedere push (rewind of non-rewind) naar refs anders dan master of integ zal sowieso niet overeenkomen met de eerste twee regels, en de derde regel staat het toe. +Nogmaals, je hoeft slechts de regels van boven naar beneden af te lopen tot je een treffer hebt voor je gevraagde toegangswijze, of een afwijzing. Een push die niets terugdraait naar master of integ wordt door de eerste regel toegestaan. Een terugdraai-push naar deze refs geeft geen treffer op de eerste regel en valt door naar de tweede regel en wordt daarom geweigerd. Elke push (terugdraaiend of niet) naar refs anders dan master of integ zullen op de eerste twee regels zowiezo niet treffen en de derde regel staat dit toe. -### Pushen beperken per gewijzigde bestanden ### +### Beperken van pushes bij gewijzigde bestanden ### -Naast het beperken van de branches waar een gebruiker wijzigingen naar kan pushen, kun je ook de bestanden die ze aan mogen raken beperken. Bijvoorbeeld, stel dat de Makefile (of een ander programma) eigenlijk niet door iedereen gewijzigd mag worden, omdat er een hoop dingen vanaf hangen of kapot gaan als de wijzigingen niet *precies goed* gedaan worden. Je kunt het gitolite vertellen: +Bovenop het beperken van gebruikersrechten op branches voor een gebruiker, kan je ook de rechten van gebruikers beperken op bestanden. Als voorbeeld, misschien is de Makefile (of een ander programma) niet echt bedoeld om te worden gewijzigd door iedereen, omdat een groot aantal dingen afhankelijk ervan zijn of omdat het stuk loopt als de wijzigingen niet *precies goed* gebeuren. Je kunt het gitolite duidelijk maken: repo foo RW = @junior_devs @senior_devs @@ -645,29 +640,29 @@ Naast het beperken van de branches waar een gebruiker wijzigingen naar kan pushe Deze krachtige eigenschap is gedocumenteerd in `conf/example.conf`. -### Persoonlijke Branches ### +### Persoonlijke branches ### -Gitolite heeft ook een eigenschap genaamd "persoonlijke branches" (of liever, "persoonlijke branch naamruimte (namespace)" die heel handig kan zijn in een bedrijfsomgeving. +Gitolite heeft ook een mogelijkheid van "persoonlijke branches" (of liever gezegd "persoonlijke branch namespace") wat erg nuttig kan zijn in een bedrijfssituatie. -Veel van de code uitwisseling die gedaan wordt in de git wereld gebeurd door middel van "pull alstublieft" verzoeken. In een bedrijfsomgeving echter is ongeverifieerde toegang een no-no, een werkstation van een ontwikkelaar kan geen verificatie doen, dus je zult naar de centrale server moeten pushen en iemand moeten vragen om vanaf daar te pullen. +Veel van de code-uitwisselingen in de git-wereld verlopen via zgn. "please pull" aanvragen. In een bedrijfsomgeving echter is ongeauthoriseerde toegang taboe, en het werkstation van een ontwikkelaar kan geen authenticatie doen, dus je moet naar de centrale server pushen en iemand vragen daarvandaan te pullen. -Dit zou doorgaans dezelfde branchnaam vervuiling veroorzaken als in een gecentraliseerd VCS, en het instellen van permissies hiervoor wordt een klus voor de admin. +Dit zou normaalgesproken een gelijksoortige branch-brij veroorzaken als in een gecentraliseerde versiebeheersysteem, en daarbij wordt het opzetten van permissies een vervelende klus voor de administrator. -Gitolite staat je toe een "personal" of "scratch" naamruimte prefix voor iedere ontwikkelaar te definiëren (bijvoorbeeld, `refs/personal//*`); zie de "personal branches" sectie in `doc/3-faq-tips-etc.mkd` voor details. +Gitolite stelt je in staat een "personal" of "scratch" namespace prefix voor elke ontwikkelaar te definiëren (bijvoorbeeld `refs/personal//*`); zie ook de "personal branches" paragraaf in `doc/3-faq-tips-etc.mkd` voor details. -### "Wildcard" repositories ### +### "Wildcard" repositores ### -Gitolite staat je toe om repositories met wildcards (eigenlijk perl regexen) te specificeren, zoals bijvoorbeeld `assignments/s[0-9][0-9]/a[0-9][0-9]`, als willekeurig voorbeeld. Dit is een *zeer* krachtige eigenschap, dat aan gezet moet worden door `$GL_WILDREPOS = 1;` in het rc bestand in te stellen. Het staat je toe om een nieuwe permissie modus ("C") toe te wijzen, die gebruikers toestaat om repositories op basis van die wildcards aan te maken, waarbij automatisch eigendom toegewezen wordt aan de gebruiker die het aangemaakt heeft, hem/haar toestaat R en RW permissies aan andere gebruikers uit te delen om samen te werken etc. Deze eigenschap is gedocumenteerd in `doc/4-wildcard-repositories.mkd`. +Gitolite laat je repositories specificeren met wildcards (eigenlijk perl regex expressies), zoals bijvoorbeeld `assignments/s[0-9][0-9]/a[0-9][0-9]`, om maar een willekeurig voorbeeld te nemen. Dit is een *heel* krachtige eigenschap die wordt aangezet door de regel `$GL_WILDREPOS = 1;` in het rc bestand. Het laat je een nieuwe permissiewijze ("C") toe te wijzen welke gebruikers in staat stelt repositories aan te maken die voldoen aan zulke wildcards, automatisch eigenaarsschap toe te wijzen aan de gebruiker die hem heeft aangemaakt, staat deze gebruiker toe om "R" en "RW" permissies aan anderen toe te wijzen om samen te werken, etc. Deze eigenschap is beschreven in `doc/4-wildcard-repositories.mkd`. -### Andere Eigenschappen ### +### Andere eigenschappen ### -We ronden deze bespreking af met een voorproefje van andere eigenschappen, die allemaal en nog vele meer, gedetailleerd zijn beschreven in de "faqs, tips, etc" en andere documenten. +We ronden deze uiteenzetting af met een passe partout van andere eigenschappen, welke alle (en nog vele andere) tot in de kleinste detail zijn beschreven in de "faqs, tips, etc" en andere documenten. -**Logging**: Gitolite legt alle succesvolle toegangen vast. Als je wat rustiger bent over het geven van rewind toegang aan andere mensen (`RW+`) en een of ander joch heeft "master" opgeblazen, dan is het logbestand je redder, in termen van het eenvoudig en snel vinden van het SHA dat kapot is gegaan. +**Logging**: Gitolite logt alle succesvolle toegangspogingen. Als je wat te los bent geweest in het toekennen van terugdraai permissies (`RW+`) en een of andere nozem heeft "master" vernaggelt, is de log-file een redder in de nood in de zin van snel en eenvoudig achterhalen van de SHA die verdwenen is. -**Git buiten normaal PATH**: Een extreem bruikbare gemakseigenschap in gitolite is ondersteuning voor een git installatie buiten het normale `$PATH` (dit komt vaker voor dan je denkt; sommige bedrijfsomgevingen of zelfs sommige hosting providers weigeren dingen systeembreed te installeren en je eindigt uiteindelijk met het installeren in je eigen home mappen). Normaal gesproken wordt je geforceerd om de *gebruikerskant* git op een of andere manier bewust te maken van deze niet-standaard locatie van de git bestanden. Met gitolite, kies je slechts een spraakzame installatie en stelt `$GIT_PATH` in in de "rc" bestanden. Voor de rest zijn er daarna geen wijzigingen meer nodig aan de gebruikerskant :-) +**Git buiten reguliere PATH**: Een ontzettend handige eigenschap in gitolite is het ondersteunen van git buiten het regulier `$PATH` (dit komt vaker voor dan je zou denken, sommige bedrijfs omgevingen of zelfs sommige hosting providers weigeren dingen systeem-breed te installeren en je eindigt ermee dat je ze in je eigen directories zet). Normaalgesproken ben je gedwongen git aan de *client-side* op de een of andere manier te vertellen van deze niet-standaard locatie van de git binaries. Met gitolite hoe je alleen een verbose installatie te kiezen en `$GIT_PATH` in de "rc" bestanden in te vullen. Hierna geen wijzigingen aan de kant van de clients nodig :-) -**Toegangsrapportage**: Een andere handige eigenschap is wat er gebeurd als je probeert met SSH naar de server te gaan. Gitolite toont je welke repos je toegang tot hebt, en welke toegang dat is. Hier is een voorbeeld: +**Rapportage van toegangsrechten**: Nog zo'n handige eigenschap is wat er gebeurt als je gewoon met ssh naar de server gaat. Gitolite laat zien welke repositories je toegang toe hebt en welke soort toegang dat dan wel is. Hier is een voorbeeld: hello sitaram, the gitolite version here is v1.5.4-19-ga3397d4 the gitolite config gives you the following access: @@ -679,25 +674,24 @@ We ronden deze bespreking af met een voorproefje van andere eigenschappen, die a R indic_web_input R shreelipi_converter -**Delegatie**: Voor hele grote installaties, kun je verantwoordelijkheden voor groepen of repositories delegeren aan diverse personen, en ze die onderdelen onafhankelijk laten beheren. Dit beperkt de belasting op de hoofd beheerder, en maakt hem minder een flessenhals. Deze eigenschap heeft zijn eigen documentatiebestand in de `doc/` map. +**Delegeren**: Voor extreem grote installaties kan je de verantwoordelijkheid voor groepen van repositories delegeren aan verschilllende mensen en hen het beheer van die delen onafhankelijk laten regelen. Dit vermindert de werkdruk van de hoofd-beheerder, en maakt van hem minder een faalpunt. Deze eigenschap heeft zijn eigen docuentatie bestand in de `doc/` directory. -**Gitweb ondersteuning**: Gitolite ondersteund gitweb op meerdere manieren. Je kunt specificeren welke repos zichtbaar zijn via gitweb. Je kunt de "eigenaar" en "omschrijving" voor gitweb instellen in het gitolite configuratiebestand. Gitweb heeft een mechanisme voor je om toegangscontrole gebaseerd op HTTP verificatie te implementeren, dus je kunt het het "samengestelde" configuratiebestand laten gebruiken dat gitolite produceert, wat betekend dat dezelfde toegangsregels (voor leestoegang) van toepassing zijn op gitweb en gitolite. +**Gitweb ondersteuning**: Gitolite ondersteunt gitweb op verschillende manieren. Je kunt aangeven welke repositories zichtbaar zijn via gitweb. Je kunt de "owner" (eigenaar) en "description" (omschrijving) voor gitweb vanuit de gitolite configuratie bestanden definiëren. Gitweb heeft een mechanisme beschikbaar waarmee toegang via HTTP wordt geïmplementeerd, deze kan je het "gecompileerde" config bestand van de gitolite config file laten gebruiken, wat inhoudt dat gitweb en gitolite dezelfde toegangsregels gebruikt (voor lees toegang). -**Spiegeling**: Gitolite kan je helpen met het onderhouden van meerdere spiegels, en er makkelijk tussen wisselen als de hoofdserver plat gaat. ## Git daemon ## -Voor publieke ongeverifieerde leestoegang tot je projecten zul je het HTTP protocol achter je willen laten, en overstappen op het Git protocol. De hoofdreden is snelheid. Het Git protocol is veel efficiënter en daarmee sneller dan het HTTP protocol, dus het zal je gebruikers tijd besparen. +Voor publieke ongeauthenticeerde leestoegang tot je projecten zul je het HTTP protocol achter je willen laten, en overstappen op het Git protocol. De belangrijkste reden is snelheid. Het Git protocol is veel efficiënter en daarmee sneller dan het HTTP protocol, dus het zal je gebruikstijd besparen. -Nogmaals, dit is voor ongeverifieerde alleen-lezen toegang. Als je dit op een server buiten je firewall draait, zul je het alleen moeten gebruiken voor projecten die voor de hele wereld toegankelijk moeten zijn. Als de server waarop je het draait binnen je firewall staat, zou je het kunnen gebruiken voor projecten waarbij een groot aantal mensen of computers (continue integratie of bouwservers) alleen-lezen toegang moeten hebben, waarbij je niet voor iedereen een SSH sleutel wilt toevoegen. +Nogmaals, dit is voor ongeauthenticeerde alleen-lezen toegang. Als je dit op een server buiten je firewall draait, zul je het alleen moeten gebruiken voor projecten die voor de hele wereld toegankelijk moeten zijn. Als de server waarop je het draait binnen je firewall staat, zou je het kunnen gebruiken voor projecten waarbij een groot aantal mensen of computers (continue integratie of bouwservers) alleen-lezen toegang moeten hebben, waarbij je niet voor iedereen een SSH sleutel wilt toevoegen. In ieder geval is het Git protocol relatief eenvoudig in te stellen. Eigenlijk is het enige dat je moet doen dit commando op een daemon manier uitvoeren: 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 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. +`--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 poort 9418 open moeten zetten op de machine waar je dit op gaat doen. -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 +Je kunt dit proces op een aantal manieren daemoniseren, afhankelijk van het besturingssystem waarop je draait. Op een Ubuntu machine, zul je een Upstart script gebruiken. Dus in het volgende bestand /etc/event.d/local-git-daemon @@ -714,18 +708,18 @@ stop je dit script: Omwille van veiligheidsredenen, wordt sterk aangeraden om deze daemon uit te voeren als gebruiker met alleen-lezen toegang op de repositories — je kunt dit makkelijk doen door een gebruiker 'git-ro' aan te maken en de daemon als deze uit te voeren. Om het eenvoudig te houden voeren we het als dezelfde 'git' gebruiker uit, als waarin Gitosis draait. -Als je je machine herstart, zal je Git daemon automatisch opstarten en herstarten als hij onderuit gaat. Om het te laten draaien zonder te herstarten, kun je dit uitvoeren: +Als je de machine herstart, zal de Git daemon automatisch opstarten en herstarten als de server onderuit gaat. Om het te laten draaien zonder te herstarten, kun je dit uitvoeren: initctl start local-git-daemon -Op andere systemen zul je misschien `xinetd` willen gebruiken, een script in je `sysvinit` systeem, of iets anders — zolang je dat commando maar ge-daemoniseerd krijgt en op een of andere manier in de gaten gehouden wordt. +Op andere systemen zul je misschien `xinetd` willen gebruiken, een script in je `sysvinit` systeem, of iets anders – zolang je dat commando maar ge-daemoniseerd krijgt en deze op een of andere manier in de gaten gehouden wordt. -Vervolgens zul je je Gitosis server moeten vertellen welke repositories je ongeverifieerde Gitserver gebaseerde toegang toestaat. Als je een sectie toevoegt voor iedere repository, dan kun je die repositories specificeren waarop je je Git daemon wilt laten lezen. Als je Git protocol toegang tot je iphone project wilt toestaan, dan voeg je dit toe aan het eind van het `gitosis.conf` bestand: +Vervolgens zul je je Gitosis server moeten vertellen welke repositories je onauthenticeerde Gitserver gebaseerde toegang toestaat. Als je een sectie toevoegt voor iedere repository, dan kun je die repositories specificeren waarop je je Git daemon wilt laten lezen. Als je Git protocol toegang tot je iphone project wilt toestaan, dan voeg je dit toe aan het eind van het `gitosis.conf` bestand: [repo iphone_project] daemon = yes -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 dat gecommit en gepushed is, dan zou de 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: @@ -751,15 +745,15 @@ Als je nu het project commit en pusht, start GitWeb automatisch met het tonen va ## Hosted Git ## -Als je niet door al het werk heen wilt om je eigen Git server op te zetten, heb je meerdere opties om je Git project op een externe speciale hosting pagina te laten beheren. Dit biedt een aantal voordelen: een ge-hoste pagina is over het algemeen snel in te stellen, en eenvoudig om projecten op te starten, en er komt geen server beheer en onderhoud bij kijken. Zelfs als je je eigen server intern ingesteld hebt, zul je misschien een publieke host pagina voor je open source broncode willen — dat is over het algemeen makkelijker voor de open source gemeenschap te vinden en je er mee te helpen. +Als je niet al het werk wilt doen om je eigen Git server op te zetten, heb je meerdere opties om je Git project op een externe speciale hosting pagina te laten beheren. Dit biedt een aantal voordelen: een ge-hoste pagina is over het algemeen snel in te stellen, eenvoudig om projecten mee op te starten, en er komt geen serverbeheer en -onderhoud bij kijken. Zelfs als je je eigen server intern ingesteld hebt, zul je misschien een publieke host pagina voor je open source broncode willen – dat is over het algemeen makkelijker voor de open source commune te vinden en je er mee te helpen. Vandaag de dag heb je een enorm aantal beheer opties om uit te kiezen, elk met verschillende voor- en nadelen. Om een recente lijst te zien, ga dan kijken op de volgende pagina : https://git.wiki.kernel.org/index.php/GitHosting -Omdat we ze niet allemaal kunnen behandelen, en ik toevallig bij een ervan werk, zullen we deze sectie gebruiken om door het instellen van een account en het opzetten van een project op GitHub lopen. Dit geeft je een idee van het benodigde werk. +Omdat we ze niet allemaal kunnen behandelen, en ik toevallig bij een ervan werk, zullen we deze paragraaf gebruiken het instellen van een account en het opzetten van een project op GitHub te doorlopen. Dit geeft je een idee van het benodigde werk. -GitHub is veruit de grootste open source Git beheer pagina en het is ook een van de weinige die zowel publieke als privé beheer opties biedt, zodat je je open source en commerciële privé code in dezelfde plaats kunt bewaren. Sterker nog, we hebben GitHub gebruikt om privé samen te werken aan dit boek. +GitHub is veruit de grootste open source Git beheer pagina en het is ook een van de weinige die zowel publieke als privé beheer opties biedt, zodat je je open source en commerciele privé code op dezelfde plaats kunt bewaren. Sterker nog, we hebben GitHub gebruikt om privé samen te werken aan dit boek. ### GitHub ### From f9a5a81ea1da72dfa309a46ff8e65666351ad120 Mon Sep 17 00:00:00 2001 From: Cor Date: Mon, 20 Jan 2014 13:33:17 +0100 Subject: [PATCH 126/690] [nl] Completed translating to Dutch, repaired a false "link" to "Simple Setups" section (that section does not exist) and made it point to the section where the ssh_keygen command is used.;sK --- nl/04-git-server/01-chapter4.markdown | 125 +++++++++++++------------- 1 file changed, 64 insertions(+), 61 deletions(-) diff --git a/nl/04-git-server/01-chapter4.markdown b/nl/04-git-server/01-chapter4.markdown index 9b2901a18..b05646106 100644 --- a/nl/04-git-server/01-chapter4.markdown +++ b/nl/04-git-server/01-chapter4.markdown @@ -1,6 +1,6 @@ # Git op de server # -Op dit punt zou je alledaagse taken waarvoor je Git zult gebruiken kunnen doen. Maar, om samen te kunnen werken in Git zul je een remote repository moeten hebben. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden, omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers de repository kunnen bereiken, zelfs als jouw computer van het netwerk is – het hebben van een betrouwbare gezamenlijke repository is vaak handig. De voorkeursmethode om met iemand samen te werken is om een tussenliggende repository in te richten waar beide partijen toegang to hebben en om daar naartoe te pushen en vandaan te pullen. We zullen deze repository de `Git server` noemen, maar je zult zien dat het over het algemeen maar een klein beetje systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. +Je zou nu de alledaagse taken waarvoor je Git zult gebruiken moeten kunnen uitvoeren. Echter, om enige vorm van samenwerking te hebben in Git is een remote repository nodig. Technisch gezien kun je wijzigingen pushen en pullen van individuele repositories, maar dat wordt afgeraden omdat je vrij gemakkelijk het werk waar anderen mee bezig zijn in de war kunt schoppen als je niet oppast. Daarnaast wil je dat je medewerkers de repository kunnen bereiken, zelfs als jouw computer van het netwerk is – het hebben van een betrouwbare gezamenlijke repository is vaak handig. De voorkeursmethode om met iemand samen te werken is om een tussenliggende repository in te richten waar beide partijen toegang tot hebben en om daar naartoe te pushen en vandaan te pullen. We zullen deze repository de `Git server` noemen, maar je zult zien dat het over het algemeen maar weinig systeembronnen kost om een Git repository te verzorgen, dus je zult er zelden een complete server voor nodig hebben. Een Git server draaien is eenvoudig. Als eerste kies je met welke protocollen je de server wilt laten communiceren. Het eerste gedeelte van dit hoofdstuk zullen we de beschikbare protocollen bespreken met de voor- en nadelen van elk. De daarop volgende paragrafen zullen we een aantal veel voorkomende opstellingen bespreken die van die protocollen gebruik maken en hoe je je server ermee kunt opzetten. Als laatste laten we een paar servers van derden zien, als je het niet erg vindt om je code op de server van een ander te zetten en niet het gedoe wilt hebben van het opzetten en onderhouden van je eigen server. @@ -16,7 +16,7 @@ Het is belangrijk om op te merken dat, met uitzondering van de HTTP protocollen, ### Lokaal protocol ### -Het simpelste is het _Lokale protocol_, waarbij de remote repository in een andere directory op de schijf staat. Deze opzet wordt vaak gebruikt als iedereen in het team toegang heeft op een gedeeld bestandssyteem zoals een NFS mount, of in het weinig voorkomende geval dat iedereen op dezelfde computer werkt. Het laatste zou niet ideaal zijn, want dan zouden alle repositories op dezelfde computer staan, zodat een fataal verlies van gegevens veel groter wordt. +Het simpelste is het _Lokale protocol_, waarbij de remote repository in een andere directory op de schijf staat. Deze opzet wordt vaak gebruikt als iedereen in het team toegang heeft op een gedeeld bestandssyteem zoals een NFS mount, of in het weinig voorkomende geval dat iedereen op dezelfde computer werkt. Het laatste zou niet ideaal zijn, want dan zouden alle repositories op dezelfde computer staan, zodat de kans op een fataal verlies van gegevens veel groter wordt. Als je een gedeeld bestandssyteem hebt, dan kun je clonen, pushen en pullen van een op een lokaal bestand aanwezige 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 het volgende uitvoeren: @@ -26,7 +26,7 @@ Of je kunt dit doen: $ git clone file:///opt/git/project.git -Git werkt iets anders als je explicite `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gesproken gebruikt om data te transporteren over een netwerk, wat over het algemeen een minder efficiënte methode is om gegevens over te dragen. De belangrijkste reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de vreemde refenties of objecten eruit gelaten – over het algemeen na een import uit een ander versiebeheer systeem of iets dergelijks (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. +Git werkt iets anders als je explicite `file://` aan het begin van de URL zet. Als je alleen het pad specificeert, probeert Git hardlinks te gebruiken, of het kopieert de bestanden die het nodig heeft. Als je `file://` specificeert, dan start Git de processen die het normaal gesproken gebruikt om data te transporteren over een netwerk, wat over het algemeen een minder efficiënte methode is om gegevens over te dragen. De belangrijkste reden om `file://` wel te specificeren is als je een schone kopie van de repository wilt met de vreemde referenties of objecten eruit gelaten – over het algemeen na een import uit een ander versiebeheer systeem of iets dergelijks (zie Hoofdstuk 9 voor onderhoudstaken). We zullen het normale pad hier gebruiken, omdat het bijna altijd sneller is om het zo te doen. Om een lokale repository aan een bestaand Git project toe te voegen, kun je iets als het volgende uitvoeren: @@ -38,7 +38,7 @@ Daarna kun je op gelijke wijze pushen naar, en pullen van die remote als je over De voordelen van bestands-gebaseerde repositories zijn dat ze eenvoudig zijn en ze maken gebruik van bestaande bestandspermissies en netwerk toegang. Als je al een gedeeld bestandssysteem hebt, waar het hele team al toegang toe heeft, dan is een repository opzetten heel gemakkelijk. Je stopt de kale repository ergens waar iedereen gedeelde toegang tot heeft, en stelt de lees- en schrijfrechten in zoals je dat bij iedere andere gedeelde directory zou doen. In de volgende paragraaf "Git op een Server Krijgen" bespreken we hoe je een kopie van een kale repository kunt exporteren voor dit doeleinde. -Dit is ook een prettige optie om snel werk uit een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project werken, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan dat hij naar een remote server moet pushen, en jij er van moet pullen. +Dit is ook een prettige optie om snel werk uit een repository van iemand anders te pakken. Als jij en een collega aan hetzelfde project werken, en hij wil dat je iets bekijkt, dan is het uitvoeren van een commando zoals `git pull /home/john/project` vaak makkelijker dan wanneer hij naar een remote server moet pushen, en jij er van moet pullen. #### De nadelen #### @@ -62,15 +62,15 @@ Je kunt ook de gebruiker weglaten, en Git gebruikt gegevens van de gebruiker waa #### De voordelen #### -Er zijn vele voordelen om SSH te gebruiken. Ten eerste moet je het eigenlijk wel gebruiken als je geauthenticeerde schrijftoegang op je repository via een netwerk wilt. Ten tweede is het relatief eenvoudig in te stellen – SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig – alle data transporten zijn versleuteld en geauthenticeerd. En als laatste is SSH efficiënt, net zoals het Git en lokale protocol, de gegevens worden zo compact mogelijk gemaakt voordat het getransporteerd wordt. +Er zijn vele voordelen om SSH te gebruiken. Ten eerste moet je het eigenlijk wel gebruiken als je geauthenticeerde schrijftoegang op je repository via een netwerk wilt. Ten tweede is het relatief eenvoudig in te stellen – SSH daemons komen veel voor, veel systeembeheerders hebben er ervaring mee, en veel operating systemen zijn er mee uitgerust of hebben applicaties om ze te beheren. Daarnaast is toegang via SSH veilig – alle data transporten zijn versleuteld en geauthenticeerd. En als laatste is SSH efficiënt, net zoals bij het Git en lokale protocol worden de gegevens zo compact mogelijk gemaakt voordat het getransporteerd wordt. #### De nadelen #### -Het negatieve aspect van SSH is dat je er geen anonieme toegang naar je repository over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken, zelfs als het alleen lezen is, zodat SSH toegang niet bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, dan is SSH misschien het enige protocol waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. +Het negatieve aspect van SSH is dat je er geen anonieme toegang naar je repository over kunt geven. Mensen moeten via SSH toegang hebben om er gebruik van te kunnen maken zelfs als het alleen lezen is, dit maakt dat SSH toegang niet echt bevordelijk is voor open source projecten. Als je het alleen binnen je bedrijfsnetwerk gebruikt, is SSH wellicht het enige protocol waar je mee in aanraking komt. Als je anonieme alleen-lezen toegang wilt toestaan tot je projecten, dan moet je SSH voor jezelf instellen om over te pushen, maar iets anders voor anderen om over te pullen. ### Het Git protocol ### -Het volgende is het Git protocol. Dit is een specifieke daemon, die met Git meegeleverd wordt; het luistert op een toegewezen poort (9418), en verleent een vergelijkbare dienst als het SSH protocol, maar dan zonder enige vorm van authenticatie. Om een repository beschikbaar te stellen over het Git protocol, moet je een `git-export-daemon-ok` bestand aanmaken – de daemon zal een repository zonder dit bestand erin niet verspreiden – maar daarbuiten is er geen beveiliging. De Git repository beschikbaar om gecloned te kunnen worden door iedereen, of het is het niet. Dit betekent dat er over het algemeen geen pushing is via dit protocol. Je kunt push toegang aanzetten, maar gegeven het gebrek aan authenticatie kan als je de push toegang aan zet iedereen die de URL van jouw project op het internet vindt, pushen naar jouw project. We volstaan met te zeggen dat dit zelden de bedoeling kan zijn. +Het volgende is het Git protocol. Dit is een specifieke daemon, die met Git meegeleverd wordt. Het luistert op een toegewezen poort (9418), en verleent een vergelijkbare dienst als het SSH protocol, maar dan zonder enige vorm van authenticatie. Om een repository beschikbaar te stellen over het Git protocol, moet je een `git-export-daemon-ok` bestand aanmaken – de daemon zal een repository zonder dit bestand erin niet verspreiden – maar daarbuiten is er geen beveiliging. De Git repository is beschikbaar om gecloned te kunnen worden door iedereen, of het is het niet. Dit betekent dat er over het algemeen geen pushing is via dit protocol. Je kunt push toegang aanzetten maar gegeven het gebrek aan authenticatie kan, als je de push toegang aan zet, iedereen die de URL van jouw project op het internet vindt pushen naar jouw project. We volstaan met te zeggen dat dit zelden de bedoeling kan zijn. #### De voordelen #### @@ -79,7 +79,7 @@ Het Git protocol is het snelste dat beschikbaar is. Als je veel verkeer verwerkt #### De nadelen #### Het nadeel van het Git protocol is het gebrek aan authenticatie. Het is over het algemeen onwenselijk dat het Git protocol de enige toegang tot je project is. Meestal zul je het samen met SSH toegang gebruiken voor de paar ontwikkelaars die push (schrijf-)toegang hebben en de rest laat je `git://` voor alleen leestoegang gebruiken. -Het is waarschijnlijk ook het meest ingewikkelde protocol om in te richten. Het moet een eigen daemon hebben, die speciaal voor die situatie ingericht is – we zullen er een instellen in het "Gitosis" gedeelte van dit hoofdstuk – het gebruikt `xinetd` configuratie of iets vergelijkbaars, wat ook niet altijd eenvoudig is op te zetten. Daarbij is ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat in bedrijfsfirewalls is opengezet. Bij firewalls van grote bedrijven, is deze ongebruikelijke poort meestal dichtgezet. +Het is waarschijnlijk ook het meest ingewikkelde protocol om in te richten. Het moet een eigen daemon hebben, die speciaal voor die situatie ingericht is – we zullen er een instellen in de "Gitosis" paragraaf van dit hoofdstuk – het gebruikt `xinetd` configuratie of iets vergelijkbaars, wat ook niet altijd eenvoudig is op te zetten. Daarbij is ook firewall toegang tot poort 9418 nodig, wat geen standaard poort is dat in bedrijfsfirewalls is opengezet. Bij firewalls van grote bedrijven, is deze ongebruikelijke poort meestal dichtgezet. ### Het HTTP/S protocol ### @@ -91,41 +91,41 @@ 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 geleverd wordt, voert het noodzakelijke commando uit (`git update-server-info`) om HTTP fetching en cloning goed werkend te krijgen en houden. Dit commando wordt uitgevoerd als je via SSH naar deze repository pushed; en andere mensen kunnen clonen met behulp van zoiets als +Dat is alles. De `post-update` hook, die standaard bij Git geleverd wordt, voert het noodzakelijke commando uit (`git update-server-info`) om HTTP fetching en cloning goed werkend te krijgen en houden. Dit commando wordt uitgevoerd als je via SSH naar deze repository pushed, en andere mensen kunnen clonen met behulp van zoiets als $ git clone http://example.com/gitproject.git In dit specifieke voorbeeld gebruiken we het `/var/www/htdocs` pad wat gebruikelijk is voor Apache opstellingen, maar je kunt iedere statische webserver gebruiken – stop de kale repository in het betreffende pad. De Git data wordt geserveerd als standaard statische bestanden (zie hoofdstuk 9 voor details over hoe het precies geserveerd wordt). -Het is mogelijk om Git ook over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en het vraagt dat je complexe WebDAV instellingen inricht. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek beschrijven. Als je geïnteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Het aardige van Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken, zonder specifieke Git funtionaliteit, dus je kunt deze functionaliteit gebruiken als je web-hosting provider WebDAV ondersteunt voor het maken van wijzigingen aan je webpagina. +Het is mogelijk om Git ook over HTTP te laten pushen, alhoewel dat geen veelgebruikte techniek is en het vereist dat je complexe WebDAV instellingen inricht. Omdat het zelden gebruikt wordt, zullen we het niet in dit boek behandelen. Als je geïnteresseerd bent om de HTTP-push protocollen te gebruiken, dan kun je op `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` lezen hoe je een repository kunt maken. Het aardige van Git laten pushen over HTTP is dat je iedere WebDAV server kunt gebruiken zonder specifieke Git funtionaliteit, dus je kunt deze optie gebruiken als je web-hosting provider WebDAV ondersteunt voor het maken van wijzigingen aan je webpagina. #### De voordelen #### -Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren is alles wat er moet gebeuren om de wereld leestoegang te geven tot je Git repository. Het neemt maar een paar minuten van je tijd. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te verspreiden - een normale Apache server kan gemiddeld duizenden bestanden zenden per seconde - is het moeilijk om zelfs een kleine server te overbelasten. +Het voordeel van het gebruik van het HTTP protocol is dat het eenvoudig in te stellen is. Een handvol benodigde commando's uitvoeren is alles wat er moet gebeuren om de wereld leestoegang te geven tot je Git repository. Het neemt maar een paar minuten van je tijd. Het HTTP protocol is niet erg belastend voor de systeembronnen van je server. Omdat het over het algemeen een statische webserver gebruikt om alle data te verspreiden is het moeilijk om zelfs een kleine server te overbelasten - een normale Apache server kan gemiddeld duizenden bestanden zenden per seconde. -Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat inhoudt dat je het transport kunt versleutelen; je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat laat gebruiken. Normaal gesproken als je je deze moeite wilt getroosten, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan in jouw specifieke geval een betere oplossing zijn om gesigneerde SSL certificaten of andere HTTP-gebaseerde authenticatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. +Je kunt ook je repositories alleen-lezen serveren via HTTPS, wat inhoudt dat je het gegevenstransport kunt versleutelen; je kunt zelfs zover gaan dat je clients een specifiek gesigneerd SSL certificaat laat gebruiken. Normaal gesproken als je je deze moeite wilt getroosten, dan is het makkelijker om publieke SSH sleutels te gebruiken; maar het kan in jouw specifieke geval een betere oplossing zijn om gesigneerde SSL certificaten of andere HTTP-gebaseerde authenticatie methoden te gebruiken voor alleen-lezen toegang via HTTPS. Een andere prettige bijkomstigheid is dat HTTP een dusdanig veel voorkomend protocol is dat bedrijfsfirewalls vaak zo ingesteld zijn dat ze verkeer via deze poort toestaan. #### De nadelen #### -Het nadeel van je repository verspreiden 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 veel hogere netwerk belasting en transport volume via HTTP dan met elk van de andere netwerk protocollen. Omdat het niet zo ingewikkeld is om alleen de data te versturen die je nodig hebt – er wordt geen dynamisch werk door de server gedaan in deze uitwisselingen – 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 verspreiden 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 veel hogere netwerk belasting en transport volume via HTTP dan met elk van de andere netwerk protocollen. Omdat het niet zo slim is om eerst te bepalen van welke gegevens het nodig is te versturen – er wordt geen dynamisch werk door de server gedaan in deze uitwisselingen – wordt vaak naar het HTTP protocol gerefereerd als het _domme_ 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 Git server initieel op te zetten, moet je een bestaande repository naar 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 conventie eindigen de namen van kale repository mappen met `.git`, zoals: +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 conventie eindigen de namen van kale repository mappen met `.git`, zoals hier: $ git clone --bare my_project my_project.git Initialized empty Git repository in /opt/projects/my_project.git/ -De uitvoer van dit commando is een beetje verwarrend. Omdat `clone` eigenlijk een `git init` en dan een `git fetch` is, zien we de uitvoer van het `git init` gedeelte, wat een lege map aanmaakt. De eigenlijke object overdracht geeft geen output, maar het gebeurt wel. Nu zou je een kopie van de Git map data in je `my_project.git` map moeten hebben. +De output van dit commando is een beetje verwarrend. Het commando `clone` is eigenlijk een `git init` en dan een `git fetch`, wat we hier zien is de output van het `git init` gedeelte wat een lege map aanmaakt. De eigenlijke object overdracht geeft geen output, maar het gebeurt wel. Nu zou je een kopie van de Git map data in je `my_project.git` map moeten hebben. Dit is ongeveer gelijk aan $ cp -Rf my_project/.git my_project.git -Er zijn een paar kleine verschillen in het configuratie bestand, maar het komt op hetzelfde neer. Het neemt de Git repository zelf, zonder een werkmap, en maakt een map aan specifiek hiervoor. +Er zijn een paar kleine verschillen in het configuratie bestand, maar het komt op hetzelfde neer. Het neemt de Git repository zelf, zonder een werkmap, en maakt een directory specifiek hiervoor aan. ### De Kale Repository op een Server Zetten ### @@ -505,25 +505,27 @@ Als je problemen hebt, kan het handig zijn om `loglevel=DEBUG` onder de `[gitosi ## Gitolite ## -Merk op: de laatste versie van deze paragraaf in het ProGit boek is altijd beschikbaar binnen de [gitolite documentation][gldpg]. De auteur geeft ook nederig aan dat, hoewel deze paragraaf accuraat is, het *kan* (en vaak ook *is*) gebruikt om gitolie te installeren zonder enige andere documentatie te lezen, dat het niet gegarandeerd compleet is, en het zeker niet de gehele enorme hoeveelheid documentatie kan vervangen dat meegeleverd wordt met gitolite. +Merk op: de laatste versie van deze paragraaf in het ProGit boek is altijd beschikbaar binnen de [gitolite documentation][gldpg]. De auteur geeft ook nederig aan dat, hoewel deze paragraaf accuraat is, het *kan* (en vaak ook *is*) worden gebruikt om gitolite te installeren zonder enige andere documentatie te lezen, maar dat je er vanuit mag gaan dat het niet compleet is, en het zeker niet de gehele enorme hoeveelheid documentatie kan vervangen dat meegeleverd wordt met gitolite. [gldpg]: http://github.com/sitaramc/gitolite/blob/pu/doc/progit-article.mkd -Git begint erg populair te worden in het bedrijfsleven, die de neiging hebben nog wat additionele eisen te hebben op het gebied van toegangscontrole. Gitolite was oorspronkelijk gemaakt om bij het vervullen van deze eisen te helpen, maar het blijkt dat het even bruikbaar is in de wereld van de open source: het Fedora Project beheert toegang tot hun package beheer repositories (meer dan 10.000 daarvan!) met gitolite, en het is waarschijnlijk daarbij ook nog eens de grootste gitolite installatie waar dan ook. +Git begint erg populair te worden in het bedrijfsleven, die de neiging heeft nog wat additionele eisen te hebben op het gebied van toegangscontrole. Gitolite was oorspronkelijk gemaakt om bij het vervullen van deze eisen te helpen, maar het blijkt dat het even bruikbaar is in de wereld van de open source: het Fedora Project beheert toegang tot hun package beheer repositories (meer dan 10.000 daarvan!) met gitolite, en het is daarbij waarschijnlijk ook nog eens de grootste gitolite installatie waar dan ook. Gitolite stelt je in staat de permissies niet alleen per repository, maar ook per branch of tag naam binnen elke repository. Dus, je kunt aangeven dat bepaalde mensen (of groepen van mensen) alleen maar bepaalde "refs" (branches of tags) kunnen pushen maar niet andere. ### Installatie ### -Het installeren van Gitolite is zeer eenvoudig, zelfs als je de uitgebreide documentatie, dat erbij geleverd wordt, niet leest. Je hebt een account op een Unix(achtige) server hebben; verschillende Linux smaken en Solaris 10 zijn getest. Je hebt geen root toegang nodig, aangenomen dat git, perl, en een openssh compatible ssh server al zijn geïnstalleerd. In de onderstaand voorbeelden zullen we het `gitolite` account gebruiken op een host genaamd `gitserver`. +Het installeren van Gitolite is zeer eenvoudig, zelfs als je de uitgebreide documentatie, dat erbij geleverd wordt, niet leest. Je hebt een account op een Unix(achtige) server nodig; verschillende Linux smaken en Solaris 10 zijn getest. Je hebt geen root toegang nodig, aangenomen dat git, perl, en een openssh compatible ssh server al zijn geïnstalleerd. In de onderstaande voorbeelden zullen we het `gitolite` account gebruiken op een host genaamd `gitserver`. -Gitolite is nogal ongebruikelijk in de zin van "server" software -- toegang gaat via ssh, en elke userid op de server is in potentie een "gitolite host". Het resultaat is, dat er een idee is van "installeren" van de software zelf, en dan het "opzetten" van een gebruiker als een "gitolist host". +Gitolite is nogal ongebruikelijk in de zin van "server" software -- toegang gaat via ssh, en elke userid op de server is in potentie een "gitolite host". Met als gevolg dat er een notie is van "installeren" van de software zelf, en dan het "opzetten" van een gebruiker als een "gitolist host". -Mensen zonder root toegang kunnen het installeren binnen hun eigen user id. Als laatste: gitlite kan geïnstalleerd worden door een script te starten *op het werkstation*, vanuit een bash-shell. (Zelfs de bash die meegeleverd wordt met msysgit volstaat, voor het geval je je dat afvroeg.) +Gitolite heeft 4 wijzen van installeren. Mensen die Fedora of Debian systemen gebruiken kunnen een RPM of DEB ophalen en deze installeren. Mensen met root toegang kunnen het handmatig installeren. Met deze twee methoden kan elke gebruiker op het systeem een "gitolite host" worden. + +Mensen zonder root toegang kunnen het installeren binnen hun eigen user id. En als laatste: gitlite kan geïnstalleerd worden door een script te starten *op het werkstation*, vanuit een bash-shell. (Zelfs de bash die meegeleverd wordt met msysgit volstaat, voor het geval je je dat afvroeg.) We zullen dit laatste in dit stuk beschrijven, voor de overige methoden verwijzen we je naar de documentatie. -Je begint met het verkrijgen van toegang op basis van een publieke sleutel, zodat je vanaf je werkstation op de server kan inloggen zonder het intypen van je wachtwoord. De volgende methode werkt op Linux; voor andere werkstation besturingssystemen moet je dit wellicht handmatig doen. We gaan er vanuit dat je al een sleutelpaar hebt gegenereerd met `ssh-keygen`. +Je begint met het verkrijgen van toegang naar je server op basis van een publieke sleutel, zodat je vanaf je werkstation op de server kan inloggen zonder het intypen van je wachtwoord. De volgende methode werkt op Linux; voor andere werkstation besturingssystemen moet je dit wellicht handmatig doen. We gaan er vanuit dat je al een sleutelpaar hebt gegenereerd met `ssh-keygen`. $ ssh-copy-id -i ~/.ssh/id_rsa gitolite@gitserver @@ -538,11 +540,11 @@ Vervolgens, clone je Gitolite van de hoofdsite van het project en roept de "easy $ cd gitolite/src $ ./gl-easy-install -q gitolite gitserver sitaram -En dat is het! Gitolite is nu geïnstalleerdop je server, en je hebt nu een gloednieuwe repository genaamd `gitolite-admin` in de home directory van jouw werkstation. Je beheert je gitolite setup door een wijziging aan te brengen in deze reporitory en deze te pushen. +En dat is het! Gitolite is nu geïnstalleerd op je server, en je hebt nu een gloednieuwe repository genaamd `gitolite-admin` in de home directory van jouw werkstation. Je beheert je gitolite setup door een wijziging aan te brengen in deze reporitory en deze te pushen. -Dat laatste commando produceert nogal een hoeveelheid uitvoer dat wellicht interessant is om te lezen. Ook wordt er, de eerste keer dat je het laat lopen, er een nieuwe sleutelpaar gemaakt; je moet een wachtwoord kiezen of Enter als je er geen wilt. Waarom een tweede sleutelpaar nodig is, en hoe deze wordt gebruikt, wordt uitgelegd in het "ssh troubleshooting" document dat bij Gitolite wordt meegeleverd. (Hey, de documentatie moet *ergens* goed voor zijn!) +Dat laatste commando produceert redelijk wat uitvoer, dat wellicht interessant is om te lezen. Ook wordt er, de eerste keer dat je het commando laat lopen, er een nieuwe sleutelpaar gemaakt; je moet een wachtwoord kiezen of Enter als je er geen wilt. Waarom een tweede sleutelpaar nodig is, en hoe deze wordt gebruikt, wordt uitgelegd in het "ssh troubleshooting" document dat bij Gitolite wordt meegeleverd. (Hey, de documentatie moet *ergens* goed voor zijn!) -Repositories genaamd `gitolite-admin` en `testing` worden standaard op de server aangemaakt. Als je een van beide lokaal wilt clonen (van een account die SSA console toegang heeft naar het gitolite account via *authorized_keys*) type je: +Repositories genaamd `gitolite-admin` en `testing` worden standaard op de server aangemaakt. Als je een van beide lokaal wilt clonen (van een account die SSH console toegang heeft naar het gitolite account via *authorized_keys*) type je: $ git clone gitolite:gitolite-admin $ git clone gitolite:testing @@ -558,7 +560,7 @@ Hoewel de standaard, snelle, installatie werkt voor de meeste mensen, zijn er ee ### Config bestand en Beheer van Toegangsregels ### -Op het moment dat de installatie afgerond is, schakel je over naar de `gitolite-admin` repository (staat in je HOME directory) en begin je rond te snuffelen om te zien wat je daar hebt: +Zodra de installatie afgerond is, schakel je over naar de `gitolite-admin` repository (die staat in je HOME directory) en begin je rond te snuffelen om te zien wat je daar hebt: $ cd ~/gitolite-admin/ $ ls @@ -580,7 +582,7 @@ Merk op dat "sitaram" (het laatste argument in het `gl-easy-install` commando da De syntax van het config bestand voor gitolite is ruimhartig van documentatie voorzien in `conf/example.conf`, dus we zullen alleen wat hoofdpunten benoemen. -Je kunt voor het gemak gebruikers of repositories groeperen. De groepnamen zijn vergelijkbaar met macros; als je ze definieert maakt het niet uit of het projecten of gebruikers zijn, dat onderscheid wordt pas gemaakt als je de "macro" gaat *gebruiken*. +Je kunt voor het gemak gebruikers of repositories groeperen. De groepnamen zijn vergelijkbaar met macros: als je ze definieert maakt het niet uit of het projecten of gebruikers zijn. Dat onderscheid wordt pas gemaakt als je de "macro" gaat *gebruiken*. @oss_repos = linux perl rakudo git gitolite @secret_repos = fenestra pear @@ -598,9 +600,9 @@ Je kunt de permissies beheren op het "ref" niveau. In het volgende voorbeeld kun RW refs/tags/rc[0-9] = @engineers RW+ = @admins -De expressie achter de `RW` of `RW+` is een zgn. regular expression (regex) waartegen de refname (ref) die wordt gepushed wordt vergeleken. Dus we noemen het natuurlijk een "refex"! En natuurlijk kan een refex veel krachtiger zijn dan hier wordt getoond, dus ga het niet overdrijven als je niet al te goed in de perl regexen zit. +De expressie achter de `RW` of `RW+` is een zgn. regular expression (regex) waartegen de refname (ref) die wordt gepushed wordt vergeleken. Dus we gaan we deze uiteraard een "refex" noemen! En natuurlijk kan een refex veel krachtiger zijn dan hier wordt getoond, dus ga het niet overdrijven als je niet al te goed in de perl regexen zit. -Zoals je wellicht al geraden hebt, prefixed Gitolite `refs/heads/` als een syntactische handigheid als de refex niet begint met `refs/`. +Zoals je wellicht al geraden hebt, gebruikt Gitolite de prefix `refs/heads/` als een syntactische handigheid indien de refex niet begint met `refs/`. Een belangrijke eigenschap van de syntax van het config bestand is dat alle regels van een repository niet op één plek hoeft te staan. Je kunt al het generieke spul bij elkaar houden, zoals de regels voor alle `oss_repos` zoals ze hier boven staan, en dan op een latere plaats specifieke regels voor specifieke gevallen, zoals hier: @@ -611,13 +613,13 @@ Deze regel wordt gewoon toegevoegd aan de set met regels voor de `gitolite` repo Je zou je op dit punt kunnen afvragen hoe de toegangsregels eigenlijk worden toegepast, laten we dat kort behandelen. -Er zijn twee niveaus van toegangsbeheer in gitolite. De eerste is op repository niveau. Als je lees (of schrijf)rechten hebt tot *enige* ref in de repository, dan heb je lees (of schrijf) rechten tot de repository. +Er zijn twee niveaus van toegangsbeheer in gitolite. De eerste is op repository niveau. Als je lees- of schrijfrechten hebt tot *enige* ref in de repository, dan heb je lees (of schrijf) rechten tot de repository. -Het tweede niveau, alleen van toepassing voor "schrijf" toegang, is per branch of tag binnen een repository. De gebruikersnaam, het type toegang wat wordt gevraagd (`W` of '+'), en de refname dat wordt gewijzigd (update) zijn bekend. De toegangsregels worden gecontroleerd in volgorde van voorkomst in het config bestand, en er wordt gekeken naar een treffer voor deze combinatie (maar onthoudt dat de refname middels een regex wordt vergeleken, niet een simpele string-vergelijking). Als er een treffer is, dan slaagt de push. Als er geen treffer wordt gevonden (fallthrough) dan wordt toegang geweigerd. +Het tweede niveau, alleen van toepassing voor "schrijf" toegang, is per branch of tag binnen een repository. De gebruikersnaam, het type toegang wat wordt gevraagd (`W` of '+'), en de refname dat wordt gewijzigd (geüpdate) zijn bekend. De toegangsregels worden gecontroleerd in volgorde van voorkomst in het config bestand, en er wordt gekeken naar een treffer voor deze combinatie (maar onthoudt dat de refname middels een regex wordt vergeleken, niet een simpele string-vergelijking). Als er een treffer is, dan slaagt de push. Als er geen treffer wordt gevonden (fallthrough) dan wordt toegang geweigerd. ### Geavanceerde Toegangs Controle met "deny" regels ### -Tot zover hebben we alleen permissies gezien uit het rijtje `R`, `RW` of `RW+`. Echter, gitolite kent een andere permissie: `-`, wat staat voor "deny" (ontken). Dit geeft je veel meer macht, tegen kosten van wat hogere complexiteit omdat een fallthrough nu niet de *enige* manier is waarop toegang kan worden geweigerd, wordt *de volgorde van regels belangrijk*! +Tot zover hebben we alleen permissies gezien uit het rijtje `R`, `RW` of `RW+`. Echter, gitolite kent een andere permissie: `-`, wat staat voor "deny" (ontken). Dit geeft je veel meer macht, tegen kosten van wat hogere complexiteit omdat een fallthrough nu niet de *enige* manier is waarop toegang kan worden geweigerd; nu wordt *de volgorde van regels belangrijk*! Stel dat, in de onderstaande situatie, we de techneuten in staat willen stellen elke branch te laten terugdraaien *behalve* master en integ. Dit is de manier om dat te doen: @@ -658,11 +660,11 @@ Gitolite laat je repositories specificeren met wildcards (eigenlijk perl regex e We ronden deze uiteenzetting af met een passe partout van andere eigenschappen, welke alle (en nog vele andere) tot in de kleinste detail zijn beschreven in de "faqs, tips, etc" en andere documenten. -**Logging**: Gitolite logt alle succesvolle toegangspogingen. Als je wat te los bent geweest in het toekennen van terugdraai permissies (`RW+`) en een of andere nozem heeft "master" vernaggelt, is de log-file een redder in de nood in de zin van snel en eenvoudig achterhalen van de SHA die verdwenen is. +**Logging**: Gitolite logt alle succesvolle toegangspogingen. Als je wat te los bent geweest in het toekennen van terugdraai permissies (`RW+`) en een of andere bijdehand heeft "master" vernaggelt, is de log-file een redder in de nood in de zin van snel en eenvoudig achterhalen van de SHA die verdwenen is. -**Git buiten reguliere PATH**: Een ontzettend handige eigenschap in gitolite is het ondersteunen van git buiten het regulier `$PATH` (dit komt vaker voor dan je zou denken, sommige bedrijfs omgevingen of zelfs sommige hosting providers weigeren dingen systeem-breed te installeren en je eindigt ermee dat je ze in je eigen directories zet). Normaalgesproken ben je gedwongen git aan de *client-side* op de een of andere manier te vertellen van deze niet-standaard locatie van de git binaries. Met gitolite hoe je alleen een verbose installatie te kiezen en `$GIT_PATH` in de "rc" bestanden in te vullen. Hierna geen wijzigingen aan de kant van de clients nodig :-) +**Git buiten reguliere PATH**: Een ontzettend handige eigenschap in gitolite is het ondersteunen van Git buiten het regulier `$PATH` (dit komt vaker voor dan je zou denken, sommige bedrijfs omgevingen of zelfs sommige hosting providers weigeren dingen systeem-breed te installeren en je eindigt ermee dat je ze in je eigen directories zet). Normaalgesproken ben je gedwongen Git aan de *client-side* op de een of andere manier te vertellen van deze niet-standaard locatie van de git binaries. Met gitolite hoe je alleen een verbose installatie te kiezen en `$GIT_PATH` in de "rc" bestanden in te vullen. Hierna geen wijzigingen aan de kant van de clients nodig :-) -**Rapportage van toegangsrechten**: Nog zo'n handige eigenschap is wat er gebeurt als je gewoon met ssh naar de server gaat. Gitolite laat zien welke repositories je toegang toe hebt en welke soort toegang dat dan wel is. Hier is een voorbeeld: +**Rapportage van toegangsrechten**: Nog zo'n handige eigenschap is wat er gebeurt als je gewoon met ssh naar de server gaat. Gitolite laat zien welke repositories je toegang toe hebt en welke soort toegang dat dan is. Hier is een voorbeeld: hello sitaram, the gitolite version here is v1.5.4-19-ga3397d4 the gitolite config gives you the following access: @@ -674,14 +676,15 @@ We ronden deze uiteenzetting af met een passe partout van andere eigenschappen, R indic_web_input R shreelipi_converter -**Delegeren**: Voor extreem grote installaties kan je de verantwoordelijkheid voor groepen van repositories delegeren aan verschilllende mensen en hen het beheer van die delen onafhankelijk laten regelen. Dit vermindert de werkdruk van de hoofd-beheerder, en maakt van hem minder een faalpunt. Deze eigenschap heeft zijn eigen docuentatie bestand in de `doc/` directory. +**Delegeren**: Voor extreem grote installaties kan je de verantwoordelijkheid voor groepen van repositories delegeren aan verschillende mensen en hen het beheer van die delen onafhankelijk laten regelen. Dit vermindert de werkdruk van de hoofd-beheerder, en maakt van hem minder een faalpunt. Deze eigenschap heeft zijn eigen documentatie in de `doc/` directory. -**Gitweb ondersteuning**: Gitolite ondersteunt gitweb op verschillende manieren. Je kunt aangeven welke repositories zichtbaar zijn via gitweb. Je kunt de "owner" (eigenaar) en "description" (omschrijving) voor gitweb vanuit de gitolite configuratie bestanden definiëren. Gitweb heeft een mechanisme beschikbaar waarmee toegang via HTTP wordt geïmplementeerd, deze kan je het "gecompileerde" config bestand van de gitolite config file laten gebruiken, wat inhoudt dat gitweb en gitolite dezelfde toegangsregels gebruikt (voor lees toegang). +**Gitweb ondersteuning**: Gitolite ondersteunt gitweb op verschillende manieren. Je kunt aangeven welke repositories zichtbaar zijn via gitweb. Je kunt de "owner" (eigenaar) en "description" (omschrijving) voor gitweb vanuit de gitolite configuratie bestanden definiëren. Gitweb heeft een mechanisme beschikbaar waarmee toegang via HTTP wordt geïmplementeerd, deze kan je het "gecompileerde" config bestand van de gitolite config file laten gebruiken, wat inhoudt dat gitweb en gitolite dezelfde toegangsregels gebruiken (voor lees toegang). +**Mirroring**: Gitolite kan je ondersteunen bij het beheren van meerdere mirrors, en het eenvoudig daartussen overschakelen als de primaire server uitvalt. ## Git daemon ## -Voor publieke ongeauthenticeerde leestoegang tot je projecten zul je het HTTP protocol achter je willen laten, en overstappen op het Git protocol. De belangrijkste reden is snelheid. Het Git protocol is veel efficiënter en daarmee sneller dan het HTTP protocol, dus het zal je gebruikstijd besparen. +Voor publieke ongeauthenticeerde leestoegang tot je projecten zul je het HTTP protocol achter je willen laten, en overstappen op het Git protocol. De belangrijkste reden is snelheid. Het Git protocol is veel efficiënter en daarmee sneller dan het HTTP protocol, dus het zal je gebruikers tijd besparen. Nogmaals, dit is voor ongeauthenticeerde alleen-lezen toegang. Als je dit op een server buiten je firewall draait, zul je het alleen moeten gebruiken voor projecten die voor de hele wereld toegankelijk moeten zijn. Als de server waarop je het draait binnen je firewall staat, zou je het kunnen gebruiken voor projecten waarbij een groot aantal mensen of computers (continue integratie of bouwservers) alleen-lezen toegang moeten hebben, waarbij je niet voor iedereen een SSH sleutel wilt toevoegen. @@ -706,7 +709,7 @@ stop je dit script: /opt/git/ respawn -Omwille van veiligheidsredenen, wordt sterk aangeraden om deze daemon uit te voeren als gebruiker met alleen-lezen toegang op de repositories — je kunt dit makkelijk doen door een gebruiker 'git-ro' aan te maken en de daemon als deze uit te voeren. Om het eenvoudig te houden voeren we het als dezelfde 'git' gebruiker uit, als waarin Gitosis draait. +Omwille van veiligheidsredenen, wordt sterk aangeraden om deze daemon uit te voeren als gebruiker met alleen-lezen toegang op de repositories – je kunt dit makkelijk doen door een nieuwe gebruiker 'git-ro' aan te maken en de daemon als deze uit te voeren. Om het eenvoudig te houden voeren we het als dezelfde 'git' gebruiker uit, als waarin Gitosis draait. Als je de machine herstart, zal de Git daemon automatisch opstarten en herstarten als de server onderuit gaat. Om het te laten draaien zonder te herstarten, kun je dit uitvoeren: @@ -726,7 +729,7 @@ Als je besluit om Gitosis niet te gebruiken, maar je wilt toch een Git daemon in $ cd /path/to/project.git $ touch git-daemon-export-ok -De aanwezigheid van dat bestand vertelt Git dat het OK is om dit project zonder verificatie te serveren. +De aanwezigheid van dat bestand vertelt Git dat het OK is om dit project zonder authenticatie te serveren. Gitosis kan ook de projecten die GitWeb toont beheren. Eerst moet je zoiets als het volgende aan het `/etc/gitweb.conf` bestand toevoegen: @@ -741,40 +744,40 @@ Je kunt instellen welke projecten GitWeb gebruikers laat bladeren door een `gitw daemon = yes gitweb = yes -Als je nu het project commit en pusht, start GitWeb automatisch met het tonen van je iphone project. +Als je nu het project commit en pushed, begint GitWeb automatisch je iphone project te tonen. ## Hosted Git ## -Als je niet al het werk wilt doen om je eigen Git server op te zetten, heb je meerdere opties om je Git project op een externe speciale hosting pagina te laten beheren. Dit biedt een aantal voordelen: een ge-hoste pagina is over het algemeen snel in te stellen, eenvoudig om projecten mee op te starten, en er komt geen serverbeheer en -onderhoud bij kijken. Zelfs als je je eigen server intern ingesteld hebt, zul je misschien een publieke host pagina voor je open source broncode willen – dat is over het algemeen makkelijker voor de open source commune te vinden en je er mee te helpen. +Als je niet al het werk wilt doen om je eigen Git server op te zetten, heb je meerdere opties om je Git project op een externe speciale hosting pagina te laten beheren. Dit biedt een aantal voordelen: een ge-hoste pagina is over het algemeen snel in te stellen, eenvoudig om projecten mee op te starten, en er komt geen serverbeheer en -onderhoud bij kijken. Zelfs als je je eigen server intern opgezet hebt, zul je misschien een publieke host pagina voor je open source broncode willen – dat is over het algemeen makkelijker voor de open source commune te vinden en je er mee te helpen. Vandaag de dag heb je een enorm aantal beheer opties om uit te kiezen, elk met verschillende voor- en nadelen. Om een recente lijst te zien, ga dan kijken op de volgende pagina : https://git.wiki.kernel.org/index.php/GitHosting -Omdat we ze niet allemaal kunnen behandelen, en ik toevallig bij een ervan werk, zullen we deze paragraaf gebruiken het instellen van een account en het opzetten van een project op GitHub te doorlopen. Dit geeft je een idee van het benodigde werk. +Omdat we ze niet allemaal kunnen behandelen, en omdat ik toevallig bij een ervan werk, zullen we deze paragraaf gebruiken het instellen van een account en het opzetten van een project op GitHub te doorlopen. Dit geeft je een idee van het benodigde werk. -GitHub is veruit de grootste open source Git beheer pagina en het is ook een van de weinige die zowel publieke als privé beheer opties biedt, zodat je je open source en commerciele privé code op dezelfde plaats kunt bewaren. Sterker nog, we hebben GitHub gebruikt om privé samen te werken aan dit boek. +GitHub is verreweg de grootste open source Git beheer site en het is ook een van de weinige die zowel publieke als privé hosting opties biedt, zodat je je open source en commerciële privé code op dezelfde plaats kunt bewaren. Als voorbeeld: we hebben GitHub gebruikt om privé samen te werken aan dit boek. ### GitHub ### -GitHub verschilt een beetje van de meeste code-beheer pagina's in de manier waarop het de projecten een naamruimte geeft. In plaats dat het primair gebaseerd is op het project, stelt GitHub gebruikers centraal. Dat betekent dat als ik mijn `grit` project op GitHub beheer, je het niet zult vinden op `github.com/grit` maar in plaats daarvan op `github.com/schacon/grit`. Er is geen generieke versie van een project, wat een project toestaat om naadloos van de ene op de andere gebruiker over te gaan als de eerste auteur het project verlaat. +GitHub verschilt een beetje van de meeste code-beheer pagina's in de manier waarop het de projecten een benoemt. In plaats dat het primair gebaseerd is op het project, stelt GitHub gebruikers centraal. Dat betekent dat als ik mijn `grit` project op GitHub beheer, je het niet zult vinden op `github.com/grit` maar in plaats daarvan op `github.com/schacon/grit`. Er is geen allesoverheersende versie van een project, wat een project in staat stelt om naadloos van de ene op de andere gebruiker over te gaan als de eerste auteur het project verlaat. -GitHub is ook een commercieel bedrijf dat geld vraagt voor accounts die privé repositories beheren, maar iedereen kan snel een gratis account krijgen om zoveel open source projecten als ze willen te beheren. We zullen er snel doorheen lopen hoe je dat doet. +GitHub is ook een commercieel bedrijf dat geld vraagt voor accounts die privé repositories beheren, maar iedereen kan snel een gratis account krijgen om net zoveel open source projecten te beheren als ze willen. We zullen er snel doorheen lopen hoe je dat doet. ### Een gebruikersaccount instellen ### -Het eerste dat je moet doen is een gratis gebruikersaccount instellen. Als je de Pricing and Signup pagina op `http://github.com/plans` bezoekt en de "Sign Up" knop aanklikt op het gratis account (zie figuur 4-2), dan wordt je naar de inteken pagina gebracht. +Het eerste dat je moet doen is een gratis gebruikers account aanvragen. Als je de Pricing and Signup pagina op `http://github.com/plans` bezoekt en de "Sign Up" knop aanklikt op het Free account (zie figuur 4-2), dan wordt je naar de inteken pagina gebracht. Insert 18333fig0402.png -Figuur 4-2. De GitHub inteken pagina. +Figuur 4-2. De GitHub plan pagina. -Hier moet je een gebruikersnaam kiezen die nog niet bezet is in het systeem, en een e-mail adres invullen dat bij het account hoort, en een wachtwoord (zie Figuur 4-3). +Hier moet je een gebruikersnaam kiezen die nog niet gebruikt is in het systeem, en een e-mail adres invullen dat bij het account hoort, en een wachtwoord (zie Figuur 4-3). Insert 18333fig0403.png Figuur 4-3. Het GitHub gebruikers inteken formulier. -Als je het beschikbaar hebt, is dit een goed moment om je publieke SSH sleutel ook toe te voegen. We hebben je eerder laten zien hoe je een nieuwe sleutel kunt genereren, in de "Eenvoudige Instellingen" sectie. Neem de inhoud van de publieke sleutel van dat paar, en plak het in het SSH publieke sleutel tekstveld. Door op de "explain ssh keys" link te klikken wordt je naar gedetailleerde instructies gebracht die je vertellen hoe dit te doen op alle veelgebruikte besturingssystemen. -Door op de "I agree, sign me up" knop te klikken wordt je naar je nieuwe gebruikers dashboard gebracht (zie Figuur 4-4). +Als je account beschikbaar is, is dit een goed moment om je publieke SSH sleutel ook toe te voegen. We hebben het genereren van een nieuwe sleutel eerder behandeld, in de "Je Publieke SSH Sleutel Genereren" paragraaf. Neem de inhoud van de publieke sleutel van dat paar, en plak het in het SSH publieke sleutel tekstveld. Door op de "explain ssh keys" link te klikken wordt je naar gedetaileerde instructies gebracht die je vertellen hoe dit te doen op alle veelvoorkomende besturingssystemen. +Door op de "I agree, sign me up" knop te klikken wordt je naar het dashboard van je nieuwe gebruikers gebracht (zie Figuur 4-4). Insert 18333fig0404.png Figuur 4-4. Het GitHub gebruikers dashboard. @@ -788,7 +791,7 @@ Start door op de "create a new one" link te klikken naast Your Repositories op h Insert 18333fig0405.png Figuur 4-5. Een nieuw repository aanmaken op GitHub. -Het enige dat je eigenlijk moet doen is een projectnaam opgeven, maar je kunt ook een beschrijving toevoegen. Wanneer je dat gedaan hebt, klik dan op de "Create Repository" knop. Nu heb je een nieuw repository op GitHub (zie Figuur 4-6). +Het enige dat je eigenlijk moet doen is een projectnaam opgeven, maar je kunt ook een beschrijving toevoegen. Wanneer je dat gedaan hebt, klik je op de "Create Repository" knop. Nu heb je een nieuw repository op GitHub (zie Figuur 4-6). Insert 18333fig0406.png Figuur 4-6. GitHub project hoofd informatie. @@ -809,14 +812,14 @@ Als je een lokaal Git repository hebt, voeg dan GitHub als remote toe en push je $ git remote add origin git@github.com:testinguser/iphone_project.git $ git push origin master -Nu wordt je project beheerd op GitHub, en kun je de URL aan iedereen geven waarmee je je project wilt delen. In dit geval is het `http://githup.com/testinguser/iphone_project`. Je kunt aan het begin van ieder van je project pagina's zien dat je twee Git URLs hebt (zie Figuur 4-8). +Nu wordt je project beheerd op GitHub, en kun je de URL aan iedereen geven waarmee je je project wilt delen. In dit geval is het `http://githup.com/testinguser/iphone_project`. Je kunt aan het begin van elk van je project pagina's zien dat je twee Git URLs hebt (zie Figuur 4-8). 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 klonen. Deel deze URL maar gewoon uit en zet 'm op je website of wat je ook hebt. +De Public Clone URL is een publieke alleen-lezen Git URL, waarmee iedereen het project kan clonen. Deel deze URL door 'm op je website neer te zetten of welke manier dan ook. -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. +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. ### Importeren vanuit Subversion ### @@ -831,12 +834,12 @@ Als je project erg groot is, niet standaard, of privé, dan zal dit proces waars Laten we de rest van het team toevoegen. Als John, Josie en Jessica allemaal intekenen voor accounts op GitHub, en je wilt ze push toegang op je repository geven, kun je ze aan je project toevoegen als medewerkers. Door dat te doen zullen pushes vanaf hun publieke sleutels werken. -Klik de "edit" knop aan de bovenkant van het project, of de Admin tab, om de Admin pagina te bereiken van je GitHub project (zie Figuur 4-10). +Klik de "edit" knop of de Admin tab aan de bovenkant van het project, om de Admin pagina te bereiken van je GitHub project (zie Figuur 4-10). Insert 18333fig0410.png Figuur 4-10. GitHub administratie pagina. -Om een andere gebruiker schrijftoegang tot je project te geven, klik dan de "Add another collaborator" link. Er verschijnt een nieuw tekstveld, waarin je een gebruikersnaam kunt invullen. Op het moment dat je typt, komt er een hulp omhoog, waarin alle mogelijke overeenkomende gebruikersnamen staan. Als je de juiste gebruiker vind, klik dan de Add knop om die gebruiker als een medewerker aan je project toe te voegen (zie Figuur 4-11). +Om een andere gebruiker schrijftoegang tot je project te geven, klik dan de "Add another collaborator" link. Er verschijnt een nieuw tekstveld, waarin je een gebruikersnaam kunt invullen. Op het moment dat je typt, komt er een hulp tevoorschijn, waarin alle mogelijke overeenkomende gebruikersnamen staan. Als je de juiste gebruiker vindt, klik dan de Add knop om die gebruiker als een medewerker aan je project toe te voegen (zie Figuur 4-11). Insert 18333fig0411.png Figuur 4-11. Een medewerker aan je project toevoegen. @@ -846,16 +849,16 @@ Als je klaar bent met medewerkers toevoegen, dan zou je een lijst met de namen m Insert 18333fig0412.png Figuur 4-12. Een lijst met medewerkers aan je project. -Als je toegang van individuen moet intrekken, dan kun je de "revoke" link klikken, en dan wordt hun push toegang ingetrokken. Voor toekomstige projecten, kun je ook de medewerker groepen kopiëren door de permissies van een bestaand project te kopiëren. +Als je toegang van individuen moet intrekken, dan kun je de "revoke" link klikken, en dan wordt hun push toegang ingetrokken. Voor toekomstige projecten, kun je ook groepen medewerker kopiëren door de permissies van een bestaand project te kopiëren. ### Je project ### -Nadat je je project gepusht hebt, of geïmporteerd vanuit Subversion, heb je een hoofd project pagina die er uitziet zoals Figuur 4-13. +Nadat je je project gepushed 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. -Als mensen je project bezoeken, zien ze deze pagina. Het bevat tabs naar de verschillende aspecten van je projecten. De Commits tab laat een lijst van commits in omgekeerde chronologische volgorde zien, vergelijkbaar met de output van het `git log` commando. De Network tab toont alle mensen die je project hebben geforked en bijgedragen hebben. De Downloads tab staat je toe project binaries te uploaden en naar tarballs en gezipte versies van ieder getagged punt in je project te linken. De Wiki tab voorziet in een wiki waar je documentatie kunt schrijven of andere informatie over je project. De Graphs tab heeft wat contributie visualisaties en statistieken over je project. De hoofd Source tab waarop je binnen komt toont de inhoud van de hoofdmap van je project en toont automatisch het README bestand eronder als je er een hebt. Deze tab toont ook een veld met de laatste commit informatie. +Als mensen je project bezoeken, zien ze deze pagina. Het bevat tabs naar de verschillende aspecten van je projecten. De Commits tab laat een lijst van commits in omgekeerde chronologische volgorde zien, vergelijkbaar met de output van het `git log` commando. De Network tab toont alle mensen die je project hebben geforked en bijgedragen hebben. De Downloads tab staat je toe project binaries te uploaden en naar tarballs en gezipte versies van ieder getagged punt in je project te linken. De Wiki tab voorziet in een wiki waar je documentatie kunt schrijven of andere informatie over je project. De Graphs tab heeft wat contributie visualisaties en statistieken over je project. De hoofd Source tab waarop je binnen komt, toont de inhoud van de hoofdmap van je project en toont automatisch het README bestand eronder als je er een hebt. Deze tab toont ook een veld met de laatste commit informatie. ### Projecten forken ### @@ -881,6 +884,6 @@ Dat is alles wat we laten zien over GitHub, maar het is belangrijk om te zien ho Je hebt meerdere opties om een remote Git repository werkend te krijgen zodat je kunt samenwerken met anderen of je werk kunt delen. -Je eigen server draaien geeft je veel controle en staat je toe om de server binnen je firewall te draaien, maar zo'n server vraagt over het algemeen een redelijke hoeveelheid tijd om in te stellen en te onderhouden. Als je je gegevens op een beheerde server plaatst, is het eenvoudig in te stellen en te onderhouden; maar je moet in staat zijn je code op iemand anders zijn servers te bewaren, en sommige organisaties staan dit niet toe. +Je eigen server draaien geeft je veel controle en stelt je in staat om de server binnen je firewall te draaien, maar zo'n server vraagt over het algemeen een redelijke hoeveelheid tijd om in te stellen en te onderhouden. Als je je gegevens op een beheerde server plaatst, is het eenvoudig in te stellen en te onderhouden; maar je moet wel willen dat je code op de server van een derde opgeslagen is, en sommige organisaties staan dit niet toe. Het zou redelijk rechttoe rechtaan moeten zijn om te bepalen welke oplossing of combinatie van oplossingen van toepassing is op jou en je organisatie. From 96d030d23684ce1c859370e55922eb36ea955f62 Mon Sep 17 00:00:00 2001 From: Cor Date: Tue, 21 Jan 2014 09:48:13 +0100 Subject: [PATCH 127/690] [nl] Revised earlier Dutch translation Modified certain sentences and wordchoises to be (hopefully) more consistent with actual use of jargon in Dutch. --- nl/01-introduction/01-chapter1.markdown | 96 ++++++++++++------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/nl/01-introduction/01-chapter1.markdown b/nl/01-introduction/01-chapter1.markdown index fc13ff83a..34f5eaab6 100644 --- a/nl/01-introduction/01-chapter1.markdown +++ b/nl/01-introduction/01-chapter1.markdown @@ -4,58 +4,58 @@ Dit hoofdstuk legt uit je hoe je aan de slag kunt gaan met Git. We zullen bij h ## Het wat en waarom van versiebeheer ## -Wat is versiebeheer? En wat heeft dat met jou te maken? Versiebeheer is een systeem dat veranderingen in een bestand of groep van bestanden over de tijd bijhoudt. Zodat je later specifieke versies kan opvragen. In de voorbeelden in dit boek is het broncode van computersoftware waarvan de versies beheerd worden maar je kan het eigenlijk met zo goed als elk soort bestand op een computer doen. +Wat is versiebeheer? En wat heeft dat met jou te maken? Versiebeheer is een systeem dat veranderingen in een bestand of groep van bestanden over de tijd bijhoudt, zodat je later specifieke versies kan opvragen. In de voorbeelden in dit boek is het broncode van computersoftware waarvan de versies beheerd worden maar je kan het eigenlijk met zo goed als elk soort bestand op een computer doen. -Als je een grafisch ontwerper bent of websites maakt en elke versie van een afbeelding of opmaak wilt bewaren (wat je zeker zou willen), is het verstandig een versiebeheersysteem (Version Control System in het Engels, afgekort tot VCS) te gebruiken. Als je dat gebruikt kan je eerdere versies van bestanden of hele project terughalen, veranderingen tussen twee momententen in tijd bekijken, zien wie het laatst iets aangepast heeft, wie een probleen heeft veroorzaakt en wanneer en nog veel meer. Een VCS gebruiken betekent meestal ook dat je de situatie gemakkelijk terug kan draaien als je een fout maakt of bestanden kwijtraakt. Daarbij komt nog dat dit allemaal heel weinig extra belasting met zich mee brengt. +Als je een grafisch ontwerper bent of websites maakt en elke versie van een afbeelding of opmaak wilt bewaren (wat je vrijwel zeker zult willen), is het verstandig een versiebeheersysteem (Version Control System in het Engels, afgekort tot VCS) te gebruiken. Als je dat gebruikt kan je eerdere versies van bestanden of hele project terughalen, veranderingen tussen twee momententen in tijd bekijken, zien wie het laatst iets aangepast heeft dat een probleem zou kunnen veroorzaken, wie een probleen heeft veroorzaakt en wanneer en nog veel meer. Een VCS gebruiken betekent meestal ook dat je de situatie gemakkelijk terug kan draaien als je een fout maakt of bestanden kwijtraakt. Daarbij komt nog dat dit allemaal heel weinig extra belasting met zich mee brengt. ### Lokale versiebeheersystemen ### -Veel mensen hebben hun eigen versiebeheer methode: ze kopiëren bestanden naar een andere map (en als ze slim zijn, geven ze die map ook een datum). Deze methode wordt veel gebruikt omdat het zo simpel is, maar het is ook ongelofelijk foutgevoelig. Het is makkelijk te vergeten in welke map je zit en naar het verkeerde bestand te schrijven, of over bestanden heen te kopiëren waar je dat niet wilde. +Veel mensen hebben hun eigen versiebeheer methode: ze kopiëren bestanden naar een andere map (en als ze slim zijn, geven ze die map ook een datum). Deze methode wordt veel gebruikt omdat het zo simpel is, maar het is ook ongelofelijk foutgevoelig. Het is makkelijk te vergeten in welke map je zit en naar het verkeerde bestand te schrijven, of onbedoeld over bestanden heen te kopiëren. -Om met dit probleem om te gaan hebben programmeurs lang geleden lokale VCSen ontwikkeld die een simpele database hadden om alle veranderingen aan bestanden te beheren (zie Figuur 1-1). +Om met dit probleem om te gaan hebben programmeurs lang geleden lokale VCSen ontwikkeld die een simpele database gebruikten om alle veranderingen aan bestanden te beheren (zie Figuur 1-1). Insert 18333fig0101.png Figuur 1-1. Een diagram van een lokaal versiebeheersysteem. -Een populair gereedschap voor VCS was een systeem genaamd rcs, wat vandaag de dag nog steeds met veel computers wordt mee geleverd. Zelfs het populaire besturingssysteem Mac OS X heeft rcs, als je de Developer Tools installeert. Dit gereedschap werkt in principe door verzamelingen van ‘patches’ (de verschillen tussen bestanden) van de opvolgende bestandsversies in een speciaal formaat op de harde schijf op te slaan; zo kan je teruggaan naar hoe een bestand er uitzag op ieder willekeurig moment in tijd, door alle patches bij elkaar op te tellen. +Een populair gereedschap voor VCS was een systeem genaamd rcs, wat vandaag de dag nog steeds met veel computers wordt mee geleverd. Zelfs het populaire besturingssysteem Mac OS X heeft rcs als je de Developer Tools installeert. Dit gereedschap werkt in principe door verzamelingen van ‘patches’ (de verschillen tussen bestanden) van de opvolgende bestandsversies in een speciaal formaat op de harde schijf op te slaan. Zo kan je teruggaan naar hoe een bestand er uitzag op ieder willekeurig moment in tijd, door alle patches bij elkaar op te tellen. ### Gecentraliseerde versiebeheersystemen ### -Het volgende grote probleem waar mensen tegenaan lopen is dat ze samen moeten werken met ontwikkelaars op andere computers. Om dit probleem op te lossen ontwikkelde men Gecentraliseerde Versiebeheersystemen (CVCSen). Deze systemen, zoals CVS, Subversion en Perforce, hebben één centrale server waarop alle versies van de bestanden staan en een aantal clients die de bestanden daar van halen (‘check out’, in het Engels). Vele jaren was dit de standaard voor versiebeheer (zie Figuur 1-2). +De volgende belangrijke uitdaging waar mensen tegenaan lopen is dat ze samen moeten werken met ontwikkelaars op andere computers. Om deze uitdaging te overkomen ontwikkelde men Gecentraliseerde Versiebeheersystemen (CVCSen). Deze systemen, zoals CVS, Subversion en Perforce, hebben één centrale server waarop alle versies van de bestanden staan en een aantal clients die de bestanden daar van halen (‘check out’, in het Engels). Vele jaren was dit de standaard voor versiebeheer (zie Figuur 1-2). Insert 18333fig0102.png Figuur 1-2. Een diagram van een gecentraliseerd versiebeheersysteem. -Deze manier van versiebeheer biedt veel voordelen, vooral als je het vergelijkt met lokale VCSen. Bijvoorbeeld, iedereen weet tot op zekere hoogte wat de overige project-medewerkers aan het doen zijn. Beheerders hebben precieze controle over wie wat kan doen; en het is veel eenvoudiger om een CVCS te beheren dan te moeten werken met lokale databases voor elke client. +Deze manier van versiebeheer biedt veel voordelen, vooral als je het vergelijkt met lokale VCSen. Bijvoorbeeld, iedereen weet tot op zekere hoogte wat de overige project-medewerkers aan het doen zijn. Beheerders hebben een hoge mate van controle over wie wat kan doen, en het is veel eenvoudiger om een CVCS te beheren dan te moeten werken met lokale databases op elke client. Maar helaas, deze methode heeft ook behoorlijke nadelen. De duidelijkste is de ‘single point of failure’: als de centrale server plat gaat en een uur later weer terug online komt kan niemand in dat uur samenwerken of versies bewaren van de dingen waar ze aan werken. Als de harde schrijf waar de centrale database op staat corrupt raakt en er geen backups van zijn verlies je echt alles — de hele geschiedenis van het project, behalve de momentopnames die mensen op hun eigen computers hebben staan. Lokale VCSen hebben hetzelfde probleem — als je de hele geschiedenis van het project op één enkele plaats bewaart, loop je ook kans alles te verliezen. ### Gedistribueerde versiebeheersystemen ### -En hier verschijnen Gedistribueerde versiebeheersystemen (DVCSen) ten tonele. In een DVCS (zoals Git, Mercurial, Bazaar en Darcs) downloaden clients niet alleen de laatste momentopnames van de bestanden. De hele geschiedenis (de ‘repository’) wordt gekopiëerd. Dus als een server neergaat en deze systemen werkten via die server samen dan kan de repository van elke willekeurige client terug worden gekopiëerd naar de server om deze te herstellen. Elke checkout is dus eigenlijk een complete backup van alle data (zie Figuur 1-3). +En hier verschijnen Gedistribueerde versiebeheersystemen (DVCSen) ten tonele. In een DVCS (zoals Git, Mercurial, Bazaar en Darcs) downloaden clients niet simpelweg de laatste momentopnames van de bestanden. De hele geschiedenis (de ‘repository’) wordt gekopiëerd. Dus als een server neergaat en deze systemen werkten via die server samen dan kan de repository van elke willekeurige client terug worden gekopiëerd naar de server om deze te herstellen. Elke checkout is dus eigenlijk een complete backup van alle data (zie Figuur 1-3). Insert 18333fig0103.png Figuur 1-3. Diagram van een gedistribueerd versiebeheersysteem Bovendien werken veel van deze systemen behoorlijk goed met meerdere (niet-lokale) repositories tegelijk zodat je met verschillende groepen mensen op verschillende manieren tegelijk aan hetzelfde project kan werken. Hierdoor kan je verschillende werkprocessen (‘workflows’) opzetten die niet mogelijk waren geweest met gecentraliseerde systemen zoals hiërarchische modellen. -## Een kleine geschiedenis van Git ## +## Een kort historisch overzicht van Git ## -Zoals zoveel goede dingen in het leven begon Git met een beetje creatieve destructie en een hoogoplopende controverse. De Linuxkernel is een open source softwareproject met een behoorlijk groot draagvlak. In het kader van het onderhoud van de Linuxkernel (1991–2002), werden aanpassingen aan de software voornamelijk verspreid via patches en gearchiveerde bestanden. In 2002 veranderde dat want vanaf dat jaar begon het project het gesloten DVCS genaamd BitKeeper te gebruiken. +Zoals zoveel goede dingen in het leven begon Git met een beetje creatieve destructie en een hoogoplopende controverse. De Linuxkernel is een open source softwareproject met een behoorlijk groot toepassingsgebied. In het kader van het onderhoud van de Linuxkernel (1991–2002), werden aanpassingen aan de software voornamelijk verspreid via patches en gearchiveerde bestanden. In 2002 veranderde dat want vanaf dat jaar begon het project een gesloten DVCS genaamd BitKeeper te gebruiken. -In 2005 viel de relatie tussen de gemeenschap die de Linuxkernel ontwikkelde en het commerciële bedrijf dat BitKeeper maakte uiteen. Het programma kon niet langer meer gratis worden gebruikt. Dit was de aanleiding voor de gemeenschap (en Linus Torvalds, de maker van Linux, in het bijzonder) om hun eigen gereedschap te ontwikkelen. Gebaseerd op de ervaring die opgedaan was toen ze nog BitKeeper gebruikten. Een paar van de doelen die ze hadden voor het nieuwe systeem waren als volgt: +In 2005 viel de relatie tussen de gemeenschap die de Linuxkernel ontwikkelde en het commerciële bedrijf dat BitKeeper maakte uiteen, en het programma kon niet langer meer gratis worden gebruikt. Dit was de aanleiding voor de gemeenschap (en Linus Torvalds, de maker van Linux, in het bijzonder) om hun eigen gereedschap te ontwikkelen. Gebaseerd op de ervaring die opgedaan was toen ze nog BitKeeper gebruikten. Een paar van de doelen die ze hadden voor het nieuwe systeem waren als volgt: * Snelheid * Eenvoudig ontwerp -* Goede ondersteuning voor niet-lineaire ontwikkeling (duizenden aparte takken tegelijk) +* Goede ondersteuning voor niet-lineaire ontwikkeling (duizenden parallelle takken (branches) ) * Volledig gedistribueerd * In staat om efficiënt om te gaan met grote projecten als de Linuxkernel (voor wat betreft snelheid maar ook opslagruimte) -Sinds het ontstaan in 2005 is Git gegroeid tot zijn huidige vorm: het is eenvoudig te gebruiken en heeft toch die oorspronkelijke eigenschappen behouden. Het is ongelofelijk snel, enorm efficiënt met grote projecten en zijn systeem voor aparte takken (‘branches’) van niet-lineaire ontwikkeling is ongeëvenaard (zie Hoofdstuk 3). +Sinds het ontstaan in 2005 is Git gegroeid tot zijn huidige vorm: het is eenvoudig te gebruiken en heeft toch die oorspronkelijke eigenschappen behouden. Het is ongelofelijk snel, enorm efficiënt met grote projecten en een ongeëvenaard systeem van branches voor het ondersteunen van niet-lineaire ontwikkeling (zie Hoofdstuk 3). ## De basis van Git ## -Dus, wat is Git in een notendop? Dit is een belangrijk deelhoofdstuk, omdat het waarschijnlijk een stuk makkelijker wordt om Git effectief te gebruiken als je goed begrijpt wat Git is en hoe het werkt. Probeer te vergeten wat je al weet over andere VCSen zoals Subversion en Perforce als je Git aan het leren bent; zo kan je verwarring door de subtiele verschillen voorkomen. Git gaat op een hele andere manier met informatie om dan die andere systemen, ook al lijken de verschillende commando’s behoorlijk op elkaar. Als je die verschillen begrijpt, kan je voorkomen dat je verward raakt als je Git gebruikt. +Dus, wat is Git in een notendop? Dit is een belangrijke paragraaf, omdat het waarschijnlijk een stuk makkelijker wordt om Git effectief te gebruiken als je goed begrijpt wat Git is en hoe het werkt. Probeer te vergeten wat je al weet over andere VCSen zoals Subversion en Perforce als je Git aan het leren bent; zo kan je verwarring door de subtiele verschillen voorkomen. Git gaat op een hele andere manier met informatie om dan die andere systemen, ook al lijken de verschillende commando’s behoorlijk op elkaar. Als je die verschillen begrijpt, kan je voorkomen dat je verward raakt als je Git gebruikt. ### Momentopnames in plaats van verschillen ### @@ -64,69 +64,69 @@ Een groot verschil tussen Git en elke andere VCS (inclusief Subversion en consoo Insert 18333fig0104.png Figuur 1-4. Andere systemen bewaren data meestal als veranderingen aan een basisversie van elk bestand. -Git ziet en bewaart zijn data heel anders. De kijk van Git op zijn data kan worden uitgelegd als een reeks momentopnames van een miniatuurbestandsysteem. Elke keer dat je ‘commit’ - de status van van je project in Git opslaat - neemt het een soort van foto van hoe al je bestanden er op dat moment uitzien en slaat een verwijzing naar die momentopname op. Voor efficiëntie slaat Git ongewijzigde bestanden niet elke keer opnieuw op — alleen een verwijzing naar het eerdere identieke bestand dat het eerder al opgeslagen had. In Figuur 1-5 kan je zie hoe Git ongeveer over zijn data denkt. +Git ziet en bewaart zijn data heel anders. De kijk van Git op zijn data kan worden uitgelegd als een reeks momentopnames (snapshots) van een miniatuurbestandsysteem. Elke keer dat je ‘commit’ - de status van van je project in Git opslaat - neemt het een soort van foto van hoe al je bestanden er op dat moment uitzien en slaat een verwijzing naar die snapshot op. Voor efficiëntie slaat Git ongewijzigde bestanden niet elke keer opnieuw op — alleen een verwijzing naar het eerdere identieke bestand dat het eerder al opgeslagen had. In Figuur 1-5 kan je zie hoe Git ongeveer over zijn data denkt. Insert 18333fig0105.png Figuur 1-5. Git bewaart data als momentopnames van het project. -Dat is een belangrijk verschil tussen Git en bijna alle overige VCSen. Hierdoor vindt Git bijna elk onderdeel van versiebeheer opnieuw uit, terwijl de meeste andere systemen het allemaal gewoon overnemen van de eerdere generaties. Hierdoor is Git meer een soort miniatuurbestandssysteem met een paar ongelooflijk krachtige gereedschappen, in plaats van niets meer dan een VCS. We zullen een paar van de voordelen die je krijgt als je op die manier over data denkt gaan onderzoeken, als we ‘branching’ (gesplitste ontwikkeling) toelichten in Hoofdstuk 3. +Dat is een belangrijk verschil tussen Git en bijna alle overige VCSen. Hierdoor vindt Git bijna elk onderdeel van versiebeheer opnieuw uit, terwijl de meeste andere systemen het van hebben overgenomen van eerdere generaties. Dit maakt Git meer een soort miniatuurbestandssysteem met een paar ongelooflijk krachtige gereedschappen, in plaats van niets meer dan een VCS. We zullen een paar van de voordelen die je krijgt als je op die manier over data denkt gaan onderzoeken, als we ‘branching’ (gesplitste ontwikkeling) toelichten in Hoofdstuk 3. ### Bijna alles is lokaal ### -De meeste handelingen in Git werken alleen op lokale bestanden en bronnen. Normaal gesproken is geen informatie nodig van een andere computer in je netwerk. Als je gewoon bent aan een CVCS, waar de meeste handelingen vertraagd worden door het netwerk, lijkt Git een geschenk van de snelheidsgoden. Omdat je de hele geschiedenis van het project op je lokale harde schijf hebt staan, lijken de meeste acties geen tijd in beslag te nemen. +De meeste handelingen in Git werken alleen op lokale bestanden en bronnen. Normaal gesproken is geen informatie nodig van een andere computer in je netwerk. Als je gewend bent aan een CVCS, waar de meeste handelingen vertraagd worden door het netwerk, lijkt Git door de goden begiftigd met de gave van ongelofelijke snelheid. Omdat je de hele geschiedenis van het project op je lokale harde schijf hebt staan, lijken de meeste acties geen tijd in beslag te nemen. -Een voorbeeld: Git hoeft niet aan een of andere server de geschiedenis van je project te vragen als je de die wilt doorbladeren – het leest simpelweg jouw lokale database. Dat betekent dat je de geschiedenis bijna direct te zien krijgt. Als je de veranderingen wilt zien tussen de huidige versie van een bestand en de versie van een maand geleden kan Git het bestand van een maand geleden opzoeken, en de lokale verschillen berekenen, in plaats van aan een niet-lokale server te moeten vragen om het te doen, of de oudere versie van het bestand ophalen om het lokaal te doen. +Een voorbeeld: Git hoeft niet aan een of andere server de geschiedenis van je project te vragen als je de die wilt doorbladeren – het leest simpelweg jouw lokale database. Dat betekent dat je de geschiedenis van het project bijna direct te zien krijgt. Als je de veranderingen wilt zien tussen de huidige versie van een bestand en de versie van een maand geleden kan Git het bestand van een maand geleden opzoeken, en de lokale verschillen berekenen, in plaats van aan een niet-lokale server te moeten vragen om het te doen, of de oudere versie van het bestand ophalen van een server om het lokaal te doen. -Dit betekent dat er maar heel weinig is dat je niet kunt doen als je offline bent of zonder VPN zit. Als je in een vliegtuig of trein zit, en je wilt nog even een beetje werken, kun je vrolijk doorgaan met commits maken tot je een netwerkverbinding krijgt, zodat je je werk kunt uploaden. Als je naar huis gaat en je VPN client niet aan de praat kunt krijgen dan kun je nog steeds doorwerken. Bij veel andere systemen is dat of onmogelijk of zeer onaangenaam. Als je bijvoorbeeld Perforce gebruikt kun je niet zo veel doen als je niet verbonden bent met de server. Met Subversion en CVS kun je bestanden bewerken maar je kunt geen commits maken voor je database (omdat die offline is). Dat lijkt misschien niet zo belangrijk maar je zult nog versteld staan wat een verschil het kan maken. +Dit betekent dat er maar heel weinig is dat je niet kunt doen als je offline bent of zonder VPN zit. Als je in een vliegtuig of trein zit, en je wilt nog even wat werken, kan je vrolijk doorgaan met commits maken tot je een netwerkverbinding krijgt, zodat je je werk kunt uploaden. Als je naar huis gaat en je VPN client niet aan de praat krijgt kan je nog steeds doorwerken. Bij veel andere systemen is dat of onmogelijk of zeer onaangenaam. Als je bijvoorbeeld Perforce gebruikt kun je niet zo veel doen als je niet verbonden bent met de server. Met Subversion en CVS kun je bestanden bewerken maar je kunt geen commits maken naar je database (omdat die offline is). Dat lijkt misschien niet zo belangrijk maar je zult nog versteld staan wat een verschil het kan maken. ### Git is integer ### -Git maakt een controlegetal (‘checksum’) van alles voordat het wordt opgeslagen en er wordt later naar die data verwezen met dit controlegetal. Dat betekent dat het onmogelijk is om de inhoud van een bestand of map te veranderen zonder dat Git er vanaf weet. Deze functionaliteit is ingebouwd in het diepste deel van Git en staat centraal in zijn filosofie. Je kunt geen informatie kwijtraken als het wordt verstuurd en bestanden kunnen niet corrupt raken zonder dat Git het weet. +Git maakt een controlegetal (‘checksum’) van alles voordat het wordt opgeslagen en er wordt later met dat controlegetal ernaar verwezen. Dat betekent dat het onmogelijk is om de inhoud van een bestand of map te veranderen zonder dat Git er vanaf weet. Deze functionaliteit is ingebouwd in het diepste deel van Git en staat centraal in zijn filosofie. Je kunt geen informatie kwijtraken als het wordt verstuurd en bestanden kunnen niet corrupt raken zonder dat Git het bemerkt. Het mechanisme dat Git gebruikt voor deze controlegetallen heet een SHA-1-hash. Dat is een tekenreeks van 40 karakters lang, bestaande uit hexadecimale tekens (0–9 en a–f) en wordt berekend uit de inhoud van een bestand of mapstructuur in Git. Een SHA-1-hash ziet er ongeveer zo uit: 24b9da6552252987aa493b52f8696cd6d3b00373 -Je zult deze hashtekenreeksen overal tegenkomen omdat Git er zoveel gebruik van maakt. Sterker nog, Git bewaart data niet onder hun bestandsnaam maar in de database van Git onder de hash van de inhoud. +Je zult deze hashtekenreeksen overal tegenkomen omdat Git er zoveel gebruik van maakt. Sterker nog, Git bewaart data niet onder hun bestandsnaam maar in de database van Git met de hash van de inhoud als sleutel. ### Git voegt normaal gesproken alleen data toe ### -Wanneer je iets doet in Git is de kans groot dat het alleen maar data aan de database van Git toevoegt. Het is erg moeilijk om het systeem iets te laten doen dat je niet ongedaan kan maken of de data uit te laten wissen op wat voor manier dan ook. Zoals met elke VCS kun je veranderingen verliezen of verhaspelen waar je nog geen momentopname van hebt gemaakt; maar als je dat eenmaal hebt gedaan, is het erg moeilijk om die data te verliezen, zeker als je je lokale database regelmatig uploadt (‘push’) naar een andere repository. +Wanneer je iets doet in Git is de kans groot dat deze acties alleen maar data aan de database van Git toevoegen. Het is erg moeilijk om het systeem iets te laten doen dat je niet ongedaan kan maken of de gegevens te laten wissen op wat voor manier dan ook. Zoals met elke VCS kun je veranderingen verliezen of verhaspelen als deze nog niet hebt gecommit; maar als je dat eenmaal hebt gedaan, is het erg moeilijk om die data te verliezen, zeker als je je lokale database regelmatig uploadt (‘push’) naar een andere repository. Je zult nog veel plezier van Git hebben omdat je weet dat je kunt experimenteren zonder het gevaar te lopen jezelf behoorlijk in de nesten te werken. Zie Hoofdstuk 9 voor een iets diepgaandere uitleg over hoe Git zijn data bewaart en hoe je de data die verloren lijkt kunt terughalen. ### De drie toestanden ### -Let nu goed op. Dit is het belangrijkste dat je over Git moet weten als je wilt dat de rest van het leerproces goed verloopt. Git heeft drie hoofdtoestanden waarin je bestanden zich kunnen bevinden: gecommit (‘commited’), aangepast (‘modified’) en voorbereid voor een commit (‘staged’). Gecommit betekent dat alle data al veilig opgeslagen is in je lokale database. Aangepast betekent dat je je bestand hebt veranderd maar dat je nog geen nieuwe momentopname in je database hebt. Voorbereid betekent dat je al hebt aangegeven dat je de huidige versie van het aangepaste bestand in je volgende momentopname toevoegt. +Let nu goed op. Dit is het belangrijkste dat je over Git moet weten als je wilt dat de rest van het leerproces gladjes verloopt. Git heeft drie hoofdtoestanden waarin je bestanden zich kunnen bevinden: gecommit (‘commited’), aangepast (‘modified’) en voorbereid voor een commit (‘staged’). Committed houdt in dat alle data al veilig opgeslagen is in je lokale database. Modified betekent dat je je bestand hebt veranderd maar dat je nog niet naar je database gecommit hebt. Staged betekent dat je al hebt aangegeven dat je de huidige versie van het aangepaste bestand in je volgende commit meegenomen moet worden. -Dit brengt ons tot de drie hoofdonderdelen van een Gitproject: de Gitmap, de werkmap, en de wachtrij voor een commit (‘staging area’) +Dit brengt ons tot de drie hoofdonderdelen van een Gitproject: de Git directory, de werk directory, en de wachtrij voor een commit (‘staging area’) Insert 18333fig0106.png -Figuur 1-6. Werkmap, wachtrij en Gitmap +Figuur 1-6. Werk directory, wachtrij en Git directory -De Gitmap is waar Git de metadata en objectdatabase van je project opslaat. Dit is het belangrijkste deel van Git. Deze map wordt gekopiëerd wanneer je een repository kloont vanaf een andere computer. +De Git directory is waar Git de metadata en objectdatabase van je project opslaat. Dit is het belangrijkste deel van Git. Deze directort wordt gekopiëerd wanneer je een repository kloont vanaf een andere computer. -De werkmap is een kopie van een bepaalde versie van het project (een ‘checkout’). Deze bestanden worden uit de gecomprimeerde database in de Gitmap gehaald en op de harde schijf geplaatst waar jij ze kunt gebruiken of bewerken. +De werk direcotry is een kopie van een bepaalde versie van het project (een ‘checkout’). Deze bestanden worden uit de gecomprimeerde database in de Git directory gehaald en op de harde schijf geplaatst waar jij ze kunt gebruiken of bewerken. -De wachtrij is een simpel bestand, dat zich in het algemeen in je Gitmap bevindt, waar informatie opgeslagen wordt over wat in de volgende commit meegaat. Het wordt soms de index genoemd, maar tegenwoordig wordt het de wachtrij (staging area) genoemd. +De wachtrij is een simpel bestand, dat zich normaalgesproken in je Git directory bevindt, waar informatie opgeslagen wordt over wat in de volgende commit meegaat. Het wordt soms de index genoemd, maar tegenwoordig wordt het de wachtrij (staging area) genoemd. De algemene manier van werken met Git gaat ongeveer zo: -1. Je bewerkt bestanden in je werkmap. -2. Je bereidt de bestanden voor, waardoor momentopnames worden toegevoegd aan de wachtrij. -3. Je maakt een commit. Een commit neemt alle momentopnames van de wachtrij en die permanent bewaard in je Gitmap. +1. Je bewerkt bestanden in je werk directory. +2. Je bereidt de bestanden voor (staged), waardoor momentopnames worden toegevoegd aan de wachtrij. +3. Je maakt een commit. Een commit neemt alle momentopnames van de wachtrij en bewaart die voorgoed in je Git directory. -Als een bepaalde versie van een bestand in de Gitmap staat, wordt het beschouwd als gecommit. Als het is aangepast, maar wel aan de wachtrij is toegevoegd, is het voorbereid. En als het veranderd is sinds het gekopiëerd werd, maar niet voorbereid is, is het aangepast. In Hoofdstuk 2 leer je meer over deze toestanden en hoe je er voordeel van kunt hebben, maar ook hoe je de wachtrij compleet over kunt slaan. +Als een bepaalde versie van een bestand in de Git directory staat, wordt het beschouwd als gecommit. Als het is aangepast, maar wel aan de wachtrij is toegevoegd, is het staged. En als het veranderd is sinds het gekopiëerd werd, maar niet staged is, is het aangepast. In Hoofdstuk 2 leer je meer over deze toestanden en hoe je er je voordeel mee kunt doen, maar ook hoe je de wachtrij compleet over kunt slaan. ## Git installeren ## -Laten we eens een beetje Git gebruiken. Je kunt natuurlijk niet meteen beginnen — je moet het eerst installeren. Er zijn een aantal manieren om eraan te komen; de belangrijkste twee zijn installeren vanaf broncode of een bestaand pakket voor jouw platform gebruiken. +Laten we eens een wat Git gebruiken. Je kunt natuurlijk niet meteen beginnen — je moet het eerst installeren. Er zijn een aantal manieren om eraan te komen; de belangrijkste twee zijn installeren vanaf broncode of een bestaand pakket voor jouw platform gebruiken. -### Installeren vanaf de bron ### +### Installeren vanaf de broncode ### -Als het mogelijk is, is het meestal handig om Git vanaf de broncode te installeren, omdat je dan altijd de nieuwste versie hebt. Elke versie van Git brengt meestal goede verbeteringen aan de gebruikersinterface met zich mee, dus de laatste versie is vaak de beste manier als je het gewoon bent software vanaf de broncode te compileren. Vaak hebben Linuxdistributies behoorlijk oude pakketen - tenzij je een hele up-to-date distro hebt of ‘backports’ (verbeteringen van een nieuwe versie op een oudere versie toepassen) gebruikt - is installeren vanaf broncode misschien wel de beste manier voor jou. +Als het mogelijk is, is het meestal nuttig om Git vanaf de broncode te installeren, omdat je dan altijd de recentste versie hebt. Elke versie van Git brengt meestal nuttige verbeteringen aan de gebruikersinterface met zich mee, dus de laatste versie is vaak de beste manier als je het gewend bent software vanaf de broncode te compileren. Vaak hebben Linuxdistributies behoorlijk oude pakketen - tenzij je een hele up-to-date distro hebt of ‘backports’ (verbeteringen van een nieuwe versie op een oudere versie toepassen) gebruikt - is installeren vanaf broncode misschien wel de beste manier voor jou. -Om Git te installeren heb je een aantal bibliotheken (‘libraries’) nodig: curl, zlib, openssl, expat, en libiconv. Als je bijvoorbeeld op een systeem werkt dat yum heeft (zoals Fedora) of apt-get (zoals systemen gebaseerd op Debian), kun je één van de volgende commando's gebruiken om alle bibliotheken waar Git van afhangt te installeren: +Om Git te installeren heb je een aantal bibliotheken (‘libraries’) nodig waar Git van afhankelijk is: curl, zlib, openssl, expat, en libiconv. Als je bijvoorbeeld op een systeem werkt dat yum heeft (zoals Fedora) of apt-get (zoals systemen gebaseerd op Debian), kun je één van de volgende commando's gebruiken om alle bibliotheken waar Git van afhankelijk is te installeren: $ yum install curl-devel expat-devel gettext-devel \ openssl-devel zlib-devel @@ -145,13 +145,13 @@ Daarna compileren en installeren: $ make prefix=/usr/local all $ sudo make prefix=/usr/local install -Als dat allemaal klaar is, kun je de nieuwste versie van Git uit Git ophalen met dit commando: +Als dat allemaal klaar is, kun je de ook nieuwste versie van Git met Git ophalen met dit commando: $ git clone git://git.kernel.org/pub/scm/git/git.git ### Op Linux installeren ### -Als je direct de uitvoerbare bestanden van Git op Linux wilt installeren, kun je dat normaal doen via het standaard pakketbeheersysteem dat meegeleverd is met je distributie. Als je Fedora gebruikt kun je yum gebruiken: +Als je direct de uitvoerbare bestanden van Git op Linux wilt installeren, kun je dat over het algemeen doen via het standaard pakketbeheersysteem dat meegeleverd is met je distributie. Als je Fedora gebruikt kun je yum gebruiken: $ yum install git-core @@ -168,7 +168,7 @@ Er zijn twee makkelijke manieren om Git op een Mac te installeren. De simpelste Insert 18333fig0107.png Figuur 1-7. Gitinstallatieprogramma voor OS X. -De andere veelgebruikte manier is om Git via MacPorts (`http://www.macports.org`) te installeren. Als je MacPorts hebt, kun je Git installeren met +De andere veelgebruikte manier is om Git via MacPorts (`http://www.macports.org`) te installeren. Als je MacPorts geïnstalleerd hebt, kun je Git installeren met $ sudo port install git-core +svn +doc +bash_completion +gitweb @@ -184,24 +184,24 @@ Nadat het geïnstalleerd is, kun je Git zowel vanaf de commandprompt gebruiken ( ## Git klaarmaken voor eerste gebruik ## -Nu je Git op je computer hebt staan, is het handig dat je een paar dingen doet om je Gitomgeving aan je voorkeuren aan te passen. Je hoeft deze instellingen normaliter maar één keer te doen. Ze blijven hetzelfde als je een nieuwe versie van Git installeert. Je kunt ze op elk moment weer veranderen door de commando’s opnieuw uit te voeren. +Nu je Git op je computer hebt staan, is het handig dat je een paar dingen doet om je Gitomgeving aan je voorkeuren aan te passen. Je hoeft deze instellingen normaliter maar één keer te doen, ze blijven hetzelfde als je een nieuwe versie van Git installeert. Je kunt ze op elk moment weer veranderen door de commando’s opnieuw uit te voeren. Git bevat standaard een stuk gereedschap genaamd `git config`, waarmee je de configuratie-eigenschappen kunt bekijken en veranderen, die alle aspecten van het uiterlijk en gedrag van Git regelen. Deze eigenschappen kunnen op drie verschillende plaatsen worden bewaard: * Het bestand `/etc/gitconfig`: Bevat eigenschappen voor elk account op de computer en al hun repositories. Als je de optie `--system` meegeeft aan `git config`, zal het dit de configuratiegegevens in dit bestand lezen of veranderen. * Het bestand `~/.gitconfig`: Eigenschappen voor jouw account. Je kunt Git dit bestand laten gebruiken door de optie `--global` mee te geven. -* Het configuratiebestand in de Gitmap (dus `.git/config`) van het repository dat je op het moment gebruikt: Specifiek voor dat ene repository. Elk niveau is belangrijker dan het voorgaande, dus waarden in `.git/config` zullen worden gebruikt in plaats van die in `/etc/gitconfig`. +* Het configuratiebestand in de Gitmap (dus `.git/config`) van het repository dat je op het moment gebruikt: Specifiek voor die ene repository. Elk niveau neemt voorrang boven het voorgaande, dus waarden die in `.git/config` zijn gebruikt zullen worden gebruikt in plaats van die in `/etc/gitconfig`. -Op systemen met Windows zoekt Git in de `$HOME` map naar het `.gitconfig`-bestand (`C:\Documents and Settings\$USER` voor de meesten). Het kijkt ook nog naar `/etc/gitconfig`, maar dan op de plek waar je MSys hebt staan, wat de plek is waar je Git op je Windowscomputer geïnstalleerd hebt. +Op systemen met Windows zoekt Git in de `$HOME` directory naar het `.gitconfig`-bestand (`C:\Documents and Settings\$USER` voor de meesten). Het kijkt ook nog naar `/etc/gitconfig`, maar dan op de plek waar je MSys hebt staan, wat de plek is waar je Git op je Windowscomputer geïnstalleerd hebt. ### Jouw identiteit ### Het eerste wat je zou moeten doen nadat je Git geïnstalleerd hebt, is je gebruikersnaam en e-mail addres opgeven. Dat is belangrijk, omdat elke commit in Git deze informatie gebruikt, en het onveranderlijk ingebed zit in de commits die je ronddeelt: - $ git config --global user.name "Scott Chacon" - $ git config --global user.email schacon@gmail.com + $ git config --global user.name "John Doe" + $ git config --global user.email johndoe@example.com -Nogmaals, dit hoef je maar één keer te doen als je de `--global` optie eraan plakt, omdat Git die informatie zal gebruiken voor alles wat je doet op dat systeem. Als je een andere naam of e-mail wilt gebruiken voor specifieke projecten, kun je het commando uitvoeren zonder de `--global` optie als je in de map van dat project zit. +Nogmaals, dit hoef je maar één keer te doen als je de `--global` optie erbij opgeeft, omdat Git die informatie zal gebruiken voor alles wat je doet op dat systeem. Als je een andere naam of e-mail wilt gebruiken voor specifieke projecten, kun je het commando uitvoeren zonder de `--global` optie als je in de directory van dat project zit. ### Je tekstverwerker ### @@ -215,11 +215,11 @@ En andere bruikbare optie die je misschien wel wilt instellen is het standaard d $ git config --global merge.tool vimdiff -Git accepteert kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge en opendiff als geldige samenvoegingsgereedschappen. Je kunt ook een ander programma gebruiken; zie Hoofdstuk 7 voor meer informatie daarover. +Git accepteert kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge en opendiff als geldige samenvoegingsgereedschappen. Je kunt ook een ander programma gebruiken, zie Hoofdstuk 7 voor meer informatie daarover. ### Je instellingen bekijken ### -Als je je instellingen wilt zien, kan je `git config --list` gebruiken voor een lijstje met alle instellingen die Git vanaf de huidige map kan vinden: +Als je je instellingen wilt zien, kan je het `git config --list` commando gebruiken voor een lijstje met alle instellingen die Git vanaf de huidige locatie kan vinden: $ git config --list user.name=Scott Chacon @@ -249,7 +249,7 @@ Bijvoorbeeld, je kunt de gebruikershandleiding voor het commando `git config` kr $ git help config -Deze commando's zijn fijn omdat je ze overal kunt opvragen, zelfs als je offline bent. +Deze commando's zijn prettig omdat je ze overal kunt opvragen, zelfs als je offline bent. Als de gebruiksaanwijzing en dit boek niet genoeg zijn en je persoonlijke hulp nodig hebt, kan je de kanalen `#git` of `#github` (beiden Engelstalig) op het Freenode IRC netwerk (irc.freenode.net) proberen. Deze kanalen zijn regelmatig gevuld met honderden mensen die allemaal zeer ervaren zijn met Git en vaak bereidwillig om te helpen. ## Samenvatting ## From a2cf37ba7b8d72a459fc27178f5c138fa1d79508 Mon Sep 17 00:00:00 2001 From: Cor Date: Tue, 21 Jan 2014 09:48:13 +0100 Subject: [PATCH 128/690] [nl] Revised earlier Dutch translation Modified certain sentences and wordchoises to be (hopefully) more consistent with actual use of jargon in Dutch. --- nl/01-introduction/01-chapter1.markdown | 92 ++++++++++++------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/nl/01-introduction/01-chapter1.markdown b/nl/01-introduction/01-chapter1.markdown index 0288809df..d64f59909 100644 --- a/nl/01-introduction/01-chapter1.markdown +++ b/nl/01-introduction/01-chapter1.markdown @@ -4,58 +4,58 @@ Dit hoofdstuk legt uit je hoe je aan de slag kunt gaan met Git. We zullen bij h ## Het wat en waarom van versiebeheer ## -Wat is versiebeheer? En wat heeft dat met jou te maken? Versiebeheer is een systeem dat veranderingen in een bestand of groep van bestanden over de tijd bijhoudt. Zodat je later specifieke versies kan opvragen. In de voorbeelden in dit boek is het broncode van computersoftware waarvan de versies beheerd worden maar je kan het eigenlijk met zo goed als elk soort bestand op een computer doen. +Wat is versiebeheer? En wat heeft dat met jou te maken? Versiebeheer is een systeem dat veranderingen in een bestand of groep van bestanden over de tijd bijhoudt, zodat je later specifieke versies kan opvragen. In de voorbeelden in dit boek is het broncode van computersoftware waarvan de versies beheerd worden maar je kan het eigenlijk met zo goed als elk soort bestand op een computer doen. -Als je een grafisch ontwerper bent of websites maakt en elke versie van een afbeelding of opmaak wilt bewaren (wat je zeker zou willen), is het verstandig een versiebeheersysteem (Version Control System in het Engels, afgekort tot VCS) te gebruiken. Als je dat gebruikt kan je eerdere versies van bestanden of hele project terughalen, veranderingen tussen twee momenten in tijd bekijken, zien wie het laatst iets aangepast heeft, wie een probleem heeft veroorzaakt en wanneer en nog veel meer. Een VCS gebruiken betekent meestal ook dat je de situatie gemakkelijk terug kan draaien als je een fout maakt of bestanden kwijtraakt. Daarbij komt nog dat dit allemaal heel weinig extra belasting met zich mee brengt. +Als je een grafisch ontwerper bent of websites maakt en elke versie van een afbeelding of opmaak wilt bewaren (wat je vrijwel zeker zult willen), is het verstandig een versiebeheersysteem (Version Control System in het Engels, afgekort tot VCS) te gebruiken. Als je dat gebruikt kan je eerdere versies van bestanden of hele project terughalen, veranderingen tussen twee momententen in tijd bekijken, zien wie het laatst iets aangepast heeft dat een probleem zou kunnen veroorzaken, wie een probleen heeft veroorzaakt en wanneer en nog veel meer. Een VCS gebruiken betekent meestal ook dat je de situatie gemakkelijk terug kan draaien als je een fout maakt of bestanden kwijtraakt. Daarbij komt nog dat dit allemaal heel weinig extra belasting met zich mee brengt. ### Lokale versiebeheersystemen ### -Veel mensen hebben hun eigen versiebeheer methode: ze kopiëren bestanden naar een andere map (en als ze slim zijn, geven ze die map ook een datum). Deze methode wordt veel gebruikt omdat het zo simpel is, maar het is ook ongelofelijk foutgevoelig. Het is makkelijk te vergeten in welke map je zit en naar het verkeerde bestand te schrijven, of over bestanden heen te kopiëren waar je dat niet wilde. +Veel mensen hebben hun eigen versiebeheer methode: ze kopiëren bestanden naar een andere map (en als ze slim zijn, geven ze die map ook een datum). Deze methode wordt veel gebruikt omdat het zo simpel is, maar het is ook ongelofelijk foutgevoelig. Het is makkelijk te vergeten in welke map je zit en naar het verkeerde bestand te schrijven, of onbedoeld over bestanden heen te kopiëren. -Om met dit probleem om te gaan hebben programmeurs lang geleden lokale VCSen ontwikkeld die een simpele database hadden om alle veranderingen aan bestanden te beheren (zie Figuur 1-1). +Om met dit probleem om te gaan hebben programmeurs lang geleden lokale VCSen ontwikkeld die een simpele database gebruikten om alle veranderingen aan bestanden te beheren (zie Figuur 1-1). Insert 18333fig0101.png Figuur 1-1. Een diagram van een lokaal versiebeheersysteem. -Een populair gereedschap voor VCS was een systeem genaamd rcs, wat vandaag de dag nog steeds met veel computers wordt mee geleverd. Zelfs het populaire besturingssysteem Mac OS X heeft rcs, als je de Developer Tools installeert. Dit gereedschap werkt in principe door verzamelingen van ‘patches’ (de verschillen tussen bestanden) van de opvolgende bestandsversies in een speciaal formaat op de harde schijf op te slaan; zo kan je teruggaan naar hoe een bestand er uitzag op ieder willekeurig moment in tijd, door alle patches bij elkaar op te tellen. +Een populair gereedschap voor VCS was een systeem genaamd rcs, wat vandaag de dag nog steeds met veel computers wordt mee geleverd. Zelfs het populaire besturingssysteem Mac OS X heeft rcs als je de Developer Tools installeert. Dit gereedschap werkt in principe door verzamelingen van ‘patches’ (de verschillen tussen bestanden) van de opvolgende bestandsversies in een speciaal formaat op de harde schijf op te slaan. Zo kan je teruggaan naar hoe een bestand er uitzag op ieder willekeurig moment in tijd, door alle patches bij elkaar op te tellen. ### Gecentraliseerde versiebeheersystemen ### -Het volgende grote probleem waar mensen tegenaan lopen is dat ze samen moeten werken met ontwikkelaars op andere computers. Om dit probleem op te lossen ontwikkelde men Gecentraliseerde Versiebeheersystemen (CVCSen). Deze systemen, zoals CVS, Subversion en Perforce, hebben één centrale server waarop alle versies van de bestanden staan en een aantal clients die de bestanden daar van halen (‘check out’, in het Engels). Vele jaren was dit de standaard voor versiebeheer (zie Figuur 1-2). +De volgende belangrijke uitdaging waar mensen tegenaan lopen is dat ze samen moeten werken met ontwikkelaars op andere computers. Om deze uitdaging te overkomen ontwikkelde men Gecentraliseerde Versiebeheersystemen (CVCSen). Deze systemen, zoals CVS, Subversion en Perforce, hebben één centrale server waarop alle versies van de bestanden staan en een aantal clients die de bestanden daar van halen (‘check out’, in het Engels). Vele jaren was dit de standaard voor versiebeheer (zie Figuur 1-2). Insert 18333fig0102.png Figuur 1-2. Een diagram van een gecentraliseerd versiebeheersysteem. -Deze manier van versiebeheer biedt veel voordelen, vooral als je het vergelijkt met lokale VCSen. Bijvoorbeeld, iedereen weet tot op zekere hoogte wat de overige project-medewerkers aan het doen zijn. Beheerders hebben precieze controle over wie wat kan doen; en het is veel eenvoudiger om een CVCS te beheren dan te moeten werken met lokale databases voor elke client. +Deze manier van versiebeheer biedt veel voordelen, vooral als je het vergelijkt met lokale VCSen. Bijvoorbeeld, iedereen weet tot op zekere hoogte wat de overige project-medewerkers aan het doen zijn. Beheerders hebben een hoge mate van controle over wie wat kan doen, en het is veel eenvoudiger om een CVCS te beheren dan te moeten werken met lokale databases op elke client. Maar helaas, deze methode heeft ook behoorlijke nadelen. De duidelijkste is de ‘single point of failure’: als de centrale server plat gaat en een uur later weer terug online komt kan niemand in dat uur samenwerken of versies bewaren van de dingen waar ze aan werken. Als de harde schrijf waar de centrale database op staat corrupt raakt en er geen backups van zijn verlies je echt alles — de hele geschiedenis van het project, behalve de momentopnames die mensen op hun eigen computers hebben staan. Lokale VCSen hebben hetzelfde probleem — als je de hele geschiedenis van het project op één enkele plaats bewaart, loop je ook kans alles te verliezen. ### Gedistribueerde versiebeheersystemen ### -En hier verschijnen Gedistribueerde versiebeheersystemen (DVCSen) ten tonele. In een DVCS (zoals Git, Mercurial, Bazaar en Darcs) downloaden clients niet alleen de laatste momentopnames van de bestanden. De hele geschiedenis (de ‘repository’) wordt gekopieerd. Dus als een server neergaat en deze systemen werkten via die server samen dan kan de repository van elke willekeurige client terug worden gekopieerd naar de server om deze te herstellen. Elke checkout is dus eigenlijk een complete backup van alle data (zie Figuur 1-3). +En hier verschijnen Gedistribueerde versiebeheersystemen (DVCSen) ten tonele. In een DVCS (zoals Git, Mercurial, Bazaar en Darcs) downloaden clients niet simpelweg de laatste momentopnames van de bestanden. De hele geschiedenis (de ‘repository’) wordt gekopiëerd. Dus als een server neergaat en deze systemen werkten via die server samen dan kan de repository van elke willekeurige client terug worden gekopiëerd naar de server om deze te herstellen. Elke checkout is dus eigenlijk een complete backup van alle data (zie Figuur 1-3). Insert 18333fig0103.png Figuur 1-3. Diagram van een gedistribueerd versiebeheersysteem Bovendien werken veel van deze systemen behoorlijk goed met meerdere (niet-lokale) repositories tegelijk zodat je met verschillende groepen mensen op verschillende manieren tegelijk aan hetzelfde project kan werken. Hierdoor kan je verschillende werkprocessen (‘workflows’) opzetten die niet mogelijk waren geweest met gecentraliseerde systemen zoals hiërarchische modellen. -## Een kleine geschiedenis van Git ## +## Een kort historisch overzicht van Git ## -Zoals zoveel goede dingen in het leven begon Git met een beetje creatieve destructie en een hoogoplopende controverse. De Linuxkernel is een open source softwareproject met een behoorlijk groot draagvlak. In het kader van het onderhoud van de Linuxkernel (1991–2002), werden aanpassingen aan de software voornamelijk verspreid via patches en gearchiveerde bestanden. In 2002 veranderde dat want vanaf dat jaar begon het project het gesloten DVCS genaamd BitKeeper te gebruiken. +Zoals zoveel goede dingen in het leven begon Git met een beetje creatieve destructie en een hoogoplopende controverse. De Linuxkernel is een open source softwareproject met een behoorlijk groot toepassingsgebied. In het kader van het onderhoud van de Linuxkernel (1991–2002), werden aanpassingen aan de software voornamelijk verspreid via patches en gearchiveerde bestanden. In 2002 veranderde dat want vanaf dat jaar begon het project een gesloten DVCS genaamd BitKeeper te gebruiken. -In 2005 viel de relatie tussen de gemeenschap die de Linuxkernel ontwikkelde en het commerciële bedrijf dat BitKeeper maakte uiteen. Het programma kon niet langer meer gratis worden gebruikt. Dit was de aanleiding voor de gemeenschap (en Linus Torvalds, de maker van Linux, in het bijzonder) om hun eigen gereedschap te ontwikkelen. Gebaseerd op de ervaring die opgedaan was toen ze nog BitKeeper gebruikten. Een paar van de doelen die ze hadden voor het nieuwe systeem waren als volgt: +In 2005 viel de relatie tussen de gemeenschap die de Linuxkernel ontwikkelde en het commerciële bedrijf dat BitKeeper maakte uiteen, en het programma kon niet langer meer gratis worden gebruikt. Dit was de aanleiding voor de gemeenschap (en Linus Torvalds, de maker van Linux, in het bijzonder) om hun eigen gereedschap te ontwikkelen. Gebaseerd op de ervaring die opgedaan was toen ze nog BitKeeper gebruikten. Een paar van de doelen die ze hadden voor het nieuwe systeem waren als volgt: * Snelheid * Eenvoudig ontwerp -* Goede ondersteuning voor niet-lineaire ontwikkeling (duizenden aparte takken tegelijk) +* Goede ondersteuning voor niet-lineaire ontwikkeling (duizenden parallelle takken (branches) ) * Volledig gedistribueerd * In staat om efficiënt om te gaan met grote projecten als de Linuxkernel (voor wat betreft snelheid maar ook opslagruimte) -Sinds het ontstaan in 2005 is Git gegroeid tot zijn huidige vorm: het is eenvoudig te gebruiken en heeft toch die oorspronkelijke eigenschappen behouden. Het is ongelofelijk snel, enorm efficiënt met grote projecten en zijn systeem voor aparte takken (‘branches’) van niet-lineaire ontwikkeling is ongeëvenaard (zie Hoofdstuk 3). +Sinds het ontstaan in 2005 is Git gegroeid tot zijn huidige vorm: het is eenvoudig te gebruiken en heeft toch die oorspronkelijke eigenschappen behouden. Het is ongelofelijk snel, enorm efficiënt met grote projecten en een ongeëvenaard systeem van branches voor het ondersteunen van niet-lineaire ontwikkeling (zie Hoofdstuk 3). ## De basis van Git ## -Dus, wat is Git in een notendop? Dit is een belangrijk deelhoofdstuk, omdat het waarschijnlijk een stuk makkelijker wordt om Git effectief te gebruiken als je goed begrijpt wat Git is en hoe het werkt. Probeer te vergeten wat je al weet over andere VCSen zoals Subversion en Perforce als je Git aan het leren bent; zo kan je verwarring door de subtiele verschillen voorkomen. Git gaat op een hele andere manier met informatie om dan die andere systemen, ook al lijken de verschillende commando’s behoorlijk op elkaar. Als je die verschillen begrijpt, kan je voorkomen dat je verward raakt als je Git gebruikt. +Dus, wat is Git in een notendop? Dit is een belangrijke paragraaf, omdat het waarschijnlijk een stuk makkelijker wordt om Git effectief te gebruiken als je goed begrijpt wat Git is en hoe het werkt. Probeer te vergeten wat je al weet over andere VCSen zoals Subversion en Perforce als je Git aan het leren bent; zo kan je verwarring door de subtiele verschillen voorkomen. Git gaat op een hele andere manier met informatie om dan die andere systemen, ook al lijken de verschillende commando’s behoorlijk op elkaar. Als je die verschillen begrijpt, kan je voorkomen dat je verward raakt als je Git gebruikt. ### Momentopnames in plaats van verschillen ### @@ -64,69 +64,69 @@ Een groot verschil tussen Git en elke andere VCS (inclusief Subversion en consoo Insert 18333fig0104.png Figuur 1-4. Andere systemen bewaren data meestal als veranderingen aan een basisversie van elk bestand. -Git ziet en bewaart zijn data heel anders. De kijk van Git op zijn data kan worden uitgelegd als een reeks momentopnames van een miniatuurbestandssysteem. Elke keer dat je ‘commit’ - de status van van je project in Git opslaat - neemt het een soort van foto van hoe al je bestanden er op dat moment uitzien en slaat een verwijzing naar die momentopname op. Voor efficiëntie slaat Git ongewijzigde bestanden niet elke keer opnieuw op — alleen een verwijzing naar het eerdere identieke bestand dat het eerder al opgeslagen had. In Figuur 1-5 kan je zie hoe Git ongeveer over zijn data denkt. +Git ziet en bewaart zijn data heel anders. De kijk van Git op zijn data kan worden uitgelegd als een reeks momentopnames (snapshots) van een miniatuurbestandsysteem. Elke keer dat je ‘commit’ - de status van van je project in Git opslaat - neemt het een soort van foto van hoe al je bestanden er op dat moment uitzien en slaat een verwijzing naar die snapshot op. Voor efficiëntie slaat Git ongewijzigde bestanden niet elke keer opnieuw op — alleen een verwijzing naar het eerdere identieke bestand dat het eerder al opgeslagen had. In Figuur 1-5 kan je zie hoe Git ongeveer over zijn data denkt. Insert 18333fig0105.png Figuur 1-5. Git bewaart data als momentopnames van het project. -Dat is een belangrijk verschil tussen Git en bijna alle overige VCSen. Hierdoor vindt Git bijna elk onderdeel van versiebeheer opnieuw uit, terwijl de meeste andere systemen het allemaal gewoon overnemen van de eerdere generaties. Hierdoor is Git meer een soort miniatuurbestandssysteem met een paar ongelooflijk krachtige gereedschappen, in plaats van niets meer dan een VCS. We zullen een paar van de voordelen die je krijgt als je op die manier over data denkt gaan onderzoeken, als we ‘branching’ (gesplitste ontwikkeling) toelichten in Hoofdstuk 3. +Dat is een belangrijk verschil tussen Git en bijna alle overige VCSen. Hierdoor vindt Git bijna elk onderdeel van versiebeheer opnieuw uit, terwijl de meeste andere systemen het van hebben overgenomen van eerdere generaties. Dit maakt Git meer een soort miniatuurbestandssysteem met een paar ongelooflijk krachtige gereedschappen, in plaats van niets meer dan een VCS. We zullen een paar van de voordelen die je krijgt als je op die manier over data denkt gaan onderzoeken, als we ‘branching’ (gesplitste ontwikkeling) toelichten in Hoofdstuk 3. ### Bijna alles is lokaal ### -De meeste handelingen in Git werken alleen op lokale bestanden en bronnen. Normaal gesproken is geen informatie nodig van een andere computer in je netwerk. Als je gewoon bent aan een CVCS, waar de meeste handelingen vertraagd worden door het netwerk, lijkt Git een geschenk van de snelheidsgoden. Omdat je de hele geschiedenis van het project op je lokale harde schijf hebt staan, lijken de meeste acties geen tijd in beslag te nemen. +De meeste handelingen in Git werken alleen op lokale bestanden en bronnen. Normaal gesproken is geen informatie nodig van een andere computer in je netwerk. Als je gewend bent aan een CVCS, waar de meeste handelingen vertraagd worden door het netwerk, lijkt Git door de goden begiftigd met de gave van ongelofelijke snelheid. Omdat je de hele geschiedenis van het project op je lokale harde schijf hebt staan, lijken de meeste acties geen tijd in beslag te nemen. -Een voorbeeld: Git hoeft niet aan een of andere server de geschiedenis van je project te vragen als je de die wilt doorbladeren – het leest simpelweg jouw lokale database. Dat betekent dat je de geschiedenis bijna direct te zien krijgt. Als je de veranderingen wilt zien tussen de huidige versie van een bestand en de versie van een maand geleden kan Git het bestand van een maand geleden opzoeken, en de lokale verschillen berekenen, in plaats van aan een niet-lokale server te moeten vragen om het te doen, of de oudere versie van het bestand ophalen om het lokaal te doen. +Een voorbeeld: Git hoeft niet aan een of andere server de geschiedenis van je project te vragen als je de die wilt doorbladeren – het leest simpelweg jouw lokale database. Dat betekent dat je de geschiedenis van het project bijna direct te zien krijgt. Als je de veranderingen wilt zien tussen de huidige versie van een bestand en de versie van een maand geleden kan Git het bestand van een maand geleden opzoeken, en de lokale verschillen berekenen, in plaats van aan een niet-lokale server te moeten vragen om het te doen, of de oudere versie van het bestand ophalen van een server om het lokaal te doen. -Dit betekent dat er maar heel weinig is dat je niet kunt doen als je offline bent of zonder VPN zit. Als je in een vliegtuig of trein zit, en je wilt nog even een beetje werken, kun je vrolijk doorgaan met commits maken tot je een netwerkverbinding krijgt, zodat je je werk kunt uploaden. Als je naar huis gaat en je VPN client niet aan de praat kunt krijgen dan kun je nog steeds doorwerken. Bij veel andere systemen is dat of onmogelijk of zeer onaangenaam. Als je bijvoorbeeld Perforce gebruikt kun je niet zo veel doen als je niet verbonden bent met de server. Met Subversion en CVS kun je bestanden bewerken maar je kunt geen commits maken voor je database (omdat die offline is). Dat lijkt misschien niet zo belangrijk maar je zult nog versteld staan wat een verschil het kan maken. +Dit betekent dat er maar heel weinig is dat je niet kunt doen als je offline bent of zonder VPN zit. Als je in een vliegtuig of trein zit, en je wilt nog even wat werken, kan je vrolijk doorgaan met commits maken tot je een netwerkverbinding krijgt, zodat je je werk kunt uploaden. Als je naar huis gaat en je VPN client niet aan de praat krijgt kan je nog steeds doorwerken. Bij veel andere systemen is dat of onmogelijk of zeer onaangenaam. Als je bijvoorbeeld Perforce gebruikt kun je niet zo veel doen als je niet verbonden bent met de server. Met Subversion en CVS kun je bestanden bewerken maar je kunt geen commits maken naar je database (omdat die offline is). Dat lijkt misschien niet zo belangrijk maar je zult nog versteld staan wat een verschil het kan maken. ### Git is integer ### -Git maakt een controlegetal (‘checksum’) van alles voordat het wordt opgeslagen en er wordt later naar die data verwezen met dit controlegetal. Dat betekent dat het onmogelijk is om de inhoud van een bestand of map te veranderen zonder dat Git er vanaf weet. Deze functionaliteit is ingebouwd in het diepste deel van Git en staat centraal in zijn filosofie. Je kunt geen informatie kwijtraken als het wordt verstuurd en bestanden kunnen niet corrupt raken zonder dat Git het weet. +Git maakt een controlegetal (‘checksum’) van alles voordat het wordt opgeslagen en er wordt later met dat controlegetal ernaar verwezen. Dat betekent dat het onmogelijk is om de inhoud van een bestand of map te veranderen zonder dat Git er vanaf weet. Deze functionaliteit is ingebouwd in het diepste deel van Git en staat centraal in zijn filosofie. Je kunt geen informatie kwijtraken als het wordt verstuurd en bestanden kunnen niet corrupt raken zonder dat Git het bemerkt. Het mechanisme dat Git gebruikt voor deze controlegetallen heet een SHA-1-hash. Dat is een tekenreeks van 40 karakters lang, bestaande uit hexadecimale tekens (0–9 en a–f) en wordt berekend uit de inhoud van een bestand of mappenstructuur in Git. Een SHA-1-hash ziet er ongeveer zo uit: 24b9da6552252987aa493b52f8696cd6d3b00373 -Je zult deze hashtekenreeksen overal tegenkomen omdat Git er zoveel gebruik van maakt. Sterker nog, Git bewaart data niet onder hun bestandsnaam maar in de database van Git onder de hash van de inhoud. +Je zult deze hashtekenreeksen overal tegenkomen omdat Git er zoveel gebruik van maakt. Sterker nog, Git bewaart data niet onder hun bestandsnaam maar in de database van Git met de hash van de inhoud als sleutel. ### Git voegt normaal gesproken alleen data toe ### -Wanneer je iets doet in Git is de kans groot dat het alleen maar data aan de database van Git toevoegt. Het is erg moeilijk om het systeem iets te laten doen dat je niet ongedaan kan maken of de data uit te laten wissen op wat voor manier dan ook. Zoals met elke VCS kun je veranderingen verliezen of verhaspelen waar je nog geen momentopname van hebt gemaakt; maar als je dat eenmaal hebt gedaan, is het erg moeilijk om die data te verliezen, zeker als je je lokale database regelmatig uploadt (‘push’) naar een andere repository. +Wanneer je iets doet in Git is de kans groot dat deze acties alleen maar data aan de database van Git toevoegen. Het is erg moeilijk om het systeem iets te laten doen dat je niet ongedaan kan maken of de gegevens te laten wissen op wat voor manier dan ook. Zoals met elke VCS kun je veranderingen verliezen of verhaspelen als deze nog niet hebt gecommit; maar als je dat eenmaal hebt gedaan, is het erg moeilijk om die data te verliezen, zeker als je je lokale database regelmatig uploadt (‘push’) naar een andere repository. Je zult nog veel plezier van Git hebben omdat je weet dat je kunt experimenteren zonder het gevaar te lopen jezelf behoorlijk in de nesten te werken. Zie Hoofdstuk 9 voor een iets diepgaandere uitleg over hoe Git zijn data bewaart en hoe je de data die verloren lijkt kunt terughalen. ### De drie toestanden ### -Let nu goed op. Dit is het belangrijkste dat je over Git moet weten als je wilt dat de rest van het leerproces goed verloopt. Git heeft drie hoofdtoestanden waarin je bestanden zich kunnen bevinden: gecommit (‘commited’), aangepast (‘modified’) en voorbereid voor een commit (‘staged’). Gecommit betekent dat alle data al veilig opgeslagen is in je lokale database. Aangepast betekent dat je je bestand hebt veranderd maar dat je nog geen nieuwe momentopname in je database hebt. Voorbereid betekent dat je al hebt aangegeven dat je de huidige versie van het aangepaste bestand in je volgende momentopname toevoegt. +Let nu goed op. Dit is het belangrijkste dat je over Git moet weten als je wilt dat de rest van het leerproces gladjes verloopt. Git heeft drie hoofdtoestanden waarin je bestanden zich kunnen bevinden: gecommit (‘commited’), aangepast (‘modified’) en voorbereid voor een commit (‘staged’). Committed houdt in dat alle data al veilig opgeslagen is in je lokale database. Modified betekent dat je je bestand hebt veranderd maar dat je nog niet naar je database gecommit hebt. Staged betekent dat je al hebt aangegeven dat je de huidige versie van het aangepaste bestand in je volgende commit meegenomen moet worden. -Dit brengt ons tot de drie hoofdonderdelen van een Gitproject: de Gitmap, de werkmap, en de wachtrij voor een commit (‘staging area’) +Dit brengt ons tot de drie hoofdonderdelen van een Gitproject: de Git directory, de werk directory, en de wachtrij voor een commit (‘staging area’) -Insert 18333fig0106.png -Figuur 1-6. Werkmap, wachtrij en Gitmap +Insert 18333fig0106.png +Figuur 1-6. Werk directory, wachtrij en Git directory -De Gitmap is waar Git de metadata en objectdatabase van je project opslaat. Dit is het belangrijkste deel van Git. Deze map wordt gekopieerd wanneer je een repository kloont vanaf een andere computer. +De Git directory is waar Git de metadata en objectdatabase van je project opslaat. Dit is het belangrijkste deel van Git. Deze directort wordt gekopiëerd wanneer je een repository kloont vanaf een andere computer. -De werkmap is een kopie van een bepaalde versie van het project (een ‘checkout’). Deze bestanden worden uit de gecomprimeerde database in de Gitmap gehaald en op de harde schijf geplaatst waar jij ze kunt gebruiken of bewerken. +De werk direcotry is een kopie van een bepaalde versie van het project (een ‘checkout’). Deze bestanden worden uit de gecomprimeerde database in de Git directory gehaald en op de harde schijf geplaatst waar jij ze kunt gebruiken of bewerken. -De wachtrij is een simpel bestand, dat zich in het algemeen in je Gitmap bevindt, waar informatie opgeslagen wordt over wat in de volgende commit meegaat. Het wordt soms de index genoemd, maar tegenwoordig wordt het de wachtrij (staging area) genoemd. +De wachtrij is een simpel bestand, dat zich normaalgesproken in je Git directory bevindt, waar informatie opgeslagen wordt over wat in de volgende commit meegaat. Het wordt soms de index genoemd, maar tegenwoordig wordt het de wachtrij (staging area) genoemd. De algemene manier van werken met Git gaat ongeveer zo: -1. Je bewerkt bestanden in je werkmap. -2. Je bereidt de bestanden voor, waardoor momentopnames worden toegevoegd aan de wachtrij. -3. Je maakt een commit. Een commit neemt alle momentopnames van de wachtrij en die permanent bewaard in je Gitmap. +1. Je bewerkt bestanden in je werk directory. +2. Je bereidt de bestanden voor (staged), waardoor momentopnames worden toegevoegd aan de wachtrij. +3. Je maakt een commit. Een commit neemt alle momentopnames van de wachtrij en bewaart die voorgoed in je Git directory. -Als een bepaalde versie van een bestand in de Gitmap staat, wordt het beschouwd als gecommit. Als het is aangepast, maar wel aan de wachtrij is toegevoegd, is het voorbereid. En als het veranderd is sinds het gekopieerd werd, maar niet voorbereid is, is het aangepast. In Hoofdstuk 2 leer je meer over deze toestanden en hoe je er voordeel van kunt hebben, maar ook hoe je de wachtrij compleet over kunt slaan. +Als een bepaalde versie van een bestand in de Git directory staat, wordt het beschouwd als gecommit. Als het is aangepast, maar wel aan de wachtrij is toegevoegd, is het staged. En als het veranderd is sinds het gekopiëerd werd, maar niet staged is, is het aangepast. In Hoofdstuk 2 leer je meer over deze toestanden en hoe je er je voordeel mee kunt doen, maar ook hoe je de wachtrij compleet over kunt slaan. ## Git installeren ## -Laten we eens een beetje Git gebruiken. Je kunt natuurlijk niet meteen beginnen — je moet het eerst installeren. Er zijn een aantal manieren om eraan te komen; de belangrijkste twee zijn installeren vanaf broncode of een bestaand pakket voor jouw platform gebruiken. +Laten we eens een wat Git gebruiken. Je kunt natuurlijk niet meteen beginnen — je moet het eerst installeren. Er zijn een aantal manieren om eraan te komen; de belangrijkste twee zijn installeren vanaf broncode of een bestaand pakket voor jouw platform gebruiken. ### Installeren vanaf de broncode ### -Als het mogelijk is, is het meestal handig om Git vanaf de broncode te installeren, omdat je dan altijd de nieuwste versie hebt. Elke versie van Git brengt meestal goede verbeteringen aan de gebruikersinterface met zich mee, dus de laatste versie is vaak de beste manier als je het gewoon bent software vanaf de broncode te compileren. Vaak hebben Linuxdistributies behoorlijk oude pakketten - tenzij je een hele up-to-date distro hebt of ‘backports’ (verbeteringen van een nieuwe versie op een oudere versie toepassen) gebruikt - is installeren vanaf broncode misschien wel de beste manier voor jou. +Als het mogelijk is, is het meestal nuttig om Git vanaf de broncode te installeren, omdat je dan altijd de recentste versie hebt. Elke versie van Git brengt meestal nuttige verbeteringen aan de gebruikersinterface met zich mee, dus de laatste versie is vaak de beste manier als je het gewend bent software vanaf de broncode te compileren. Vaak hebben Linuxdistributies behoorlijk oude pakketen - tenzij je een hele up-to-date distro hebt of ‘backports’ (verbeteringen van een nieuwe versie op een oudere versie toepassen) gebruikt - is installeren vanaf broncode misschien wel de beste manier voor jou. -Om Git te installeren heb je een aantal bibliotheken (‘libraries’) nodig: curl, zlib, openssl, expat, en libiconv. Als je bijvoorbeeld op een systeem werkt dat yum heeft (zoals Fedora) of apt-get (zoals systemen gebaseerd op Debian), kun je één van de volgende commando's gebruiken om alle bibliotheken waar Git van afhangt te installeren: +Om Git te installeren heb je een aantal bibliotheken (‘libraries’) nodig waar Git van afhankelijk is: curl, zlib, openssl, expat, en libiconv. Als je bijvoorbeeld op een systeem werkt dat yum heeft (zoals Fedora) of apt-get (zoals systemen gebaseerd op Debian), kun je één van de volgende commando's gebruiken om alle bibliotheken waar Git van afhankelijk is te installeren: $ yum install curl-devel expat-devel gettext-devel \ openssl-devel zlib-devel @@ -145,13 +145,13 @@ Daarna compileren en installeren: $ make prefix=/usr/local all $ sudo make prefix=/usr/local install -Als dat allemaal klaar is, kun je de nieuwste versie van Git uit Git ophalen met dit commando: +Als dat allemaal klaar is, kun je de ook nieuwste versie van Git met Git ophalen met dit commando: $ git clone git://git.kernel.org/pub/scm/git/git.git ### Op Linux installeren ### -Als je direct de uitvoerbare bestanden van Git op Linux wilt installeren, kun je dat normaal doen via het standaard pakketbeheersysteem dat meegeleverd is met je distributie. Als je Fedora gebruikt kun je yum gebruiken: +Als je direct de uitvoerbare bestanden van Git op Linux wilt installeren, kun je dat over het algemeen doen via het standaard pakketbeheersysteem dat meegeleverd is met je distributie. Als je Fedora gebruikt kun je yum gebruiken: $ yum install git-core @@ -168,7 +168,7 @@ Er zijn twee makkelijke manieren om Git op een Mac te installeren. De simpelste Insert 18333fig0107.png Figuur 1-7. Gitinstallatieprogramma voor OS X. -De andere veelgebruikte manier is om Git via MacPorts (`http://www.macports.org`) te installeren. Als je MacPorts hebt, kun je Git installeren met +De andere veelgebruikte manier is om Git via MacPorts (`http://www.macports.org`) te installeren. Als je MacPorts geïnstalleerd hebt, kun je Git installeren met $ sudo port install git-core +svn +doc +bash_completion +gitweb @@ -186,15 +186,15 @@ Opmerking voor Windows gebruikers: je zou Git moeten gebruiken met de msysGit sh ## Git klaarmaken voor eerste gebruik ## -Nu je Git op je computer hebt staan, is het handig dat je een paar dingen doet om je Gitomgeving aan je voorkeuren aan te passen. Je hoeft deze instellingen normaliter maar één keer te doen. Ze blijven hetzelfde als je een nieuwe versie van Git installeert. Je kunt ze op elk moment weer veranderen door de commando’s opnieuw uit te voeren. +Nu je Git op je computer hebt staan, is het handig dat je een paar dingen doet om je Gitomgeving aan je voorkeuren aan te passen. Je hoeft deze instellingen normaliter maar één keer te doen, ze blijven hetzelfde als je een nieuwe versie van Git installeert. Je kunt ze op elk moment weer veranderen door de commando’s opnieuw uit te voeren. Git bevat standaard een stuk gereedschap genaamd `git config`, waarmee je de configuratie-eigenschappen kunt bekijken en veranderen, die alle aspecten van het uiterlijk en gedrag van Git regelen. Deze eigenschappen kunnen op drie verschillende plaatsen worden bewaard: * Het bestand `/etc/gitconfig`: Bevat eigenschappen voor elk account op de computer en al hun repositories. Als je de optie `--system` meegeeft aan `git config`, zal het de configuratiegegevens in dit bestand lezen of veranderen. * Het bestand `~/.gitconfig`: Eigenschappen voor jouw account. Je kunt Git dit bestand laten gebruiken door de optie `--global` mee te geven. -* Het configuratiebestand in de Gitmap (dus `.git/config`) van het repository dat je op het moment gebruikt: Specifiek voor dat ene repository. Elk niveau is belangrijker dan het voorgaande, dus waarden in `.git/config` zullen worden gebruikt in plaats van die in `/etc/gitconfig`. +* Het configuratiebestand in de Gitmap (dus `.git/config`) van het repository dat je op het moment gebruikt: Specifiek voor die ene repository. Elk niveau neemt voorrang boven het voorgaande, dus waarden die in `.git/config` zijn gebruikt zullen worden gebruikt in plaats van die in `/etc/gitconfig`. -Op systemen met Windows zoekt Git naar het `.gitconfig` bestand in de `$HOME` map (`%USERPROFILE%` in een Windows omgeving), welke `C:\Documents and Settings\$USER` is of `C:\Users\$USER` voor de meeste mensen, afhankelijk van de versie (`$USER` is `%USERNAME%` in een Windows omgeving). Het kijkt ook nog naar `/etc/gitconfig`, maar dan op de plek waar je MSys hebt staan, wat de plek is waar je Git op je Windowscomputer geïnstalleerd hebt. +Op systemen met Windows zoekt Git in de `$HOME` directory naar het `.gitconfig`-bestand (`C:\Documents and Settings\$USER` voor de meesten). Het kijkt ook nog naar `/etc/gitconfig`, maar dan op de plek waar je MSys hebt staan, wat de plek is waar je Git op je Windowscomputer geïnstalleerd hebt. ### Jouw identiteit ### @@ -203,7 +203,7 @@ Het eerste wat je zou moeten doen nadat je Git geïnstalleerd hebt, is je gebrui $ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com -Nogmaals, dit hoef je maar één keer te doen als je de `--global` optie meegeeft, omdat Git die informatie zal gebruiken voor alles wat je doet op dat systeem. Als je een andere naam of e-mail wilt gebruiken voor specifieke projecten, kun je het commando uitvoeren zonder de `--global` optie als je in de map van dat project zit. +Nogmaals, dit hoef je maar één keer te doen als je de `--global` optie erbij opgeeft, omdat Git die informatie zal gebruiken voor alles wat je doet op dat systeem. Als je een andere naam of e-mail wilt gebruiken voor specifieke projecten, kun je het commando uitvoeren zonder de `--global` optie als je in de directory van dat project zit. ### Je tekstverwerker ### @@ -217,11 +217,11 @@ En andere bruikbare optie die je misschien wel wilt instellen is het standaard d $ git config --global merge.tool vimdiff -Git accepteert kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge en opendiff als geldige samenvoegingsgereedschappen. Je kunt ook een ander programma gebruiken; zie Hoofdstuk 7 voor meer informatie daarover. +Git accepteert kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge en opendiff als geldige samenvoegingsgereedschappen. Je kunt ook een ander programma gebruiken, zie Hoofdstuk 7 voor meer informatie daarover. ### Je instellingen bekijken ### -Als je je instellingen wilt zien, kan je `git config --list` gebruiken voor een lijstje met alle instellingen die Git vanaf de huidige map kan vinden: +Als je je instellingen wilt zien, kan je het `git config --list` commando gebruiken voor een lijstje met alle instellingen die Git vanaf de huidige locatie kan vinden: $ git config --list user.name=Scott Chacon @@ -251,7 +251,7 @@ Bijvoorbeeld, je kunt de gebruikershandleiding voor het commando `git config` kr $ git help config -Deze commando's zijn fijn omdat je ze overal kunt opvragen, zelfs als je offline bent. +Deze commando's zijn prettig omdat je ze overal kunt opvragen, zelfs als je offline bent. Als de gebruiksaanwijzing en dit boek niet genoeg zijn en je persoonlijke hulp nodig hebt, kan je de kanalen `#git` of `#github` (beiden Engelstalig) op het Freenode IRC netwerk (irc.freenode.net) proberen. Deze kanalen zijn regelmatig gevuld met honderden mensen die allemaal zeer ervaren zijn met Git en vaak bereidwillig om te helpen. ## Samenvatting ## From 3a76fc712f608eb566dfaafccaa4cb372cec28ad Mon Sep 17 00:00:00 2001 From: "J.M" Date: Tue, 21 Jan 2014 18:27:00 +0100 Subject: [PATCH 129/690] [de] Update localization summary in README --- de/README.md | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/de/README.md b/de/README.md index 5d72f1653..2f13c8319 100644 --- a/de/README.md +++ b/de/README.md @@ -13,26 +13,26 @@ In diesem Projekt kannst Du Dich nun austoben und Deinen Beitrag zur Übersetzun Beispielhaftes Vorgehen: git clone git@github.com:deinname/progit.git - + # Trage das deutsche Repository ebenso als Remote ein git remote add progit-de git@github.com:progit-de/progit.git - + # Lokalen Branch anlegen und daran arbeiten git checkout -b Chapter71 git commit -m "[de] Fix headings in chapter 7.1" - + # Wenn Deine Arbeit in sich abgeschlossen ist, kannst Du die Ergebnisse pushen. # Vor einem Push solltest Du allerdings prüfen, ob sich zwischenzeitlich # das Repository git@github.com:progit-de/progit.git aktualisiert hat. git fetch progit-de - - # Falls es sich aktualisiert hat, führe einen Rebase aus und + + # Falls es sich aktualisiert hat, führe einen Rebase aus und # behebe die ggf. aufgetretenden Konflikte git rebase progit-de/next - + # Pushe Deine Ergebnisse in Dein Github Repository git push origin - + Informiere uns jetzt mit einem Pull Request unter Github, dass Dein Branch fertiggestellt und bereit zum mergen ist. Wir werden dann Dein Ergebnis prüfen bzw. ein weiterer Helfer wird Dein Ergebnis reviewen. Das kann dazu führen, dass Du Deine Übersetzung noch überarbeiten musst. Siehe das Review als positive Hilfestellung damit das Ergebnis insgesamt besser wird und nimm die Kritik nicht negativ auf. Danach werden wir Deine Arbeit übernehmen und schließlich in den Hauptzweig unter progit/progit einpflegen. @@ -44,7 +44,7 @@ Die Commit Nachrichten beginnen mit einem vorangestellten [de], dann ein Leerzei Beispiel: [de] Remove comment for Figure 7-1 because it is shown on git-scm.com - + - Bla bla blub ## Vorgaben für das Übersetzen ## @@ -95,7 +95,7 @@ Beispiel: * Repository (Plural: Repositorys) * SHA-1 * SHA-1-Hash (Genitiv: SHA-1-Hashes) -* SHA-1-Hashwert (Plural: SHA-1-Hashwerte) +* SHA-1-Hashwert (Plural: SHA-1-Hashwerte) * SHA-1-Prüfsumme * SHA-1-Wert * stagen (gestaget, ungestaget) @@ -556,63 +556,63 @@ Bitte den Status nicht aktualisieren. Dies übernimmt ein Maintainer. Ja Nein Ja -Review notwendig +Ok 9.1 Ja Nein Ja -Review notwendig +Ok 9.2 Ja Nein Ja -Review notwendig +Ok 9.3 Ja Nein Ja -Review notwendig +Ok 9.4 Teilweise Nein Ja -Review notwendig +Ok 9.5 Ja Nein Ja -Review notwendig +Ok 9.6 Ja Nein Ja -Review notwendig +Ok 9.7 Ja Nein Ja -Review notwendig +Ok 9.8 Ja Nein Ja -Review notwendig +Ok Index of Commands From 4665f774ee823f809d0d6108334fe2e7e5ca4025 Mon Sep 17 00:00:00 2001 From: Broda Noel Date: Wed, 22 Jan 2014 17:04:23 -0300 Subject: [PATCH 130/690] [es] Fixed semantics errors --- es/05-distributed-git/01-chapter5.markdown | 350 ++++++++++++++++++++- 1 file changed, 346 insertions(+), 4 deletions(-) diff --git a/es/05-distributed-git/01-chapter5.markdown b/es/05-distributed-git/01-chapter5.markdown index 91972492e..083205c9a 100644 --- a/es/05-distributed-git/01-chapter5.markdown +++ b/es/05-distributed-git/01-chapter5.markdown @@ -27,7 +27,7 @@ Al permitir multiples repositorios remotos, en Git es posible tener un flujo de 1. La persona gestora del proyecto envia (push) a su repositorio público (repositorio principal). 2. Una persona que desea contribuir, clona dicho repositorio y hace algunos cambios. 3. La persona colaboradora envia (push) a su propia copia pública. -4. Esta persona colaboradora envia a la gestora un correo-e solicitándole recupere e integre los cambios. +4. Esta persona colaboradora envia a la gestora un correo electronico solicitándole recupere e integre los cambios. 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. @@ -299,7 +299,7 @@ Quedando su repositorio como se muestra en la Figura 5-12 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 electronico 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 ... @@ -323,7 +323,7 @@ Pero hay un pequeño problema, necesita enviar el trabajo fusionado en su rama ' Esto es lo que se denomina un _refspec_. Puedes ver el Capítulo 9 para una discusión más detallada acerca de los _refspecs_ de Git y los distintos usos que puedes darles. -A continuación, John envia un correo-e a jessica comentandole que ha enviado algunos cambios a la rama 'featureA' y pidiendole que los verifique. Ella lanza un 'git fetch' para recuperar dichos cambios: +A continuación, John envia un correo electronico a jessica comentandole que ha enviado algunos cambios a la rama 'featureA' y pidiendole que los verifique. Ella lanza un 'git fetch' para recuperar dichos cambios: $ git fetch origin ... @@ -545,4 +545,346 @@ Tras esto, Git escupirá una serie de información de registro, con pinta más o To: jessica@example.com Subject: [PATCH 1/2] added limit to log function Date: Sat, 30 May 2009 13:29:15 -0700 - Message-Id: <12437153 + 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 + +En estos momentos, deberías poder ir a tu carpeta de borradores (Drafts), cambiar el destinatario (To) para apuntar a la lista de correo donde estés enviando el parche, puede que poner en copia (CC) al gestor o persona responsable, y enviar el mensaje. + +### Recapitulación ### + +En esta sección hemos visto unos cuantos de los flujos de trabajo más habituales para lidiar con distintos tipos de proyectos Git. Y hemos introducido un par de nuevas herramientas para ayudarte a gestionar estos procesos. A continuación veremos cómo trabajar en el otro lado de la moneda: manteniendo y gestionando un proyecto Git. Vas a aprender cómo ser un dictador benevolente o un gestor de integración. + +## Gestionando un proyecto ## + +Además de conocer cómo contribuir de forma efectiva a un proyecto, es posible que desees saber tambien cómo mantener uno. Lo cual implicará saber aceptar y aplicar parches generados vía `format-patch`, enviados a tí a través de correo electronico; o saber integrar cambios realizados en ramas de repositorios que añadirás como remotos a tu proyecto. Tanto si gestionas un repositorio canónico, como si deseas colaborar verificando o aprobando parches, necesitas saber cómo aceptar trabajo de otros de la forma más clara para tus contribuyentes y más sostenible para tí a largo plazo. + +### 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--. +Como recordarás, la forma de crear una rama basandola en tu rama master es: + + $ git branch sc/ruby_client master + +O, si deseas crearla y saltar inmediatamente a ella, puedes también utilizar la opción '-b' del comando 'checkout': + + $ git checkout -b sc/ruby_client master + +Tras esto, estarás listo para añadir tu trabajo a esa rama puntual y ver si deseas o no fusionarla luego con alguna otra de tus ramas de más largo recorrido. + +### Aplicar parches recibidos por correo electronico ### + +Si vas a integrar en tu proyecto un parche recibido a través de un correo electrónico. Antes de poder evaluarlo, tendrás que incorporarlo a una de tus ramas puntuales. Tienes dos caminos para incorporar un parche recibido por correo electronico: usando el comando 'git apply' o usando el comando 'git am'. + +#### Incorporando un parche con apply #### + +Si recibes un parche de alguien que lo ha generado con el comando 'git diff' o con un comando 'diff' de Unix, puedes incorporalo con el comando 'git apply'. Suponiendo que has guardado el parche en '/tmp/patch-ruby-client.patch', puedes incorporarlo con una orden tal como: + + $ git apply /tmp/patch-ruby-client.patch + +Esto modificará los archivos en tu carpeta de trabajo. Es prácticamente idéntico a lanzar el comando 'patch -p1', aunque es más paranoico y acepta menos coincidencias aproximadas. Además, es capaz de manejar adicciones, borrados o renombrados de archivos, si vienen en formato 'git diff'. Mientras que 'patch' no puede hacerlo. Por ultimo, citar que 'git apply' sigue un modelo de "aplicar todo o abortar todo", incorporando todos los cambios o no incorporando ninguno. Mientras que 'patch' puede incorporar cambios parcialmente, dejando tu carpeta de trabajo en un estado inconsistente. 'git apply' es, de lejos, mucho más paranoico que 'patch'. Nunca creará una confirmación de cambios (commit) por tí, --tras ejecutar el comando, tendrás que preparar (stage) y confirmar (commit) manualmente todos los cambios introducidos--. + +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 + error: patch failed: ticgit.gemspec:1 + error: ticgit.gemspec: patch does not apply + +Si obtienes una salida vacia, el parche se podrá incorporar limpiamente. Además, este comando retorna con un status no-cero en caso de fallar la comprobación, por lo que puedes utilizarlo en scripts si lo deseas. + +#### Incorporando un parche con am #### + +Si la persona que contribuye es usuaria de Git y conoce lo suficiente como para utilizar el comando 'format-patch' al generar su parche, tendrás mucho camino recorrido al incorporarlo; ya que el parche traerá consigo información sobre el o la autora, además de un mensaje de confirmación de cambios. Si puedes, anima a tus colaboradoras a utilizar 'format-patch' en lugar de 'diff' cuando vayan a generar parches. Solo deberías utilizar 'git apply' en caso de parches antiguos y similares. + +Para incorporar un parche generado con 'format-patch', utilizarás el comando 'git am'. Técnicamente, 'git am' se construyó para leer un archivo de buzón de correo (mbox file), que no es más que un simple formato de texto plano para almacenar uno o varios mensajes de correo electrónico en un solo archivo de texto. Es algo parecido a esto: + + 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 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. + +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 + 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: + + $ 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 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. + +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 + 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". + +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 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 + 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. + +En este caso, estamos intentando incorporar un parche que ya tenemos incorporado. Sin la opción '-3', tendríamos problemas. + +Al aplicar varios parches desde un mbox, puedes lanzar el comando 'am' en modo interactivo; haciendo que se detenga en cada parche y preguntandote si aplicarlo o no: + + $ 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 + +Es una utilidad interesante si tienes tienes almacenados unos cuantos parches, porque puedes ir revisando previamente cada parche y aplicarlos selectivamente. + +Cuando tengas integrados y confirmados todos los parches relativos al tema puntual en que estas trabajando, puedes plantearte cómo y cuándo lo vas a integar en alguna otra rama de más largo recorrido. + +### Recuperando ramas remotas ### + +Si recibes una contribución de un usuario que ha preparado su propio repositorio, ha guardado unos cuantos cambios en este, y luego te ha enviado la URL del repositorio y el nombre de la rama remota donde se encuentran los cambios. Puedes añadir dicho repositorio como un remoto y fusionar los cambios localmente. + +Por ejemplo, si Jessica te envia un correo electrónico comentandote que tiene una nueva e interesante funcionalidad en la rama 'ruby-client' de su repositorio. Puedes probarla añadiendo el remoto correspondiente y recuperando localmente dicha rama. + + $ git remote add jessica git://github.com/jessica/myproject.git + $ git fetch jessica + $ git checkout -b rubyclient jessica/ruby-client + +Si más tarde vuelva a enviarte otro correo electronico avisandote de otra gran funcionalidad que ha incorporado, puedes recuperarla (fetch y checkout) directamente, porque tienes el remoto ya definido. + +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 electronico; 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. + +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: + + $ git pull git://github.com/onetimeguy/project.git + From git://github.com/onetimeguy/project + * branch HEAD -> FETCH_HEAD + Merge made by recursive. + +### Revisando lo introducido ### + +Ahora que tienes una rama puntual con trabajo aportado por otras personas. Tienes que decidir lo que deseas hacer con él. En esta sección revisaremos un par de comandos, que te ayudarán a ver exactamente los cambios que introducirás si fusionas dicha rama puntual con tu rama principal. + +Suele ser util revisar todas las confirmaciones de cambios (commits) que esten es esta rama, pero no en tu rama principal. Puedes excluir de la lista las confirmaciones de tu rama principal añadiendo la opción '--not' delante del nombre de la rama. Por ejemplo, si la persona colaboradora te envia dos parches y tu creas una rama 'contrib' donde aplicar dichos parches; puedes lanzar algo como esto: + + $ 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 + +Para ver en detalle los cambios introducidos por cada confirmación (commit), recuerda que pasando la opción '-p' al comando 'git log', obtendrás un listado extendido con las diferencias introducidas por cada confirmación. + +Para ver plenamente todas las diferencias y lo que sucederá realmente si fusionas esta rama puntual con otra rama, tendrás que utilizar un pequeño truco para obtener los resultados correctos. Puedes pensar en lanzar esto: + + $ git diff master + +Este comando te dará las diferencias, pero puede ser engañoso. Si tu rama 'master' ha avanzado con respecto al momento en que se creó la rama puntual a partir de ella, puedes obtener resultados realmente extraños. Debido a que Git compara directamente las instantáneas de la última confirmación de cambios en la rama puntual donde te encuentras y en la rama 'master'. Por ejemplo, si en la rama 'master' habias añadido una línea a un archivo, la comparación directa de instantáneas te llevará a pensar que la rama puntual va a borrar dicha línea. + +Si 'master' es un ancestro directo de tu rama puntual, no tendrás problemas. Pero si los historiales de las dos ramas son divergentes, la comparación directa de diferencias dará la apariencia de estar añadiendo todo el material nuevo en la rama puntual y de estar borrando todo el material nuevo en la rama 'master'. + +Y lo que realmente querías ver eran los cambios introducidos por la rama puntual, --el trabajo que vas a introducir si la fusionas con la rama 'master'--. Lo puedes hacer indicando a Git que compare la última confirmación de cambios en la rama puntual, con el más reciente ancestro común que tenga esta respecto de la rama 'master'. + +Técnicamente, lo puedes hacer descubriendo tu mismo dicho ancestro común y lanzando la comprobación de diferencias respecto de él: + + $ git merge-base contrib master + 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 + $ 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: + + $ git diff master...contrib + +Este comando mostrará únicamente el trabajo en tu actual rama puntual que haya sido introducido a partir de su ancestro común con la rama 'master'. Es una sintaxis muy util, que merece recordar. + +### Integrando el trabajo aportado por otros ### + +Cuando todo el trabajo presente en tu rama puntual esté listo para ser integrado en una rama de mayor rango, la cuestión es cómo hacerlo. Yendo aún más lejos, ?cual es el sistema de trabajo que deseas utilizar para el mantenimiento de tu proyecto? Tienes bastantes opciones, y vamos a ver algunas de ellas. + +#### Fusionando flujos de trabajo #### + +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 +Figura 5-19. Historial con varias ramas puntuales. + +Insert 18333fig0520.png +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). + +Insert 18333fig0521.png +Figura 5-21. Antes de fusionar una rama puntual. + +Insert 18333fig0522.png +Figura 5-22. Tras fusionar una rama puntual. + +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. +Puedes continuar ampliando este concepto, disponiendo de una rama 'integrate' donde ir fusionando todo el trabajo entre sí. A continuación, cuando el código en dicha rama sea estable y pase todas las pruebas, la fusionarás con la rama 'develop'; y, cuando se demuestre que permanece estable durante un cierto tiempo, avanzarás la rama 'master' hasta ahí. + +#### Flujos de trabajo con grandes fusiones #### + +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 +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 +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. + +#### Flujos de trabajo reorganizando o entresacando #### + +Otros gestores de mantenimiento, al procesar el trabajo recibido de las personas colaboradoras, en lugar de fusiones (merge), suelen preferir reorganizar (rebase) o entresacar (cherry-pick) sobre su propia rama principal; obteniendo así un historial prácticamente lineal. Cuando desees integrar el trabajo que tienes en una rama puntual, te puedes situar sobre ella y lanzar el comando 'rebase'; de esta forma recompondrás los cambios encima de tu actual rama 'master' (o 'develop' o lo que corresponda). Si funciona, se realizará un avance rápido (fast-forward) en tu rama 'master', y acabarás teniendo un historial lineal en tu proyecto. + +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 +Figura 5-26. Historial de ejemplo, antes de entresacar. + +Si deseas integar únicamente la confirmación 'e43a6' en tu rama 'master', puedes lanzar: + + $ 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(-) + +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 +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. + +### Marcando tus lanzamientos de versiones ### + +Cuando decides dar por preparada una versión, probablemente querrás etiquetar dicho punto de algún modo; de tal forma que, más adelante, puedas volver a generar esa versión en cualquier momento. Puedes crear una nueva etiqueta tal y como se ha comentado en el capítulo 2. Si decides firmar la etiqueta como gestor de mantenimientos que eres, el proceso será algo como: + + $ 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 + +Si firmas tus etiquetas, puedes tener un problema a la hora de distribuir la clave PGP pública utilizada en la firma. Los gestores del proyeto Git ha resuelto este problema incluyendo sus claves públicas como un objeto en el repositorio, añadiendo luego una etiqueta apuntando directamente a dicho contenido. Para ello, has de seleccionar cada clave que deseas incluir, lanzando el comando '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] + +Tras esto, puedes importar directamente la clave en la base de datos Git, exportandola y redirigiendola a través del comando 'git hash-object'. Para, de esta forma, escribir un nuevo objeto dentro de Git y obtener de vuelta la firma SHA-1 de dicho objeto. + + $ gpg -a --export F721C45A | git hash-object -w --stdin + 659ef797d181633c87ec71ac3f9ba29fe5775b92 + +Una vez tengas el contenido de tu clave guardado en Git, puedes crear una etiquta que apunte directamente al mismo; indicando para ello el nuevo valor SHA-1 que te ha devuelto el objeto 'hash-object': + + $ 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:, + + $ git show maintainer-pgp-pub | gpg --import + +De esta forma, pueden utilizar esa clave para verificar todas las etiquetas que firmes. Además, si incluyes instrucciones en el mensaje de etiquetado, con el comando `git show `, los usuarios podrán tener directrices específicas acerca de la verificación de etiquetas. + +### Generando un número de ensamblado ### + +Debido a que Git no dispone de una serie monótona ascendente de números para cada confirmación de cambios (commit), si deseas tener un nombre humanamente comprensible por cada confirmación, has de utilizar el comando 'git describe'. Git te dará el nombre de la etiqueta más cercana, mas el número de confirmaciones de cambios entre dicha etiqueta y la confirmación que estas describiendo, más una parte de la firma SHA-1 de la confirmación: + + $ git describe master + v1.6.2-rc1-20-g8c5b85c + +De esta forma, puedes exportar una instantánea u obtener un nombre comprensible por cualquier persona. Es más, si compilas Git desde código fuente clonado desde el repositorio Git, el comando 'git --version' te dará algo parecido. Si solicitas descripción de una confirmación de cambios (commit) etiquetada directamente con su propia etiqueta particular, obtendrás dicha etiqueta como descripción. + +El comando 'git describe' da preferencia a las etiquetas anotativas (etiquetas creadas con las opciones '-a' o '-s'). De esta forma las etiquetas para las versiones pueden ser creadas usando 'git describe', asegurandose el que las confirmaciones de cambios (commit) son adecuadamente nombradas cuando se describen. Tambien puedes utilizar esta descripción para indicar lo que deseas activar (checkout) o mostrar (show); pero realmente estarás usando solamente la parte final de la firma SHA-1 abreviada, por lo que no siempre será válida. Por ejemplo, el kernel de Linux ha saltado recientemente de 8 a 10 caracteres, para asegurar la unicidad de los objetos SHA-1; dando como resultado que los nombres antiguos de 'git describe' han dejado de ser válidos. + +### Preparando un lanzamiento de versión ### + +Si quieres lanzar una nueva versión. Una de las cosas que desearas crear es un archivo con la más reciente imagen de tu código, para aquellas pobres almas que no utilizan Git. El comando para hacerlo es 'git archive': + + $ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz + $ ls *.tar.gz + v1.6.2-rc1-20-g8c5b85c.tar.gz + +Quien abra ese archivo tarball, obtendrá la más reciente imagen de tu proyecto; puesta bajo una carpeta de proyecto. También puedes crear un archivo zip de la misma manera, tan solo indicando la opción '--format=zip' al comando 'git archive': + + $ git archive master --prefix='project/' --format=zip > `git describe master`.zip + +Así, tendrás sendos archivos tarball y zip con tu nueva versión, listos para subirlos a tu sitio web o para ser enviados por correo electrónico a tus usuarios. + +### El registro rápido ### + +Ya va siendo hora de enviar un mensaje a tu lista de correo, informando a las personas que desean conocer la marcha de tu proyecto. Una manera elegante de generar rápidamente una lista con los principales cambios añadidos a tu proyecto desde la anterior versión, es utilizando el comando 'git shortlog'. Este comando resume todas las confirmaciones de cambios (commits) en el rango que le indiques. Por ejemplo, si tu último lanzamiento de versión lo fué de la 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 + +Obtendrás un claro resumen de todas las confirmaciones de cambios (commit) desde la versión v1.0.1, agrupadas por autor, y listas para ser incorporadas en un mensaje a tu lista de correo. + +## Recapitulación ## + +A estas alturas, deberías sentirte confortable tanto contribuyendo a un proyecto, como manteniendo tu propio proyecto o integrando contribuciones de otras personas. Felicidades por haber llegado a ser un desarrollador Git efectivo!. En el capítulo siguiente, aprenderás el uso de más herramientas avanzadas y algunos trucos para tratar con situaciones complejas; haciendo de tí un verdadero maestro Git. From c51d3b7e0f81fe98ad980a9e1b8832a6a274cca0 Mon Sep 17 00:00:00 2001 From: Wojciech Krawczyk Date: Sun, 26 Jan 2014 17:43:23 +0100 Subject: [PATCH 131/690] Fix misspellings --- pl/05-distributed-git/01-chapter5.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pl/05-distributed-git/01-chapter5.markdown b/pl/05-distributed-git/01-chapter5.markdown index 61032e009..fd5408ae4 100644 --- a/pl/05-distributed-git/01-chapter5.markdown +++ b/pl/05-distributed-git/01-chapter5.markdown @@ -377,15 +377,15 @@ Figure 5-11. Sekwencja zdarzeń dla prostego przepływu zmian między programist ### Prywatne zarządzane zespoły ### -W tym scenariuszu, zobaczysz jak działa współpraca w większych prywatnych grupach. Nauczysz się jak pracować w środowisku w którym małe grupy współpracują ze sobą nad funkcjonalnościami, a następnie stworzone przez nich zmiany są integrowane przez inną osobą. +W tym scenariuszu, zobaczysz jak działa współpraca w większych prywatnych grupach. Nauczysz się jak pracować w środowisku w którym małe grupy współpracują ze sobą nad funkcjonalnościami, a następnie stworzone przez nich zmiany są integrowane przez inną osobę. -Załóżmy że John i Jessica wspólnie pracują nad jedną funkcjonalnością, a Jessica i Josie nad drugą. W taj sytuacji, organizacja używa przepływu pracy z osobą integrującą zmiany, w której wyniki pracy poszczególnych grup są integrowane przez wyznaczone osoby, a gałąź `master` może być jedynie przez nie aktualizowana. W tym scenariuszu, cała praca wykonywana jest w osobnych gałęziach zespołów, a następnie zaciągana przez osoby integrujące. +Załóżmy że John i Jessica wspólnie pracują nad jedną funkcjonalnością, a Jessica i Josie nad drugą. W tej sytuacji, organizacja używa przepływu pracy z osobą integrującą zmiany, w której wyniki pracy poszczególnych grup są integrowane przez wyznaczone osoby, a gałąź `master` może być jedynie przez nie aktualizowana. W tym scenariuszu, cała praca wykonywana jest w osobnych gałęziach zespołów, a następnie zaciągana przez osoby integrujące. -Prześledźmy sposób pracy Jessici w czasie gdy pracuje ona nad obiema funkcjonalnościami, współpracując jednocześnie z dwoma niezależnymi programistami. Zakładając że ma już ona sklonowane repozytorium, rozpoczyna pracę nad funkcjonalnością `featureA`. Tworzy nową gałąź dla niej i wprowadza w niej zmiany: +Prześledźmy sposób pracy Jessici w czasie gdy pracuje ona nad obiema funkcjonalnościami, współpracując jednocześnie z dwoma niezależnymi programistami. Zakładając że ma już sklonowane repozytorium, rozpoczyna pracę nad funkcjonalnością `featureA`. Tworzy nową gałąź dla niej i wprowadza w niej zmiany: From 3f404d1f1c475070b223db66f790372b3ae9a7ec Mon Sep 17 00:00:00 2001 From: Zhenye YU Date: Tue, 28 Jan 2014 15:25:34 +0800 Subject: [PATCH 132/690] [zh] Change font of pdf format to 'WenQuanYi Micro Hei', which looks better --- latex/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/latex/config.yml b/latex/config.yml index 2ed0f7939..33d11a1e7 100644 --- a/latex/config.yml +++ b/latex/config.yml @@ -15,9 +15,9 @@ default: thanks: "This is the PDF file for the Pro Git book contents. It is licensed under the Creative Commons Attribution-Non Commercial-Share Alike 3.0 license. I hope you enjoy it, I hope it helps you learn Git, and I hope you'll support Apress and me by purchasing a print copy of the book at Amazon: \\url{http://tinyurl.com/amazonprogit}" zh: langrule: "\\XeTeXlinebreakskip=0em plus 0.1em minus 0.01em\n\\XeTeXlinebreakpenalty=0" - font: AR PL UMing CN - bold: AR PL UKai CN - mono: AR PL UKai CN + font: WenQuanYi Micro Hei + bold: WenQuanYi Micro Hei Mono + mono: WenQuanYi Micro Hei Mono prechap: "第" postchap: "章" presect: "" From 3da5f7c481fe4d59c9487762833a4c4c06e5bb7b Mon Sep 17 00:00:00 2001 From: Cor Date: Wed, 29 Jan 2014 09:23:50 +0100 Subject: [PATCH 133/690] [nl] Retranslate chapter 03 Reshuffle wording and sentences. Replace some Babelfish type translations with more sensible translations. Introduce diacritics to enhance clarity. --- nl/03-git-branching/01-chapter3.markdown | 262 +++++++++++------------ 1 file changed, 131 insertions(+), 131 deletions(-) diff --git a/nl/03-git-branching/01-chapter3.markdown b/nl/03-git-branching/01-chapter3.markdown index c850eb23a..78dc75ca0 100644 --- a/nl/03-git-branching/01-chapter3.markdown +++ b/nl/03-git-branching/01-chapter3.markdown @@ -1,38 +1,38 @@ # Branchen in Git # -Bijna elk versiebeheersysteem ondersteunt een bepaalde vorm van branchen. Branchen komt erop neer dat je een tak afsplitst van de grote lijn van de ontwikkeling en daar verder mee werkt zonder de hoofdlijn te vervuilen. Bij veel VCS'en gaat dat nogal moeizaam, en eisen vaak van je dat je een nieuwe kopie maakt van de map waar je bronbestanden in staan, wat lang kan duren voor grote projecten. +Bijna elk versiebeheersysteem ondersteunt een bepaalde vorm van branchen. Branchen komt erop neer dat je een tak afsplitst van de hoofd ontwikkellijn en daar verder mee gaat werken zonder aan de hoofdlijn te komen. Bij veel VCS'en is dat nogal een duur proces, vaak wordt er een nieuwe kopie gemaakt van de directory waar je broncode in staan, wat lang kan duren voor grote projecten. -Sommige mensen verwijzen naar het branch model in Git als de "killer eigenschap", en het maakt Git zeker apart in de VCS gemeenschap. Waarom is het zo bijzonder? De manier waarop Git branched is ongelooflijk lichtgewicht, waardoor branch operaties vrijwel instant zijn en het wisselen tussen de branches over het algemeen net zo snel. In tegenstelling to vele andere VCS's, moedigt Git een werkwijze aan die vaak branched en merged, zelfs meerdere keren per dag. Deze eigenschap begrijpen en beheersen geeft je een krachtig en uniek gereedschap en kan letterlijk de manier waarop je ontwikkelt veranderen. +Sommige mensen verwijzen naar het branch model in Git als de "killer eigenschap", en het onderscheidt Git zeker in de VCS gemeenschap. Waarom maakt het zo bijzonder? De manier waarop Git branched is ongelooflijk lichtgewicht, waardoor branch operaties vrijwel instant zijn en het wisselen tussen de branches over het algemeen net zo snel. In tegenstelling to vele andere VCS's, moedigt Git juist een werkwijze aan die vaak branched en merged, zelfs meerdere keren per dag. Deze eigenschap begrijpen en de techniek beheersen geeft je een krachtig en uniek gereedschap en kan letterlijk de manier waarop je ontwikkelt veranderen. ## Wat een branch is ## -Om de manier waarop Git branched echt te begrijpen, moeten we een stap terug doen en onderzoeken hoe Git zijn gegevens opslaat. Zoals je je kunt herinneren van Hoofdstuk 1, slaat Git zijn gegevens niet op als een reeks van sets met wijzigingen of delta's, maar in plaats daarvan als een serie snapshots. +Om de manier waarop Git branched echt te begrijpen, moeten we een stap terug doen en onderzoeken hoe Git zijn gegevens opslaat. Zoals je misschien herinnert van Hoofdstuk 1, slaat Git zijn gegevens niet op als een reeks van wijzigingen of delta's, maar in plaats daarvan als een serie snapshots. -Als je in Git commit, dan slaat Git een commit object op dat een verwijzing bevat naar het snapshot van de inhoud die je gestaged hebt, de auteur en bericht metagegevens, en nul of meer verwijzingen naar de commit of commits die de directe ouders van deze commit waren: nul ouders voor de eerste commit, één ouder voor een normale commit, en meerdere ouders voor een commit die resulteert uit een samenvoeging of twee of meer branches. +Als je in Git commit, dan slaat Git een commit object op dat een verwijzing bevat naar het snapshot van de inhoud die je gestaged hebt, de auteur en bericht metagegevens, en nul of meer verwijzingen naar de commit of commits die de directe ouders van deze commit waren: nul ouders voor de eerste commit, één ouder voor een normale commit, en meerdere ouders voor een commit die het resultaat is van een merge van twee of meer branches. -Om dit te visualiseren, laten we aannemen dat je een map hebt die drie bestanden bevat, en je staged ze allemaal en commit. Door de bestanden te stagen krijgen ze allen een checksum (de SHA-1 hash die we in Hoofdstuk 1 noemden), bewaart die versie van het bestand in het Git repository (Git verwijst ernaar als blobs), en voegt die checksum toe aan het stage gebied: +Om dit te visualiseren, gaan we aannemen dat je een directory hebt met drie bestanden, en je staged en commit ze allemaal. Door de bestanden te stagen krijgen ze allemaal een checksum (de SHA-1 hash waar we het in Hoofdstuk 1 over hadden), bewaart die versie van het bestand in het Git repository (Git noemt ze blobs), en voegt die checksum toe aan het stage gebied: $ git add README test.rb LICENSE $ git commit -m 'initial commit of my project' -Als je de commit aanmaakt door `git commit` uit te voeren, zal Git iedere submap van een checksum voorzien (in dit geval, alleen de hoofdmap); en die drie objecten in het Git repository opslaan. Daarna creëert Git een commit object dat de metagegevens bevat en een verwijzing naar de hoofd project boom zodat het het snapshot kan namaken als dat nodig is. +Als je de commit aanmaakt door `git commit` uit te voeren zal Git iedere project directory van een checksum voorzien en slaat ze als boomstructuur (`tree`) objecten in de Git repository op. Daarna creëert Git een `commit` object dat de metagegevens bevat en een verwijzing naar de hoofd project `tree`-object zodat Git deze snapshot kan opnieuw kan maken als dat nodig is. -Je Git repository bevat nu vijf objecten: een blob voor de inhoud van ieder van je drie bestanden, een boom dat de inhoud van de map weergeeft en specificeert welke bestandsnamen opgeslagen zijn als welke blobs, en een commit met de verwijzing naar die hoofd boom en alle commit metagegevens. Conceptueel zien de gegevens in je Git repository eruit zoals in Figuur 3-1. +Je Git repository bevat nu vijf objecten: een blob voor de inhoud van ieder van de drie bestanden, een tree die de inhoud van de directory weergeeft en specificeert welke bestandsnamen opgeslagen zijn als welke blobs, en een commit met de verwijzing naar die hoofd tree en alle commit metagegevens. Conceptueel zien de gegevens in je Git repository eruit zoals in Figuur 3-1. Insert 18333fig0301.png -Figuur 3-1. Enkele commit repository gegevens. +Figuur 3-1. Repository gegevens van een enkele commit. -Als je wat wijzigingen doet en nogmaals commit, dan slaat de volgende commit een verwijzing op naar de commit die er direct aan vooraf ging. Na nog eens twee commits, zal je historie er misschien uit zien als Figuur 3-2. +Als je wat wijzigingen maakt en nogmaals commit, dan slaat de volgende commit een verwijzing op naar de commit die er direct aan vooraf ging. Na nog eens twee commits, zal je historie er ongeveer uit zien als Figuur 3-2. Insert 18333fig0302.png Figuur 3-2. Git object gegevens voor meerdere commits. -Een branch in Git is simpelweg een lichtgewicht verplaatsbare verwijzing naar een van deze commits. De standaard branch naam in Git is master. Als je initieel commits maakt, dan wordt je een master branch gegeven die wijst naar de laatste commit die je gemaakt hebt. Iedere keer als je commit, beweegt het automatisch vooruit. +Een branch in Git is simpelweg een lichtgewicht verplaatsbare verwijzing naar een van deze commits. De standaard branch naam in Git is master. Als je initieel commits maakt, dan krijg je een `master` branch die wijst naar de laatste commit die je gemaakt hebt. Iedere keer als je commit, beweegt het automatisch vooruit. Insert 18333fig0303.png Figuur 3-3. Branch wijzend in de commit gegevens historie. -Wat gebeurt er als je een nieuwe branch maakt? Wel, door dat te doen wordt een nieuwe verwijzing aangemaakt voor jou om te verplaatsen. Laten we zeggen dat je een nieuwe branch genaamd testing maakt. Je doet dit met het `git branch` commando: +Wat gebeurt er als je een nieuwe branch maakt? Door dat te doen wordt een nieuwe verwijzing voor jou aangemaakt die je dan kunt verplaatsen. Laten we zeggen dat je een nieuwe branch genaamd testing maakt. Je doet dit met het `git branch` commando: $ git branch testing @@ -41,12 +41,12 @@ Dit maakt een nieuwe verwijzing naar dezelfde commit waar je nu op zit (zie Figu Insert 18333fig0304.png Figuur 3-4. Meerdere branches wijzend naar de commit gegevens historie. -Hoe weet Git op welke branch je nu zit? Het houdt een speciale verwijzing bij genaamd HEAD. Let op dat dit heel anders is dan het concept van HEAD in andere VCS's waar je misschien gewend aan bent, zoals bijvoorbeeld Subversion of CVS. In Git, is dit een verwijzing naar de lokale branch waar je nu op zit. In dit geval, zit je nog steeds op master. Het git branch commando heeft alleen een nieuwe branch aangemaakt — het is nog niet omgeschakeld naar die branch (zie Figuur 3-5). +Hoe weet Git op welke branch je nu zit? Het houdt een speciale verwijzing bij genaamd HEAD. Let op dat dit heel anders is dan het concept van HEAD in andere VCS's waar je misschien gewend aan bent, zoals bijvoorbeeld Subversion of CVS. In Git, is dit een verwijzing naar de lokale branch waar je nu op zit. In dit geval, zit je nog steeds op master. Het git branch commando heeft alleen een nieuwe branch aangemaakt — het is nog niet overgeschakeld naar die branch (zie Figuur 3-5). Insert 18333fig0305.png Figuur 3-5. HEAD bestand wijzend naar de branch waar je op zit. -Om te schakelen naar een bestaande branch, voer je het `git checkout` commando uit. Laten we eens omschakelen naar de nieuwe testing branch: +Om over te schakelen naar een bestaande branch, voer je het `git checkout` commando uit. Laten we eens overschakelen naar de nieuwe testing branch: $ git checkout testing @@ -65,7 +65,7 @@ Figuur 3-7 toont het resultaat. Insert 18333fig0307.png Figuur 3-7. De branch waar HEAD naar wijst gaat vooruit met iedere commit. -Dit is interessant, omdat je testing branch nu vooruit is gegaan, maar je master branch nog steeds wijst naar de commit waar je op was toen je `git checkout` uitvoerde om om te schakelen. Laten we eens terugschakelen naar de master branch: +Dit is interessant, omdat je testing branch nu vooruit is gegaan, maar je master branch nog steeds wijst naar de commit waar je op was toen je `git checkout` uitvoerde voor het overschakelen. Laten we eens terugschakelen naar de `master` branch: $ git checkout master @@ -74,21 +74,21 @@ Figuur 3-8 toont het resultaat. Insert 18333fig0308.png Figuur 3-8. HEAD verschuift naar een andere branch bij een checkout. -Dat commando deed twee dingen. Het verplaatste de HEAD verwijzing terug naar de master branch, en het draaide de bestanden in je werkmap terug naar het snapshot waar master naar wijst. Dit betekent ook dat de wijzigingen die je vanaf dit punt maakt zullen afwijken van een oudere versie van het project. Het betekent in essentie dat het het werk dat je in je testing branch hebt gedaan tijdelijk terugdraait zodat je in een andere richting kunt gaan. +Dat commando heeft twee dingen gedaan. Het verplaatste de HEAD verwijzing terug naar de `master` branch, en het draaide de bestanden in je werkdirectory terug naar het snapshot waar die `master` naar wijst. Dit betekent ook dat de wijzigingen die je vanaf dit punt maakt uiteen zullen gaan lopen met een oudere versie van het project. In essentie betekent dat het werk dat je in je testing branch hebt gedaan tijdelijk wordt teruggedraait, zodat je een andere richting op kunt gaan. -Laten we een paar wijzigingen doen en nog eens committen: +Laten we een paar wijzigingen maken en nog eens committen: $ vim test.rb $ git commit -a -m 'made other changes' -Nu is je project historie afgeweken (zie Figuur 3-9). Je hebt een branch gemaakt en bent er naartoe omgeschakeld, hebt er wat werk op gedaan, en bent toen teruggeschakeld naar je hoofd branch en hebt nog ander werk gedaan. Beide van die veranderingen zijn geïsoleerd van elkaar in aparte branches: je kunt heen en weer schakelen tussen de branches en ze samenvoegen als je klaar bent. En je hebt dat alles gedaan met eenvoudige `branch` en `checkout` commando's. +Nu is je project historie uiteen gelopen (zie Figuur 3-9). Je hebt een branch gemaakt en bent er naartoe overgeschakeld, hebt er wat werk op gedaan, en bent toen teruggeschakeld naar je hoofd branch en hebt nog wat ander werk gedaan. Al die veranderingen zijn geïsoleerd van elkaar in aparte branches: je kunt heen en weer schakelen tussen de branches en ze mergen als je klaar bent. En je hebt dat alles gedaan met eenvoudige `branch` en `checkout` commando's. Insert 18333fig0309.png -Figuur 3-9. De branch histories zijn uiteen gegaan. +Figuur 3-9. De branch histories zijn uiteen gaan lopen. -Omdat een branch in Git in feite een eenvoudig bestand is dat de 40 karakter lange SHA-1 checksum van de commit bevat waar het naar wijst, zijn branches goedkoop om te maken en weg te gooien. Een nieuwe branch aanmaken is zo makkelijk en eenvoudig als 41 bytes naar een bestand schrijven (40 karakters en een harde return). +Omdat een branch in Git in feite een eenvoudig bestand is dat de 40 karakter lange SHA-1 checksum van de commit bevat waar het naar wijst, zijn branches goedkoop om te maken en weer weg te gooien. Een nieuwe branch aanmaken is zo snel en eenvoudig als 41 bytes naar een bestand schrijven (40 karakters en een harde return). -Dit is in scherp contrast met de manier waarop de meeste VCS applicaties branchen, wat inhoud dat alle project bestanden naar een tweede map gekopieerd worden. Dit kan enkele seconden of zelfs minuten duren, afhankelijk van de grootte van het project, en daarentegen is het in Git altijd meteen klaar. En omdat we de ouders opslaan terwijl we committen, wordt het vinden van een goed punt als basis voor het samenvoegen automatisch voor ons gedaan en is over het algemeen eenvoudig om te doen. Deze eigenschappen helpen ontwikkelaars aan te moedigen om branches vaak aan te maken en te gebruiken. +Dit is in scherp contrast met de wijze waarop de meeste VCS applicaties branchen, wat vaak het kopiëren van alle project bestanden naar een tweede map inhoudt. Dit kan enkele seconden of zelfs minuten duren, afhankelijk van de grootte van het project, daarentegen is het in Git altijd vrijwel meteen klaar. En omdat we de ouders opslaan terwijl we committen, wordt het vinden van een goed punt dat kan dienen als basis voor het mergen automatisch voor ons gedaan en is dat over het algemeen eenvoudig om te doen. Deze eigenschappen helpen ontwikkelaars met vertrouwen branches vaak aan te maken en te gebruiken. Laten we eens kijken waarom je dat zou moeten doen. @@ -114,7 +114,7 @@ Als eerste, laten we zeggen dat je aan je project werkt en al een paar commits h Insert 18333fig0310.png Figuur 3-10. Een korte en eenvoudige commit historie. -Je hebt besloten dan je gaat werken aan probleem #53 in wat voor probleem beheersysteem je bedrijf ook gebruikt. Om duidelijk te zijn, Git is niet verbonden een een probleem beheersysteem in het bijzonder; maar omdat probleem #53 een beperkt onderwerp is waar je aan werkt, zul je een nieuwe branch aanmaken waarin je gaat werken. Om een branch aan te maken en er meteen naartoe te schakelen, kun je het `git checkout` commando uitvoeren met de `-b` optie: +Je hebt besloten dan je gaat werken aan probleem #53 in wat voor systeem je bedrijf ook gebruikt om problemen te registreren. Voor de duidelijkheid: Git is niet verbonden met een probleem beheersysteem in het bijzonder, maar omdat probleem #53 een specifiek onderwerp is waar je aan wilt werken, zul je een nieuwe branch aanmaken waarin je gaat werken. Om een branch aan te maken en er meteen naartoe te schakelen, kun je het `git checkout` commando uitvoeren met de `-b` optie: $ git checkout -b iss53 Switched to a new branch "iss53" @@ -137,16 +137,16 @@ Je doet wat werk aan je web site en doet wat commits. Door dat te doen beweegt d Insert 18333fig0312.png Figuur 3-12. De iss53 branch is vooruit gegaan met je werk. -Nu krijg je het telefoontje dan er een probleem is met de web site, en je moet het meteen repareren. Met Git hoef je je reparatie niet meteen uit te leveren samen met de `iss53` wijzigingen die je gedaan hebt, en je hoeft ook niet veel moeite te stoppen in het terugdraaien van die wijzigingen voordat je kunt werken aan het toepassen van je reparatie in productie. Het enige dat je moet doen in terugschakelen naar je master branch. +Nu krijg je het telefoontje dan er een probleem is met de web site, en je moet het meteen repareren. Met Git hoef je de reparatie niet tegelijk uit te leveren met de `iss53` wijzigingen die je gemaakt hebt, en je hoeft ook niet veel moeite te doen om die wijzigingen terug te draaien voordat je kunt werken aan het toepassen van je reparatie in productie. Het enige wat je moet doen in terugschakelen naar je master branch. -Maar, voordat je dat doet, let dan op dat als je werkmap of staging gebied wijzigingen bevat die nog niet gecommit zijn en conflicteren met de branch die je gaat uitchecken, dan laat Git je niet omschakelen. Het is het beste om een schone werk status te hebben als je tussen branches gaat schakelen. Er zijn altijd manieren om hier omheen te gaan (te weten, stashen en commit ammending). die we later gaan behandelen. Voor nu, heb je al je wijzigingen gecommit, zodat je terug kunt schakelen naar je master branch: +Maar voordat je dat doet, let op dat als je werk directory of staging gebied wijzigingen bevat die nog niet gecommit zijn en conflicteren met de branch die je gaat uitchecken, Git je niet toestaat om te schakelen. Het is het beste om een schone werk status te hebben als je tussen branches gaat schakelen. Er zijn manieren om hier mee om te gaan (te weten, stashen en commit ammending) die we later gaan behandelen. Voor nu heb je alle wijzigingen gecommit, zodat je terug kunt schakelen naar je master branch: $ git checkout master Switched to branch "master" -Op dit punt, is je project werkmap precies zoals het was voordat je begon te werken aan probleem #53, en je kunt je concentreren op je snelle reparatie. Dit is een belangrijk punt om te onthouden: Git herstelt je werkmap zodat die eruit ziet als het snapshot van de commit waar de branch die je uitchecked naar wijst. Het voegt toe, verwijdert en wijzigt bestanden automatisch om er zeker van te zijn dat je werkkopie eruit ziet zoals de branch eruit zag toen je er voor het laatst op committe. +Hierna, is je project werk directory precies zoals het was voordat je begon te werken aan probleem #53, en je kunt je concentreren op je snelle reparatie. Dit is een belangrijk punt om te onthouden: Git herstelt je werk directory zodanig dat deze eruit ziet als het snapshot van de commit waar de branch die je uitchecked naar wijst. Het voegt automatisch bestanden toe, verwijdert en wijzigt ze om er zeker van te zijn dat je werkkopie eruit ziet zoals de branch eruit zag toen je er voor het laatst op committe. -Vervolgens heb je een snelle reparatie te doen. Laten we een reparatie branch maken om op te werken totdat het af is (zie Figuur 3-13): +Vervolgens heb je een snelle reparatie (hotfix) te doen. Laten we een reparatie branch maken om op te werken totdat het af is (zie Figuur 3-13): $ git checkout -b hotfix Switched to a new branch "hotfix" @@ -158,7 +158,7 @@ Vervolgens heb je een snelle reparatie te doen. Laten we een reparatie branch ma Insert 18333fig0313.png Figuur 3-13. snelle reparatie branch gebaseerd op de tip van je master branch. -Je kunt je tests draaien, er zeker van zijn dat de reparatie is wat je wil, en het samenvoegen met je master branch om het naar productie uit te rollen. Je doet dit met het `git merge` commando: +Je kunt je tests draaien, je erzelf van verzekeren dat de reparatie is wat je wil, en het mergen in je master branch en het naar productie uitrollen. Je doet dit met het `git merge` commando: $ git checkout master $ git merge hotfix @@ -167,14 +167,14 @@ Je kunt je tests draaien, er zeker van zijn dat de reparatie is wat je wil, en h README | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) -Je zult de uitdrukking "Fast forward" zien in die samenvoeging. Omdat de commit van de branch waar je mee samenvoegde direct stroomopwaarts was van de commit waar je op zit, zal Git de verwijzing vooruit zetten. Om dat op een andere manier te zeggen, als je een commit probeert samen te voegen met een commit die bereikt kan worden door de historie van eerste commit te volgen, zal Git de dingen vereenvoudigen door de verwijzing vooruit te verplaatsen omdat er geen afwijkend werk is om samen te voegen — dit wordt een "fast forward" genoemd. +Je zult de uitdrukking "Fast forward" zien in die merge. Omdat de commit van de branch waar je mee samenvoegde direct stroomopwaarts was van de commit waar je op zit, zal Git de verwijzing vooruit verplaatsen. Om het op een andere manier te zeggen, als je een commit probeert te mergen met een commit die bereikt kan worden door de historie van eerste commit te volgen, zal Git de dingen vereenvoudigen door de verwijzing vooruit te verplaatsen omdat er geen afwijkend werk is om rte mergen; dit wordt een "fast forward" genoemd. -Je wijziging is nu in het snapshot van de commit waar de `master` branch naar wijst, en je kunt je wijziging uitrollen (zie Figuur 3-14). +Je wijziging zit nu in het snapshot van de commit waar de `master` branch naar wijst, en je kunt je wijziging uitrollen (zie Figuur 3-14). Insert 18333fig0314.png Figuur 3-14. Je master branch wijst naar dezelfde plek als de snelle reparatie branch na de wijziging. -Nadat je super-belangrijke reparatie uitgerold is, ben je klaar om terug te schakelen naar het werk dat je deed voordat je onderbroken werd. Maar, eerst zul je de snelle reparatie branch verwijderen, omdat je die niet langer nodig hebt — de `master` branch wijst naar dezelfde plek. Je kunt het verwijderen met de `-d` optie op `git branch`: +Nadat je super-belangrijke reparatie uitgerold is, ben je klaar om terug te schakelen naar het werk dat je deed voordat je onderbroken werd. Maar, eerst zul je de snelle reparatie branch verwijderen, omdat je die niet langer nodig hebt: de `master` branch wijst naar dezelfde plek. Je kunt het verwijderen met de `-d` optie op `git branch`: $ git branch -d hotfix Deleted branch hotfix (3a0874c). @@ -191,11 +191,11 @@ Nu kun je terugschakelen naar je werk in uitvoering branch voor probleem #53 en Insert 18333fig0315.png Figuur 3-15. Je iss53 branch kan onafhankelijk vooruit bewegen. -Het is interessant om hier op te merken dat het werk dat je in je snelle reparatie branch gedaan hebt, niet zit in de bestanden van je `iss53` branch. Als je dat binnen moet halen, dan kun je je `master` branch in je `iss53` branch samenvoegen door `git merge master` uit te voeren, of je kunt wachten met die wijzigingen te integreren totdat je beslist om je `iss53` branch later in je `master` binnen te halen. +Het is nuttig om hier op te merken dat het werk dat je in je snelle reparatie branch gedaan hebt, niet in de bestanden van je `iss53` branch zit. Als je dat binnen moet halen, dan kun je de `master` branch in de `iss53` branch merge door `git merge master` uit te voeren, of je kunt wachten met die wijzigingen te integreren tot het moment dat je het besluit neemt de `iss53` branch in de `master` te trekken. ### Eenvoudig samenvoegen ### -Stel dat je besloten hebt dat je probleem #53 werk compleet is en klaar bent om samen te gaan voegen in je `master` branch. Om dat te doen, zul je je `iss53` branch samenvoegen zoals je je snelle reparatie branch eerder hebt samengevoegd. Het enige dat je hoeft te doen is de branch uit te checken waar je in wenst samen te voegen en dan het `git merge` commando uit te voeren: +Stel dat je besloten hebt dat je probleem #53 werk gereed is en klaar bent om het te mergen in de `master` branch. Om dat te doen, zul je je `iss53` branch mergen zoals je die snelle reparatie branch eerder hebt gemerged. Het enige dat je hoeft te doen is de branch uit te checken waar je in wenst te mergen en dan het `git merge` commando uit te voeren: $ git checkout master $ git merge iss53 @@ -203,32 +203,32 @@ Stel dat je besloten hebt dat je probleem #53 werk compleet is en klaar bent om README | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) -Dit ziet er iets anders uit dan de snelle reparatie samenvoeging die je eerder deed. In dit geval is je ontwikkelingshistorie afgeweken van een ouder punt. Omdat de commit op de branch waar je op zit geen directe voorouder is van de branch waar je in samenvoegt, moet Git wat werk doen. In dit geval, doet Git een eenvoudige drieweg samenvoeging, gebruikmakend van de twee snapshots waarnaar gewezen wordt door de branch punten en de gezamenlijke voorouder van die twee. Figuur 3-16 markeert de drie snapshots die Git gebruikt om zijn samenvoeging in dit geval te doen. +Dit ziet er iets anders uit dan de snelle reparatie merge die je eerder deed. In dit geval is je ontwikkelingshistorie afgeweken van een eerder punt. Omdat de commit op de branch waar je op zit geen directe voorouder is van de branch waar je in merged, moet Git wat werk doen. In dit geval, doet Git een eenvoudige drieweg merge, gebruikmakend van de twee snapshots waarnaar gewezen wordt door de branch punten en de gezamenlijke voorouder van die twee. Figuur 3-16 markeert de drie snapshots die Git gebruikt om de merge te doen in dit geval te doen. Insert 18333fig0316.png -Figuur 3-16. Git identificeert automatisch de beste gezamenlijke voorouder als samenvoegingsbasis voor het samenvoegen van de branches. +Figuur 3-16. Git identificeert automatisch de beste gezamenlijke voorouder als basis voor het mergen van de branches. -In plaats van de branch verwijzing vooruit te bewegen, maakt Git een nieuw snapshot dat resulteert uit deze drieweg samenvoeging en maakt automatisch een nieuwe commit die daar naar wijst (zie Figuur 3-17). Dit wordt een samenvoegingscommit genoemd, en is bijzonder in dat het meer dan één ouder heeft. +In plaats van de branch verwijzing vooruit te verplaatsen, maakt Git een nieuw snapshot dat resulteert uit deze drieweg merge en maakt automatisch een nieuwe commit die daar naar wijst (zie Figuur 3-17). Dit wordt een mergecommit genoemd, en is bijzonder in die zin dat het meer dan één ouder heeft. -Het is de moeite om te vertellen dat Git de beste gezamenlijke voorouder bepaalt om te gebruiken als samenvoeg basis; dit is anders dan CVS of Subversion (voor versie 1.5), waarbij de ontwikkelaar die de samenvoeging deed zelf de beste samenvoeg basis moest uitzoeken. Dit zorgt er voor dat samenvoegen in Git een serieus stuk eenvoudiger is dan in deze andere systemen. +Het is belangrijk om erop te wijzen dat Git de beste gezamenlijke voorouder bepaalt om te gebruiken als merge basis; dit is anders dan CVS of Subversion (voor versie 1.5), waar het de ontwikkelaar die de merge doet degene is die de beste merge basis moest uitzoeken. Dit maakt het mergen in Git een behoorlijk stuk eenvoudiger dan in deze andere systemen. Insert 18333fig0317.png Figuur 3-17. Git maakt automatisch een nieuw commit object aan die het samengevoegde werk bevat. -Nu dat je werk samengevoegd is, heb je geen verdere noodzaak voor de `iss53` branch. Je kunt het verwijderen en dan handmatig het ticket in je ticket-volg systeem sluiten: +Nu dat je werk gemerged is, is er geen verdere noodzaak meer voor de `iss53` branch. Je kunt het verwijderen en daarna handmatig de ticket in het ticket-volg systeem sluiten: $ git branch -d iss53 -### Eenvoudige samenvoeg conflicten ### +### Eenvoudige merge conflicten ### -Soms, gaat dit proces niet soepel. Als je hetzelfde gedeelte van hetzelfde bestand anders hebt gewijzigd in twee branches die je samenvoegt, dan zal Git niet in staat zijn om ze netjes samen te voegen. Als je reparatie voor probleem #53 hetzelfde gedeelte van een bestand heeft aangepast als de snelle reparatie, dan krijg je een samenvoeg conflict dat er ongeveer zo uit ziet: +Af en toe verloopt dit proces niet soepel. Als je hetzelfde gedeelte van hetzelfde bestand anders hebt gewijzigd in twee branches die je merged, dan zal Git niet in staat zijn om ze netjes te mergen. Als je reparatie voor probleem #53 hetzelfde gedeelte van een bestand heeft gewijzigd als de snelle reparatie, dan krijg je een merge conflict dat er ongeveer zo uit ziet: $ 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 heeft niet automatisch een nieuwe samenvoeg commit gemaakt. Het heeft het proces gestopt totdat jij het conflict oplost. Als je wilt zien welke bestanden nog niet zijn samengevoegd op ieder punt na een samenvoeg conflict, dan kun je `git status` uitvoeren: +Git heeft niet automatisch een nieuwe merge commit gemaakt. Het heeft het proces gestopt zodat jij het conflict kan oplossen. Als je wilt zien welke bestanden nog niet zijn gemerged op ieder punt na een merge conflict, dan kun je `git status` uitvoeren: [master*]$ git status index.html: needs merge @@ -240,7 +240,7 @@ Git heeft niet automatisch een nieuwe samenvoeg commit gemaakt. Het heeft het pr # unmerged: index.html # -Alles dat samenvoeg conflicten heeft en dat nog niet is opgelost wordt getoond als niet-samengevoegd. Git voegt standaard conflict-oplossings markeringen toe aan de bestanden die conflicten hebben, zodat je ze handmatig kunt openen en die conflicten kunt oplossen. Je bestand bevat een sectie die er ongeveer zo uit ziet: +Alles wat merge conflicten heeft en wat nog niet is opgelost wordt getoond als unmerged. Git voegt standaard conflict-oplossings markeringen toe aan de bestanden die conflicten hebben, zodat je ze handmatig kunt openen en die conflicten kunt oplossen. Je bestand bevat een gedeelte die er zo ongeveer uit ziet: <<<<<<< HEAD:index.html @@ -250,14 +250,14 @@ Alles dat samenvoeg conflicten heeft en dat nog niet is opgelost wordt getoond a >>>>>>> iss53:index.html -Dit betekend dat de versie in HEAD (jouw master branch, omdat dat hetgene was dat je uitgechecked had toen je je samenvoeg commando uitvoerde) is het bovenste gedeelte van dat blok (alles boven de `======`), terwijl de versie in je `iss53` branch eruit ziet zoals alles in het onderste gedeelte. Om het conflict op te lossen, moet je één van de twee gedeeltes kiezen of de inhoud zelf samenvoegen. Bijvoorbeeld, je zou dit conflict op kunnen lossen door het hele blok met dit te vervangen: +Dit betekent dat de versie in HEAD (jouw master branch, omdat dat degene was dat je uitgechecked had toen je het merge commando uitvoerde) is het bovenste gedeelte van dat blok (alles boven de `======`), terwijl de versie in je `iss53` branch eruit ziet zoals alles in het onderste gedeelte. Om het conflict op te lossen, moet je één van de twee gedeeltes kiezen of de inhoud zelf mergen. Je zou bijvoorbeeld dit conflict op kunnen lossen door het hele blok met dit te vervangen: -Deze oplossing bevat een stukje uit elke sectie, en ik heb de `<<<<<<<`, `=======`, en `>>>>>>>` regels volledig verwijderd. Nadat je elk van deze secties opgelost hebt in elk conflicterend bestand, voer dan `git add` uit op ieder bestand om het als opgelost te markeren. Het bestand stagen markeert het als opgelost in Git. -Als je een grafische applicatie wil gebruiken om deze problemen op te lossen, kun je `git mergetool` uitvoeren, wat een toepasselijk visuele samenvoeg applicatie opstart en je door de conflicten heen loopt: +Deze oplossing bevat een stukje uit beide secties, en ik heb de `<<<<<<<`, `=======`, en `>>>>>>>` regels volledig verwijderd. Nadat je elk van deze secties opgelost hebt in elk conflicterend bestand, voer dan `git add` uit voor ieder bestand om het als opgelost te markeren. Het bestand stagen markeert het als opgelost in Git. +Als je een grafische applicatie wil gebruiken om deze problemen op te lossen, kun je `git mergetool` uitvoeren, wat een toepasselijk grafische merge applicatie opstart dat je door de conflicten heen leidt: $ git mergetool merge tool candidates: kdiff3 tkdiff xxdiff meld gvimdiff opendiff emerge vimdiff @@ -268,9 +268,9 @@ Als je een grafische applicatie wil gebruiken om deze problemen op te lossen, ku {remote}: modified Hit return to start merge resolution tool (opendiff): -Als je een ander samenvoeg applicatie wil gebruiken dan de standaard (Git koos `opendiff` voor me in dit geval, omdat ik het commando uitvoerde op een Mac), dan kun je alle ondersteunde applicaties zien aan de top na "merge tool candidates". Type de naam van de applicatie die je liever gebruikt. In Hoofdstuk 7 zullen we bespreken hoe je deze standaard waarde voor je omgeving kunt wijzigen. +Als je een ander merge applicatie wil gebruiken dan de standaard (Git koos `opendiff` voor me in dit geval, omdat ik het commando uitvoerde op een Mac), dan kun je alle ondersteunde applicaties opgenoemd zien na "merge tool candidates". Type de naam van de applicatie die je liever gebruikt. In Hoofdstuk 7 zullen we bespreken hoe je deze standaard waarde voor jouw omgeving kunt wijzigen. -Nadat je de samenvoeg applicatie afsluit, vraagt Git je of de samenvoeging succesvol was. Als je het script vertelt dat dat zo is, dan staged het het bestand om het voor je als opgelost te markeren. +Nadat je de merge applicatie afsluit, vraagt Git je of de merge succesvol was. Als je het script vertelt dat dit het geval is, dan staged dit script het bestand voor je om het als opgelost te markeren. Je kunt `git status` nogmaals uitvoeren om er zeker van te zijn dat alle conflicten opgelost zijn: @@ -282,7 +282,7 @@ Je kunt `git status` nogmaals uitvoeren om er zeker van te zijn dat alle conflic # modified: index.html # -Als je daar blij mee bent, en je controleert dat alles waar conflicten in zaten gestaged zijn, dan kun je `git commit` typen om de samenvoeg commit af te ronden. Het commit bericht ziet er standaard ongeveer zo uit: +Als je het daar mee eens bent, en je gecontroleerd hebt dat alles waar conflicten in zat gestaged is, dan kun je `git commit` typen om de merge commit af te ronden. Het commit bericht ziet er standaard ongeveer zo uit: Merge branch 'iss53' @@ -295,36 +295,36 @@ Als je daar blij mee bent, en je controleert dat alles waar conflicten in zaten # and try again. # -Je kunt dat bericht aanpassen met details over hoe je het conflict opgelost hebt, als je denkt dat dat behulpzaam zou zijn voor anderen die in de toekomst naar deze samenvoeging kijken — waarom je deed wat je deed, als dat niet vanzelfsprekend is. +Je kunt dat bericht aanpassen met details over hoe je het conflict opgelost hebt, als je denkt dat dat behulpzaam zal zijn voor anderen die in de toekomst naar deze samenvoeging kijken; waarom je heb je gedaan wat je gedaan hebt, als dat niet vanzelfsprekend is. ## Branch beheer ## -Nu heb je wat branches aangemaakt, samengevoegd, en verwijderd. Laten we eens kijken naar wat branch beheer applicaties die handig zijn als je begint met het doorlopend gebruik van branches. +Nu heb je wat branches aangemaakt, gemerged, en verwijderd. Laten we eens kijken naar wat branch beheer toepassingen die handig zijn als je vaker branches gaat gebruiken. -Het `git branch` commando doet meer dan alleen branches aanmaken en verwijderen. Als je het zonder argumenten uitvoert, dan krijg je een eenvoudige uitvoer van je huidige branches: +Het `git branch` commando doet meer dan alleen branches aanmaken en verwijderen. Als je het zonder argumenten uitvoert, dan krijg je een eenvoudige lijst van de huidige branches: $ git branch iss53 * master testing -Neem notie van het `*` karakter dat vooraf gaat aan de `master` branch: het geeft de branch aan die je op dit moment uitgechecked hebt. Dit betekent dat als je op dit punt commit, de `master` branch vooruit zal gaan met je nieuwe werk. Om de laatste commit op iedere branch te zien, kun je `git branch -v` uitvoeren: +Merk op dat het `*` karakter vooraf gaat aan de `master` branch: het geeft de branch aan dat je op dit moment uitgechecked hebt. Dit betekent dat als je op dit punt commit, de `master` branch vooruit zal gaan met je nieuwe werk. Om de laatste commit op iedere branch te zien, kun je `git branch -v` uitvoeren: $ git branch -v iss53 93b412c fix javascript issue * master 7a98805 Merge branch 'iss53' testing 782fd34 add scott to the author list in the readmes -Een andere handige optie om uit te vogelen in welke staat je branches zijn, is om deze lijst te filteren op branches die je wel of nog niet samengevoegd hebt in de branch waar je nu op zit. De handige `--merged` en `--no-merged` opties zijn voor dit doel beschikbaar in Git sinds versie 1.5.6. Om te zien welke branches al samengevoegd zijn in de branch waar je nu op zit, kun je `git branch --merged` uitvoeren: +Een andere handige optie om uit te vogelen in welke staat je branches zijn, is om deze lijst te filteren op branches die je wel of nog niet gemerged hebt in de branch waar je nu op zit. De handige `--merged` en `--no-merged` opties zijn voor dit doel beschikbaar in Git. Om te zien welke branches al gemerged zijn in de branch waar je nu op zit, kun je `git branch --merged` uitvoeren: $ git branch --merged iss53 * master -Omdat je `iss53` al eerder hebt samengevoegd, zie je het terug in je lijst. Branches op deze lijst zonder de `*` ervoor zijn over het algemeen geschikt om te verwijderen met `git branch -d`: je hebt hun werk al in een andere branch zitten, dus je zult niets kwijtraken. +Omdat je `iss53` al eerder hebt gemerged, zie je het terug in je lijst. Branches op deze lijst zonder de `*` ervoor zijn over het algemeen zonder problemen te verwijderen met `git branch -d`: je hebt hun werk al in een andere branch zitten, dus je zult niets kwijtraken. -Om alle branches te zien die werk bevatten dat je nog niet samengevoegd hebt, kun je `git branch --no-merged` uitvoeren: +Om alle branches te zien die werk bevatten dat je nog niet gemerged hebt, kun je `git branch --no-merged` uitvoeren: $ git branch --no-merged testing @@ -335,85 +335,85 @@ Dit toont je andere branch. Omdat het werk bevat dat nog niet samengevoegd is, z 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'. -Als je de branch echt wilt verwijderen en dat werk wilt verliezen, dan kun je het forceren met `-D`, zoals het behulpzame bericht verteld. +Als je de branch echt wilt verwijderen en dat werk wilt verliezen, dan kun je het forceren met `-D`, zoals het behulpzame bericht je al meldt. ## Branch werkwijzen ## -Nu dat je de basis van het branchen en samenvoegen onder de knie hebt, wat kan of zou je met ze kunnen doen? In dit gedeelte gaan we over een aantal veel voorkomende werkwijzen die deze lichtgewicht branches mogelijk maken, zodat je kunt beslissen of dat je ze wilt integreren in je ontwikkel cyclus. +Nu dat je de basis van het branchen en samenvoegen onder de knie hebt, wat kan of zou je met ze kunnen doen? In deze paragraaf gaan we een aantal veel voorkomende werkwijzen die deze lichtgewicht branches mogelijk maken behandelen, zodat je kunt besluiten of je ze wilt toepassen in jouw ontwikkel cyclus. ### Lang-lopende branches ### -Omdat Git gebruik maakt van een eenvoudige drieweg samenvoeging, is het meerdere keren samenvoegen vanuit een branch met een andere over een langere periode over het algemeen eenvoudig om te doen. Dit betekent dat je meerdere branches kunt hebben, die altijd open staan en die je voor verschillende delen van je ontwikkel cyclus gebruikt; je kunt regelmatig samenvoegen van een aantal ervan in de anderen. +Omdat Git gebruik maakt van een eenvoudige drieweg merge, is het meerdere keren mergen vanuit een branch in een andere gedurende een langere periode over het algemeen eenvoudig te doen. Dit betekent dat je meerdere branches kunt hebben, die altijd open staan en die je voor verschillende delen van je ontwikkel cyclus gebruikt; je kunt regelmatig een aantal mergen in andere. -Veel Git ontwikkelaars hebben een werkwijze die deze aanpak omarmd, zoals het hebben van alleen volledig stabiele code in hun `master` branch — waarschijnlijk alleen code die is of zal worden vrijgegeven. Ze hebben een andere parallelle branch genaamd develop of next waarop ze werken of die ze gebruiken om stabiliteit te testen — het is niet noodzakelijk altijd stabiel, maar zodra het naar een stabiele status gaat, kan het worden samengevoegd in `master`. Het wordt gebruikt om onderwerp branches (branches met een korte levensduur, zoals jou eerdere `iss53` branch) binnen te halen, zodra die klaar zijn, om er zeker van te zijn dat ze voor alle testen slagen en geen fouten introduceren. +Veel Git ontwikkelaars hebben een werkwijze die deze aanpak omarmt, zoals het hebben van alleen volledig stabiele code in hun `master` branch — waarschijnlijk alleen code die is of zal worden vrijgegeven. Ze hebben een andere parallelle branch "develop" of "next" genaamd waarop ze werken of die ze gebruiken om stabiliteit te testen — het is niet noodzakelijk altijd stabiel, maar zodra het in een stabiele status verkeert, kan het worden gemerged in `master`. Het wordt gebruikt om topic branches (branches met een korte levensduur, zoals jou eerdere `iss53` branch) te pullen zodra die klaar zijn, om er zich ervan te verzekeren dat alle testen slagen en er geen fouten worden geïntroduceerd. -In werkelijkheid praten we over verwijzingen die zich verplaatsen over de lijn van de commits die je maakt. De stabiele branches zijn verder naar achter in je commit historie, en de splinternieuwe branches zijn verder naar voren in de historie (zie Figuur 3-18). +In essentie praten we over verwijzingen die zich verplaatsen over de lijn van de commits die je maakt. De stabiele branches zijn verder naar achter in je commit historie, en de splinternieuwe branches zijn verder naar voren in de historie (zie Figuur 3-18). Insert 18333fig0318.png -Figuur 3-18. Meer stabiele branches zijn vaak verder naar achter in de commit historie. +Figuur 3-18. Meer stabiele branches zijn over het algemeen verder naar achter in de commit historie. -Ze zijn over het algemeen makkelijker voor te stellen als werk silo's, waar sets van commits slagen naar een meer stabiele silo als ze volledig getest zijn (zie Figuur 3-19). +Ze zijn misschien makkelijker voor te stellen als werk silo's, waar sets van commits stapsgewijs naar een meer stabiele silo worden gepromoveerd als ze volledig getest zijn (zie Figuur 3-19). Insert 18333fig0319.png Figuur 3-19. Het kan handig zijn om je branches voor te stellen als silo's. -Je kunt dit doen voor meerdere niveaus van stabiliteit. Sommige grotere projecten hebben ook een `proposed` of `pu` (proposed updates) branch die branches geïntegreerd heeft die wellicht nog niet klaar zijn om in de `next` of `master` branch te gaan. Het idee is dat je branches op verschillende niveaus van stabiliteit zitten; zodra ze een stabiel niveau bereiken, worden ze in de branch boven hun samengevoegd. -Nogmaals, het hebben van langlopende branches is niet noodzakelijk, maar het helpt vaak wel, in het bijzonder als je moet omgaan met zeer grote of complexe projecten. +Je kunt dit blijven doen voor elk niveaus van toegenomen stabiliteit. Sommige grotere projecten hebben ook een `proposed` of `pu` (proposed updates) branch die branches geïntegreerd heeft die wellicht nog niet klaar zijn om in de `next` of `master` branch te gaan. Het idee erachter is dat de branches op verschillende niveaus van stabiliteit zitten. Zodra ze een meer stabiel niveau bereiken, worden ze in de branch boven hun gemerged. +Nogmaals, het hebben van langlopende branches is niet noodzakelijk maar het helpt vaak wel, in het bijzonder als je te maken hebt met zeer grote of complexe projecten. -### Onderwerp branches ### +### Topic branches ### -Maar, onderwerp branches zijn bruikbaar in projecten van iedere grootte. Een onderwerp branch is een kortlopende branch die je maakt en gebruikt om een enkele eigenschap of gerelateerd werk in te doen. Dit is iets wat je waarschijnlijk nooit van tevoren met een VCS gedaan hebt, omdat het over het algemeen te duur is om branches aan te maken en samen te voegen. Maar in Git komt het vaak voor om branches aan te maken, op te werken, en te verwijderen meerdere keren per dag. +Topic branches zijn nuttig in projecten van elke grootte. Een topic branch is een kortlopende branch die je maakt en gebruikt om een specifieke functie te realiseren of daaraan gerelateerd werk te doen. Dit is iets wat je waarschijnlijk nooit eerder met een VCS gedaan hebt, omdat het over het algemeen te duur is om branches aan te maken en te mergen. Maar in Git is het niet ongebruikelijk om meerdere keren per dag branches aan te maken, daarop te werken, en ze te verwijderen. -Je zag dit in het laatste gedeelte met de `iss53` en `hotfix` branches die je gemaakt had. Je hebt een aantal commits op ze gedaan en ze meteen verwijderd zodra je ze samengevoegd had in je hoofd branch. Deze techniek staat je toe om snel en volledig van context te veranderen — omdat je werk is gescheiden in silo's waar alle wijzigingen in die branch met dat onderwerp te maken hebben, is het makkelijker te zien wat er is gebeurd tijdens een code review en dergelijke. Je kunt de wijzigingen daar minuten, dagen of maanden bewaren, en ze samenvoegen als je er klaar voor bent, ongeacht in de volgorde waarin ze gemaakt of aan gewerkt zijn. +Je zag dit in de vorige paragraaf met de `iss53` en `hotfix` branches die je gemaakt had. Je hebt een aantal commits op ze gedaan en ze meteen verwijderd zodra je ze gemerged had in je hoofd branch. Deze techniek staat je toe om snel en volledig van context te veranderen — omdat je werk is onderverdeeld in silo's waar alle wijzigingen te maken hebben met het onderwerp van die branch, is het makkelijker te zien wat er is gebeurd tijdens een code review en dergelijke. Je kunt de wijzigingen daar minuten, dagen of maanden bewaren, en ze mergen als ze er klaar voor zijn, ongeacht de volgorde waarin ze gemaakt of aan gewerkt zijn. -Neem als voorbeeld een situatie waarbij wat werk gedaan wordt (op `master`), gebranched wordt voor een probleem (`iss91`), waar een beetje aan gewerkt wordt, gebranched wordt vanaf de tweede branch om op een andere manier te proberen hetzelfde op te lossen (`iss91v2`) terug te gaan naar je master branch en daar een tijdje te werken, en dan vanaf daar branchen om wat werk te doen waarvan je niet zeker weet of het wel een goed idee is (`dumbidea` branch). Je commit historie zal er uit zien als Figuur 3-20. +Neem als voorbeeld een situatie waarbij wat werk gedaan wordt (op `master`), er wordt een branche gemaakt voor een probleem (`iss91`) daar wordt wat aan gewerkt, er wordt een tweede branch gemaakt om op een andere manier te proberen hetzelfde op te lossen (`iss91v2`); even teruggaan naar de master branch om daar een tijdje te werken, en dan vanaf daar branchen om wat werk te doen waarvan je niet zeker weet of het wel een goed idee is (`dumbidea` branch). Je commit historie zal er uit zien als Figuur 3-20. Insert 18333fig0320.png -Figuur 3-20. Je commit geschiedenis met meerdere onderwerp branches. +Figuur 3-20. Je commit geschiedenis met meerdere topic branches. -Nu, laten we zeggen dat je beslist dat je de tweede oplossing voor je probleem het beste vindt (`iss91v2`); en je hebt de `dumbidea` branch aan je collega's laten zien, en het blijkt geniaal te zijn. Je kunt dan de originele `iss91` weggooien (waarbij je commits C5 en C6 verliest), en de andere twee samenvoegen. Je historie ziet er dan uit als Figuur 3-21). +Laten we zeggen dat je besluit dat je de tweede oplossing voor je probleem het beste vindt (`iss91v2`), en je hebt de `dumbidea` branch aan je collega's laten zien en het blijkt geniaal te zijn. Je kunt dan de oorspronkelijke `iss91` weggooien (waardoor je commits C5 en C6 kwijt raakt), en de andere twee mergen. Je historie ziet er dan uit als Figuur 3-21). Insert 18333fig0321.png Figuur 3-21. Je historie na het samenvoegen van dumbidea en iss91v2. -Het is belangrijk om te onthouden dat wanneer je dit alles doet, deze branches volledig lokaal zijn. Als je aan het branchen of samenvoegen bent, dan wordt alles gedaan in jouw Git repository — dus er gebeurt geen server communicatie. +Het is belangrijk om te beseffen dat tijdens al deze handelingen, al deze branches volledig lokaal zijn. Als je aan het branchen of mergen bent, dan wordt alles alleen in jouw Git repository gedaan, dus er vindt geen server communicatie plaats. ## Remote branches ## -Remote branches zijn referenties naar de staat van de branches op je remote repositories. Ze zijn lokale branches die jij niet kunt verplaatsen; ze worden automatisch verplaatst zodra je wat netwerk communicatie doet. Remote branches gedragen zich als boekenleggers om je eraan te helpen herinneren waar de branches op je remote repositories waren de laatste keer dat je met ze in contact was. +Remote branches zijn referenties naar de staat van de branches op remote repositories. Ze zijn lokale branches die jij niet kunt verplaatsen; ze worden automatisch verplaatst zodra je er netwerk communicatie plaatsvindt. Remote branches gedragen zich als boekenleggers om je eraan te helpen herinneren wat de staat van de branches was op je remote repositories toen je voor het laatst met ze in contact was. -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`. +Ze hebben de vorm `(remote)/(branch)`. Bijvoorbeeld, als je wil zien hoe de `master` branch op je `origin` de laatste keer dat je er mee communiceerde er uit zag, dan zal je de `origin/master` branch moeten bekijken. Als je aan het werk bent met een probleem samen met een partner en zij heeft een `iss53` branch gepushed, kan je je eigen lokale `iss53` 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 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). +Dit is wat verwarrend, 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 alle gegevens binnen, maakt een verwijzing naar waar de `master` branch is en noemt dat lokaal `origin/master`, en deze kan je niet verplaatsen. Git geeft je ook een 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. +Figuur 3-22. Een Git clone geeft je een eigen master branch en origin/master wijzend naar de master branch van origin. -Als je wat werk doet op je lokale master branch, en in de tussentijd zet iemand anders iets terug naar `git.ourcompany.com` en vernieuwt die master branch, dan zijn jullie histories verschillend vooruit geschoven. En, zolang je geen contact hebt met je origin server, zal je `origin/master` verwijzing niet verplaatsen (zie Figuur 3-23). +Als je wat werk doet op je lokale master branch, en in de tussentijd pushed iemand anders iets naar `git.ourcompany.com` en daarmee die master branch vernieuwd, dan zijn jullie histories verschillend vooruit geschoven. En, zolang je geen contact hebt met de origin server, zal jouw `origin/master` verwijzing niet verplaatsen (zie Figuur 3-23). Insert 18333fig0323.png -Figuur 3-23. Lokaal werken terwijl iemand anders naar je remote server terugzet laat iedere historie anders vooruit gaan. +Figuur 3-23. Lokaal werken terwijl iemand anders naar je remote server pushed laat elke historie anders vooruit gaan. -Om je werk te synchroniseren, voer je een `git fetch origin` commando uit. Dit commando bekijkt welke server origin is (in dit geval is het `git.ourcompany.com`), haalt gegevens er vanaf die je nog niet hebt, en vernieuwt je lokale gegevensbank, waarbij je `origin/master` verwijzing naar zijn nieuwere positie verplaatst wordt (zie Figuur 3-24). +Om je werk te synchroniseren, voer je een `git fetch origin` commando uit. Dit commando bekijkt welke op server origin is (in dit geval is het `git.ourcompany.com`), haalt gegevens er vanaf die je nog niet hebt en vernieuwt je lokale database, waarbij je `origin/master` verwijzing naar zijn nieuwe positie verplaatst wordt (zie Figuur 3-24). Insert 18333fig0324.png Figuur 3-24. Het git fetch commando vernieuwt je remote referenties. -Om het hebben van meerdere remote servers te demonstreren en hoe remote branches voor die remote projecten er uit zien, laten we eens aannemen dat je nog een interne Git server hebt, die alleen wordt gebruikt voor ontwikkeling gedaan door een van je sprint teams. Deze server bevindt zich op `git.team1.ourcompany.com`. Je kunt het als een nieuwe remote referentie toevoegen aan het project waar je nu aan werkt door het `git remote add` commando uit te voeren, zoals we behandeld hebben in Hoofdstuk 2. Noem deze remote `teamone`, wat je afkorting voor die hele URL wordt (zie Figuur 3-25). +Om het hebben van meerdere remote servers te tonen en hoe remote branches voor die remote projecten er uit zien, zullen we aannemen dat je nog een interne Git server hebt die alleen wordt gebruikt voor ontwikkeling gedaan door een van je sprint teams. Deze server bevindt zich op `git.team1.ourcompany.com`. Je kunt het als een nieuwe remote referentie toevoegen aan het project waar je nu aan werkt door het `git remote add` commando uit te voeren, zoals we behandeld hebben in Hoofdstuk 2. Noem deze remote `teamone`, wat jouw afkorting voor die hele URL wordt (zie Figuur 3-25). Insert 18333fig0325.png Figuur 3-25. Een andere server als een remote toevoegen. -Nu kun je `git fetch teamone` uitvoeren om alles op te halen dat de `teamone` server heeft en jij nog niet. Omdat server een subset is van de gegevens die je `origin` server op dit moment heeft, haalt Git geen gegevens maar stelt een remote branch genaamd `teamone/master` in om te wijzen naar de commit die `teamone` heeft naar zijn `master` branch (zie Figuur 3-26). +Nu kun je `git fetch teamone` uitvoeren om alles op te halen dat wat de `teamone` remote server heeft en jij nog niet. Omdat die server een subset heeft van de gegevens die jouw `origin` server op dit moment heeft, haalt Git geen gegevens maar maakt een remote branch genaamd `teamone/master` aan en laat die wijzen naar de commit die `teamone` heeft als zijn `master` branch (zie Figuur 3-26). Insert 18333fig0326.png -Figuur 3-26. Je krijgt lokaal een referentie naar de positie van teamone's master branch. +Figuur 3-26. Je krijgt lokaal een referentie naar de master branch positie van teamone. -### Terugzetten ### +### Pushen ### -Als je een branch wil delen met de wereld, dan moet je het naar een remote terugzetten waar je schrijftoegang op hebt. Je lokale branches worden niet automatisch gesynchroniseerd met de remotes waar je naar schrijft — je moet de branches die je wilt delen expliciet terugzetten. Op die manier, kun je privé branches gebruiken voor werk dat je niet wil delen, en alleen de onderwerp branches terugzetten waar je op wilt samenwerken. +Als je een branch wil delen met de rest van de wereld, dan moet je het naar een remote terugzetten waar je schrijftoegang op hebt. Je lokale branches worden niet automatisch gesynchroniseerd met de remotes waar je naar schrijft, je moet de branches die je wilt delen uitdrukkelijk pushen. Op die manier kun je privé branches gebruiken voor het werk dat je niet wil delen, en alleen die topic branches pushen waar je op wilt samenwerken. -Als je een branch genaamd `serverfix` hebt, waar je met anderen aan wilt werken, dan kun je die terugzetten op dezelfde manier waarop je je eerste branch hebt teruggezet. Voer `git push (remote) (branch)` uit: +Als je een branch genaamd `serverfix` hebt waar je met anderen aan wilt werken, dan kun je die op dezelfde manier pushen als waarop je dat voor de eerste branch hebt gedaan. Voer `git push (remote) (branch)` uit: $ git push origin serverfix Counting objects: 20, done. @@ -423,9 +423,9 @@ Als je een branch genaamd `serverfix` hebt, waar je met anderen aan wilt werken, To git@github.com:schacon/simplegit.git * [new branch] serverfix -> serverfix -Dit is een beetje kort door de bocht. Git zal de `serverfix` branchnaam automatisch expanderen naar `refs/heads/serverfix:refs/heads/serverfix`, wat betekent "Neem mijn lokale serverfix branch en zet dat terug om de serverfix branch van de remote te vernieuwen.". We zullen in detail over het `refs/heads` gedeelte gaan hebben in Hoofdstuk 9, maar je kunt het over het algemeen weglaten. Je kun ook `git push origin serverfix:serverfix` doen, wat hetzelfde doet — het zegt, "Neem mijn serverfix en maak het de serverfix van de remote." Je kunt dit formaat gebruiken om een lokale branch terug te zetten naar een remote branch die anders heet. Als je niet wil dat het `serverfix` heet aan de remote kant, kun je in plaats daarvan `git push origin serverfix:awesomebranch` gebruiken om je lokale `serverfix` branch naar de `awesomebranch` op het remote project terug te zetten. +Dit is een verkorte manier. Git zal de `serverfix` branchnaam automatisch expanderen naar `refs/heads/serverfix:refs/heads/serverfix`, wat staat voor "Neem mijn lokale serverfix branch en push die om de serverfix branch van de remote te vernieuwen.". We zullen het `refs/heads` gedeelte gedetaileerd behandelen in Hoofdstuk 9, maar je kunt het normaalgesproken weglaten. Je kun ook `git push origin serverfix:serverfix` doen, wat hetzelfde doet. Dit staat voor "Neem mijn serverfix en maak het de serverfix van de remote." Je kunt dit formaat gebruiken om een lokale branch te pushen naar een remote branch die anders heet. Als je niet wil dat het `serverfix` heet aan de remote kant, kan je in plaats daarvan `git push origin serverfix:awesomebranch` gebruiken om je lokale `serverfix` branch naar de `awesomebranch` op het remote project te pushen. -De volgende keer dat één van je medewerkers van de server fetched, zullen ze een referentie krijgen naar waar de servers versie van `serverfix` is onder de remote branch `origin/serverfix`: +De volgende keer dat één van je medewerkers van de server fetched zal deze een referentie krijgen naar de versie van `serverfix` op de server, onder de remote branch `origin/serverfix`: $ git fetch origin remote: Counting objects: 20, done. @@ -435,61 +435,61 @@ De volgende keer dat één van je medewerkers van de server fetched, zullen ze e From git@github.com:schacon/simplegit * [new branch] serverfix -> origin/serverfix -Het is belangrijk om op te merken dat als je een fetch doet die nieuwe remote branches ophaalt, je niet automatisch lokale, aanpasbare kopieën daarvan hebt. In andere woorden, in dit geval heb je geen nieuwe `serverfix` branch — je hebt alleen een `origin/serverfix` verwijzing die je niet kunt aanpassen. +Het is belangrijk om op te merken dat als je een fetch doet die nieuwe remote branches ophaalt, je niet automatisch lokale aanpasbare kopieën daarvan hebt. In andere woorden, in dit geval heb je geen nieuwe `serverfix` branch, je hebt alleen een `origin/serverfix` verwijzing die je niet kunt aanpassen. -Om dit werk in je huidige werk branch samen te voegen, kun je `git merge origin/serverfix` uitvoeren. Als je je eigen `serverfix` branch wilt waar je op kunt werken, dan kun je deze vanaf je remote branch baseren: +Om dit werk in je huidige werk branch te mergen, kun je `git merge origin/serverfix` uitvoeren. Als je een eigen `serverfix` branch wilt waar je op kunt werken, dan kun je deze op je remote branch baseren: $ git checkout -b serverfix origin/serverfix Branch serverfix set up to track remote branch refs/remotes/origin/serverfix. Switched to a new branch "serverfix" -Dit geeft je een lokale branch waar je op kunt werken, die begint met waar `origin/serverfix` is. +Dit maakt een lokale branch aan waar je op kunt werken, die begint met waar `origin/serverfix` is. -### Volg branches ### +### Tracking branches ### -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. +Een lokale branch uitchecken van een remote branch creëert automatisch een zogenaamde _volg branch_ (_tracking branch_). Tracking branches zijn lokale branches die een directe releatie met een remote branch hebben. Als je op een tracking branch zit en `git push` typt, dat weet Git automatisch naar welke server en branch hij moet pushen. En, als je op een van die branches zit zal het uitvoeren van `git pull` alle remote referenties ophalen en automatisch naar de corresponderende remote branch mergen. -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: +Als je een repository kloont, zal het over het algemeen automatisch een `master` branch aanmaken, die `origin/master` tracked. Daarom werken `git push` en `git pull` zo uit het doosje, zonder verdere argumenten. Maar je kan ook andere tracking branches instellen als je dat wilt, andere die niet branches volgen op `origin` en niet de `master` branch tracken. Een eenvoudig voorbeeld is wat je zojuist gezien hebt: `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. Switched to a new branch "serverfix" -Om een lokale branch in te stellen met een andere naam dan de remote branch, kun je eenvoudig de eerste versie met een andere lokale branch naam gebruiken: +Om een lokale branch te maken met een andere naam dan de remote branch, kun je simpelweg de eerste variant met een andere lokale branch naam gebruiken: $ git checkout -b sf origin/serverfix Branch sf set up to track remote branch refs/remotes/origin/serverfix. Switched to a new branch "sf" -Nu zal je lokale sf branch automatisch halen en terugzetten van origin/serverfix. +Nu zal je lokale `sf` branch automatisch pullen en pushen van origin/serverfix. ### Remote branches verwijderen ### -Stel dat je klaar bent met een remote branch — stel dat jij en je medewerkers klaar zijn met een eigenschap en het hebben samengevoegd in je `master` branch van je remote (of welke branch je stabiele codelijn ook in zit). Dan kun je een remote branch verwijderen door de nogal stompzinnige syntax `git push [remotenaam] :[branch]` te gebruiken. Als je je `serverfix` branch van de server wilt verwijderen, dan voer je het volgende uit: +Stel dat je klaar bent met een remote branch, stel dat jij en je medewerkers klaar zijn met een feature en het hebben gemerged in de `master` branch van de remote (of welke branch je stabiele code ook in zit). Dan kun je een remote branch verwijderen door de nogal botte syntax `git push [remotenaam] :[branch]` te gebruiken. Als je de `serverfix` branch van de server wilt verwijderen, dan voer je het volgende uit: $ git push origin :serverfix To git@github.com:schacon/simplegit.git - [deleted] serverfix -Boem. Geen branch meer op je server. Je zult deze pagina wel een ezelsoor willen geven, omdat je dat commando nodig hebt, en je het waarschijnlijk zult vergeten. Een manier om dit commando te onthouden is door de `git push [remotenaam] [lokalebranch]:[remotebranch]` syntax te onthouden die we iets eerder behandeld hebben. Als je het `[lokalebranch]` gedeelte weglaat, dan zeg je in feite, "Neem iets willekeurigs aan mijn kant en maak dat de `[remotebranch]`." +Boem. Geen branch meer op je server. Je zult deze pagina wel een ezelsoortje willen geven, omdat je dat commando nodig gaat hebben en het waarschijnlijk zult vergeten. Een manier om dit commando te onthouden is door de `git push [remotenaam] [lokalebranch]:[remotebranch]` syntax te onthouden die we kortgeleden behandeld hebben. Als je het `[lokalebranch]` gedeelte weglaat dan zeg je in feite, "Neem niets aan mijn kant en maak dat de `[remotebranch]`." ## Rebasen ## -In Git zijn er twee hoofdmanieren om wijzigingen te integreren van één branch in een andere: de `samenvoeging` en de `rebase`. In dit gedeelte zul je leren wat rebasen is, hoe je het moet doen, waarom het een zeer bijzondere toepassing is, en in welke gevallen je het niet wilt gebruiken. +In Git zijn er twee hoofdmanieren om wijzigingen te integreren van de ene branch in een andere: de `merge` en de `rebase`. In deze paragraaf zul je leren wat rebasen is, hoe je dat moet doen, waarom het een zeer bijzondere toepassing is en in welke gevallen je het niet wilt gebruiken. -### De eenvoudige rebase ### +### De simpele rebase ### -Als je teruggaat naar een eerder voorbeeld van de Samenvoegen sectie (zie Figuur 3-27), dan kun je zien dat je werk is afgeweken en dat je commits hebt gedaan op de twee verschillende branches. +Als je het eerdere voorbeeld van de Merge-paragraaf erop terugslaat (zie Figuur 3-27), dan zul je zien dat je werk is uiteengelopen en dat je commits hebt gedaan op de twee verschillende branches. Insert 18333fig0327.png -Figuur 3-27. Je initiële afgeweken historie. +Figuur 3-27. Je initiële uiteengelopen historie. -De eenvoudigste weg om de branches te integreren, zoals we al hebben besproken, is het `samenvoeg` commando. Het voert een drieweg samenvoeging uit tussen de twee laatste snapshots van de branches (C3 en C4), en de meest recente gezamenlijke voorouder van die twee (C2), creëert een nieuw snapshot (en commit), zoals getoond in Figuur 3-28. +De simpelste manier om de branches te integreren, zoals we al hebben besproken, is het `merge` commando. Het voert een drieweg merge uit tussen de twee laatste snapshots van de branches (C3 en C4), en de meest recente gezamenlijke voorouder van die twee (C2), en maakt een nieuw snapshot (en commit) zoals getoond in Figuur 3-28. Insert 18333fig0328.png -Figuur 3-28. Een branch samenvoegen om de afgeweken werk historie te integreren. +Figuur 3-28. Een branch merge om de uiteengelopen werk histories te integreren. -Maar, er is een andere manier: je kunt de patch van de wijziging die werd geïntroduceerd in C3 pakken en die opnieuw toepassen bovenop C4. In Git, wordt dit _rebasen_ genoemd. Met het `rebase` commando, kun je alle wijzigingen pakken die zijn gecommit op een branch, en ze opnieuw afspelen op een andere. +Maar, er is nog een manier: je kunt de patch van de wijziging die werd geïntroduceerd in C3 pakken en die opnieuw toepassen op C4. In Git, wordt dit _rebasen_ genoemd. Met het `rebase` commando kan je alle wijzigingen pakken die zijn gecommit op de ene branch, en ze opnieuw afspelen op een andere. In dit voorbeeld, zou je het volgende uitvoeren: @@ -498,37 +498,37 @@ In dit voorbeeld, zou je het volgende uitvoeren: First, rewinding head to replay your work on top of it... Applying: added staged command -Het werkt door naar de gezamenlijke voorouder van de twee branches te gaan (degene waar je op zit en degene waar je naar rebased), de verschillen pakken die geïntroduceerd is bij iedere commit op de branch waar je op zit, die diffs in tijdelijke bestanden bewaren, de huidige branch terugzetten naar dezelfde commit als de branch waar je op rebased, en uiteindelijk iedere wijziging om de beurt toepassen, Figuur 3-29 toont dit proces. +Het gebeurt door naar de gezamenlijke voorouder van de twee branches te gaan (degene waar je op zit en degene waar je op rebased), de diff te nemen die geïntroduceerd is voor elke losse commit op de branch waar je op zit, die diffs in tijdelijke bestanden te bewaren, de huidige branch terug te zetten naar dezelfde commit als de branch waar je op rebased, en uiteindelijk elke diff om de beurt toe te passen, Figuur 3-29 toont dit proces. Insert 18333fig0329.png Figuur 3-29. De wijzigingen die geïntroduceerd zijn in C3 rebasen op C4. -Op dit punt kun je terug gaan naar de master branch en een fast-forward samenvoeging doen (zie Figuur 3-30). +Hierna kan je terug gaan naar de master branch en een fast-forward merge doen (zie Figuur 3-30). Insert 18333fig0330.png Figuur 3-30. De master branch Fast-forwarden. -Nu is het snapshot waar C3' naar wijst precies hetzelfde als degene waar C5 naar wees in het samenvoeg voorbeeld. Er zit geen verschil in het eindproduct van de integratie, maar rebasen zorgt voor een schonere historie. Als je de log van een gerebasete branch bekijkt, ziet het eruit als een lineaire historie: het lijkt alsof al het werk in serie is gebeurt, zelfs als het in werkelijkheid in parallel gedaan is. +Nu is het snapshot waar C3' naar wijst precies dezelfde als degene waar C5 naar wees in het merge voorbeeld. Er zit geen verschil in het eindresultaat van de integratie, maar rebasen zorgt voor een duidelijkere historie. Als je de log van een gerebasdte branch bekijkt, ziet het eruit als een lineaire historie: het lijkt alsof al het werk in serie is gebeurt, zelfs wanneer het in werkelijkheid in parallel gedaan is. -Vaak zul je dit doen om er zeker van te zijn dat je commits netjes aansluiten op een remote branch — misschien in een project waar je op probeert bij te dragen, maar dat je niet onderhoudt. In dit geval zou je je werk in een branch doen en dan je werk rebasen op `origin/master` als je klaar ben om je patches in te sturen naar het hoofd project. Op die manier hoeft de beheerder geen integratie werk te doen — gewoon een fast-forward of een schone toepassing. +Vaak zal je dit doen om er zeker van te zijn dat je commits netjes toegepast kunnen worden op een remote branch, misschien in een project waar je aan probeert bij te dragen, maar dat je niet beheert. In dit geval zou je het werk in een branch uitvoeren en dan je werk rebasen op `origin/master` als je klaar ben om je patches in te sturen naar het hoofd project. Op die manier hoeft de beheerder geen integratie werk te doen maar gewoon een fast-forward of een gewone apply. -Let op het snapshot waar de laatste commit naar wijst waar je mee eindigt, of het de laatste van de gerebasete commits voor een rebase is, of de laatste samenvoeg commit na een samenvoeging, het is hetzelfde snapshot — alleen de historie is verschillend. Rebasen speelt veranderingen van een werklijn opnieuw af op een andere in de volgorde waarin ze geïntroduceerd waren, en samenvoegen pakt de eindpunten en voegt die samen. +Merk op dat de snapshot waar de laatste commit op het eind naar wijst, of het de laatste van de gerebasete commits voor een rebase is of de laatste merge commit na een merge, detzelfde snapshot is; alleen de historie is verschillend. Rebasen speelt veranderingen van een werklijn opnieuw af op een andere, in de volgorde waarin ze gemaakt zijn, terwijl mergen de eindresultaten pakt en die samenvoegt. ### Interessantere rebases ### -Je kunt je rebase ook opnieuw laten afspelen op iets anders dan de rebase branch. Pak een historie zoals in Figuur 3-31, bijvoorbeeld. Je hebt een onderwerp branch afgesplitst (`server`) om wat server-kant functionaliteit toe te voegen aan je project, en toen een commit gedaan. Daarna, heb je daar vanaf gebranched om de client-kant wijzigingen te doen (`client`) en een paar keer gecommit. Als laatste, ben je teruggegaan naar je server branch en hebt nog een paar commits gedaan. +Je kunt je rebase ook opnieuw laten afspelen op iets anders dan de rebase branch. Pak een historie zoals in Figuur 3-31, bijvoorbeeld. Je hebt een topic branch afgesplitst (`server`) om wat server-kant functionaliteit toe te voegen aan je project en toen een gecommit. Daarna heb je daar vanaf gebranched om de client-kant wijzigingen te doen (`client`) en een paar keer gecommit. Als laatste, ben je teruggegaan naar je server branch en hebt nog een paar commits gedaan. Insert 18333fig0331.png -Figuur 3-31. Een historie met een onderwerp branch vanaf een andere onderwerp branch. +Figuur 3-31. Een historie met een topic branch vanaf een andere topic branch. -Stel dat je beslist dat je je client-kant wijzigingen wilt samenvoegen in je hoofdlijn voor een vrijgave, maar je wilt de server-kant wijzigingen nog laten wachten totdat het verder getest is. Je kunt de wijzigingen van client pakken, die nog niet op server zitten (C8 en C9) en die opnieuw afspelen op je master branch door de `--onto` optie te gebruiken van `git rebase`: +Stel dat je beslist dat je de client-kant wijzigingen wilt mergen in je hoofdlijn voor een release, maar je wilt de server-kant wijzigingen nog laten wachten totdat het verder getest is. Je kunt de wijzigingen van client pakken, die nog niet op server zitten (C8 en C9) en die opnieuw afspelen op je master branch door de `--onto` optie te gebruiken van `git rebase`: $ git rebase --onto master server client -Dit zegt in feite, "Check de client branch uit, vogel de patches van de gezamenlijke voorouder van de `client` en de `server` branches uit, en speel die opnieuw af op `master`." Het is een beetje complex; maar het resultaat, getoond in Figuur 3-32, is erg vet. +Dit zegt in feite, "Check de client branch uit, verzamel de patches van de gezamenlijke voorouder van de `client` en de `server` branches, en speel die opnieuw af op `master`." Het is een beetje ingewikkeld, maar het resultaat, getoond in Figuur 3-32, is erg prettig. Insert 18333fig0332.png -Figuur 3-32. Een onderwerp branch rebasen vanaf een andere onderwerp branch. +Figuur 3-32. Een topic branch rebasen vanaf een andere topic branch. Nu kun je een fast-forward doen van je master branch (zie Figuur 3-33): @@ -538,21 +538,21 @@ Nu kun je een fast-forward doen van je master branch (zie Figuur 3-33): Insert 18333fig0333.png Figuur 3-33. Je master branch fast-forwarden om de client branch wijzigingen mee te nemen. -Stel dat je beslist om je server branch ook binnen te halen. Je kunt de server branch rebasen op de master branch zonder het eerst te moeten uitchecken door `git rebase [basisbranch] [onderwerpbranch]` uit te voeren — wat de onderwerp branch uitchecked (in dit geval, `server`) voor je en het opnieuw afspeelt om de basis branch (`master`): +Stel dat je besluit om de server branch ook te pullen. Je kunt de server branch rebasen op de master branch zonder het eerst te hoeven uitchecken door `git rebase [basisbranch] [topicbranch]` uit te voeren, wat de topic branch voor je uitchecked (in dit geval, `server`) en het opnieuw afspeelt om de basis branch (`master`): $ git rebase master server -Dit speelt je `server` werk opnieuw af bovenop je `master` werk, zoals getoond in Figuur 3-34. +Dit speelt het `server` werk opnieuw af op het `master` werk, zoals getoond in Figuur 3-34. Insert 18333fig0334.png -Figuur 3-34. Je server branch bovenop je master branch rebasen. +Figuur 3-34. Je server branch op je master branch rebasen. -Daarna, kun je de basis branch (`master`) fast-forwarden: +Daarna kan je de basis branch (`master`) fast-forwarden: $ git checkout master $ git merge server -Je kunt de `client` en `server` branches verwijderen, omdat al het werk geïntegreerd is en je ze niet meer nodig hebt, waarbij je historie voor het hele proces er uit ziet zoals Figuur 3-35: +Je kunt de `client` en `server` branches verwijderen, omdat al het werk geïntegreerd is en je ze niet meer nodig hebt, en de historie voor het hele proces ziet eruit zoals in Figuur 3-35: $ git branch -d client $ git branch -d server @@ -562,38 +562,38 @@ Figuur 3-35. Uiteindelijke commit historie. ### De gevaren van rebasen ### -Ahh, maar de zegen van rebasen is niet zonder nadelen, wat samengevat kan worden in een enkele regel: +Ahh, maar de zegeningen van rebasen zijn niet geheel zonder nadelen, samengevat in één enkele regel: -**Rebase geen commits die je teruggezet hebt naar een publiek repository.** +**Rebase geen commits die je gepushed hebt naar een publiek repository.** -Als je die richtlijn volgt, dan gebeurt je niets. Als je dat niet doet, zullen mensen je haten, en je zult door vrienden en familie uitgehoond worden. +Als je die richtlijn volgt, dan zal je niets overkomen. Als je dat niet doet, zullen mensen je haten en je zult door vrienden en familie uitgehoond worden. -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. +Als je spullen rebaset, zet je bestaande commits buitenspel en maak je nieuwe aan die vergelijkbaar zijn maar anders. Als je commits ergens pushed en andere pullen deze en baseren daar werk op, en vervolgens herschrijf je die commits met `git rebase` en pushed deze weer, dan zullen je medewerkers hun werk opnieuw moeten mergen en zal de boel erg vervelend worden als je hun werk probeert te pullen 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 kloont en dan daar wat werk vanaf doet. Je commit historie ziet er uit als Figuur 3-36. +Laten we eens kijken naar een voorbeeld hoe werk rebasen dat je publiek gemaakt hebt problemen kan veroorzaken. Stel dat je van een centrale server kloont en dan daar wat werk aan doet. Je commit historie ziet er uit als Figuur 3-36. Insert 18333fig0336.png -Figuur 3-36. Kloon een repository, en baseer wat werk daarop. +Figuur 3-36. Kloon een repository, en doe 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. +Nu doet iemand anders wat meer werk dat een merge bevat, en pushed dat werk naar de centrale server. Je fetched dat en merged de nieuwe remote branch in jouw werk, zodat je historie er uit ziet zoals Figuur 3-37. Insert 18333fig0337.png -Figuur 3-37. Haal meer commits op, en voeg ze samen in je werk. +Figuur 3-37. Haal meer commits op, en merge ze in je werk. -Daarna, beslist de persoon die het werk teruggezet heeft om terug te gaan en hun werk in plaats daarvan te rebasen; ze voeren een `git push --force` uit om de historie op de server te herschrijven. Je haalt dan van die server op, waarbij je de nieuwe commits omlaag haalt. +Daarna, beslist de persoon die het werk gepushed heeft om terug te gaan en hun werk te gaan rebasen; ze voeren een `git push --force` uit om de historie op de server te herschrijven. Je pulled daarna van die server, waarbij je de nieuwe commits binnen krijgt. Insert 18333fig0338.png -Figuur 3-38. Iemand zet gerebasete commits terug, daarbij commits achterlatend waar jij werk op gebaseerd hebt. +Figuur 3-38. Iemand pushed gerebasete commits, daarbij commits buitenspel zettend waar jij werk op gebaseerd hebt. -Op dit punt, moet je dit werk opnieuw samenvoegen, alhoewel je dat al gedaan hebt. Rebasen verandert de SHA-1 hashes van deze commits, dus voor Git zien ze er uit als nieuwe commits, terwijl je in feite al het C4 werk in je historie hebt (zie Figuur 3-39). +Nu moet je dit werk opnieuw mergeen, hoewel je dat al gedaan hebt. Rebasen verandert de SHA-1 hashes van deze commits, dus voor Git zien ze er uit als nieuwe commits, terwijl je in feite het C4 werk al in je historie hebt (zie Figuur 3-39). Insert 18333fig0339.png -Figuur 3-39. Je voegt hetzelfde werk opnieuw samen in een nieuwe samenvoegingscommit. +Figuur 3-39. Je merge hetzelfde werk opnieuw in een nieuwe merge commit. -Je moet dat werk op een bepaald punt samenvoegen, zodat je bij kunt blijven met de andere ontwikkelaar in de toekomst. Nadat je dat doet, zal je history zowel de C4 als de C4' commits bevatten, die verschillende SHA-1 hashes hebben, maar hetzelfde werk introduceren en hetzelfde commit bericht hebben. Als je een `git log` uitvoert als je historie er zo uitziet, dan zul je twee commits zien die dezelfde auteur en bericht hebben, wat verwarrend zal zijn. Daarnaast, als je deze historie terugzet naar de server, dan zul je al die gerebasete commits opnieuw introduceren op de centrale server, wat mensen nog meer kan verwarren. +Je moet dat werk op een bepaald punt mergen, zodat je in de toekomst bij kunt blijven met de andere ontwikkelaar. Nadat je dat gedaan hebt, zal je history zowel de C4 als de C4' commits bevatten, die verschillende SHA-1 hashes hebben, maar die hetzelfde werk introduceren en dezelfde commit bericht hebben. Als je een `git log` uitvoert als je historie er zo uitziet, dan zul je twee commits zien die dezelfde auteur, datum en bericht hebben, wat verwarring geeft. Daarnaast zal je, als je deze historie pushed naar de server, al die gerebasete commits opnieuw introduceren op de centrale server, wat mensen nog meer kan verwarren. -Als je rebasen behandelt als een manier om op te ruimen en met commits werkt voordat je ze terugzet, en als je alleen commits rebaset die nog nooit publiekelijk beschikbaar zijn geweest, dan zal alles in orde zijn. Als je commits rebaset die al publiekelijk teruggezet zijn, en mensen kunnen werk gebaseerd hebben op die commits, dan bereid je maar voor op wat frustrerende problemen. +Als je rebasen behandelt als een manier om commits op te ruimen ze bewerken voordat je ze pushed, en als je alleen commits rebaset die nog nooit publiekelijk beschikbaar zijn geweest, dan zal er niets aan de hand zijn. Als je commits rebaset die al publiekelijk gepushed zijn, en mensen kunnen werk gebaseerd hebben op die commits, bereid je dan maar voor op een aantal frustrerende problemen. ## Samenvatting ## -We hebben de basis van branchen en samenvoegen in Git behandeld. Je moet je op je gemak voelen met het maken en omschakelen naar nieuwe branches, schakelen tussen branches, en lokale branches samen te voegen. Je zou in staat moeten zijn om je branches te delen door ze naar een gedeelde server terug te zetten, met anderen op gedeelde branches samen te werken en je branches te rebasen voordat ze gedeeld zijn. +We hebben de basis van branchen en mergen in Git behandeld. Je zou je op je gemak moeten voelen met het maken en omschakelen naar nieuwe branches, omschakelen tussen branches, en lokale branches te mergen. Je zou in staat moeten zijn om je branches te delen door ze naar een gedeelde server te pushen, met anderen op gedeelde branches samen te werken en je branches te rebasen voordat ze gedeeld zijn. From abf31985675d451704cc852c0e8be8485a7c8e9c Mon Sep 17 00:00:00 2001 From: Matt Deacalion Stevens Date: Wed, 29 Jan 2014 18:04:09 +0000 Subject: [PATCH 134/690] Update command line output in Chapter 2 The command line output in the examples is from an older version of Git (1.7.*) and is slightly inconsistent with the latest version. --- en/02-git-basics/01-chapter2.markdown | 297 +++++++++++++------------- 1 file changed, 152 insertions(+), 145 deletions(-) diff --git a/en/02-git-basics/01-chapter2.markdown b/en/02-git-basics/01-chapter2.markdown index bbf48f64d..57d2103a7 100644 --- a/en/02-git-basics/01-chapter2.markdown +++ b/en/02-git-basics/01-chapter2.markdown @@ -54,8 +54,8 @@ Figure 2-1. The lifecycle of 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) + 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. @@ -63,11 +63,12 @@ Let’s say you add a new file to your project, a simple `README` file. If the f $ vim README $ git status - # On branch master - # Untracked files: - # (use "git add ..." to include in what will be committed) - # - # README + 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. @@ -81,12 +82,12 @@ In order to begin tracking a new file, you use the command `git add`. To begin t 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 - # + 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. @@ -95,58 +96,60 @@ You can tell that it’s staged because it’s under the “Changes to be commit 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 - # + 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) + (use "git checkout -- ..." to discard changes in working directory) + + 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 - # + 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 - # + 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) + (use "git checkout -- ..." to discard changes in working directory) + + 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 - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + new file: README + modified: benchmarks.rb + ### Ignoring Files ### @@ -192,17 +195,18 @@ If the `git status` command is too vague for you — you want to know exactly wh 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 - # + 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) + (use "git checkout -- ..." to discard changes in working directory) + + modified: benchmarks.rb + To see what you’ve changed but not yet staged, type `git diff` with no other arguments: @@ -247,16 +251,18 @@ For another example, if you stage the `benchmarks.rb` file and then edit it, you $ 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 - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + modified: benchmarks.rb + + 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 + Now you can use `git diff` to see what is still unstaged @@ -305,10 +311,9 @@ The editor displays the following text (this example is a Vim screen): # 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 + # ~ ~ ~ @@ -319,8 +324,8 @@ You can see that the default commit message contains the latest output of the `g 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(-) + [master 463dc4f] Fix benchmarks for speed + 2 files changed, 3 insertions(+) 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. @@ -332,15 +337,17 @@ Remember that the commit records the snapshot you set up in your staging area. A 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 - # + 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) + + modified: benchmarks.rb + + no changes added to commit (use "git add" and/or "git commit -a") $ git commit -a -m 'added new benchmarks' [master 83e38c7] added new benchmarks - 1 files changed, 5 insertions(+), 0 deletions(-) + 1 files changed, 5 insertions(+) Notice how you don’t have to run `git add` on the `benchmarks.rb` file in this case before you commit. @@ -352,26 +359,26 @@ If you simply remove the file from your working directory, it shows up under the $ 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 - # + On branch master + Changes not staged for commit: + (use "git add/rm ..." to update what will be committed) + (use "git checkout -- ..." to discard changes in working directory) + + deleted: grit.gemspec + + no changes added to commit (use "git add" and/or "git commit -a") 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 - # + 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. @@ -401,14 +408,12 @@ and it works fine. In fact, if you run something like this and look at the statu $ 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 - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + renamed: README.txt -> README + However, this is equivalent to running something like this: @@ -525,7 +530,7 @@ You can also use a series of summarizing options with `git log`. For example, if changed the version number Rakefile | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) + 1 file changed, 1 insertion(+), 1 deletion(-) commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 Author: Scott Chacon @@ -534,7 +539,7 @@ You can also use a series of summarizing options with `git log`. For example, if removed unnecessary test code lib/simplegit.rb | 5 ----- - 1 files changed, 0 insertions(+), 5 deletions(-) + 1 file changed, 5 deletions(-) commit a11bef06a3f659402fe7563abf99ad00de2209e6 Author: Scott Chacon @@ -545,7 +550,7 @@ You can also use a series of summarizing options with `git log`. For example, if README | 6 ++++++ Rakefile | 23 +++++++++++++++++++++++ lib/simplegit.rb | 25 +++++++++++++++++++++++++ - 3 files changed, 54 insertions(+), 0 deletions(-) + 3 files changed, 54 insertions(+) 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: @@ -700,31 +705,32 @@ The next two sections demonstrate how to wrangle your staging area and working d $ git add . $ git status - # On branch master - # Changes to be committed: - # (use "git reset HEAD ..." to unstage) - # - # modified: README.txt - # modified: benchmarks.rb - # + 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 + Unstaged changes after reset: + M benchmarks.rb $ 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 - # + 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. @@ -732,23 +738,23 @@ The command is a bit strange, but it works. The `benchmarks.rb` file is modified 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 - # + 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 - # + 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. @@ -764,12 +770,12 @@ Managing remote repositories includes knowing how to add remote repositories, re 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. + Cloning into 'ticgit'... + remote: Reusing existing pack: 1857, done. + remote: Total 1857 (delta 0), reused 0 (delta 0) + Receiving objects: 100% (1857/1857), 374.35 KiB | 193.00 KiB/s, done. + Resolving deltas: 100% (772/772), done. + Checking connectivity... done. $ cd ticgit $ git remote origin @@ -940,6 +946,7 @@ You can see the tag data along with the commit that was tagged by using the `git Date: Mon Feb 9 14:45:11 2009 -0800 my version 1.4 + commit 15027957951b64cf874c3557a0f3547bd83b3ff6 Merge: 4a447f7... a6b4c97... Author: Scott Chacon From 1d1ce116c69cda792844bf9eac6907a326ca5b09 Mon Sep 17 00:00:00 2001 From: cor Date: Sun, 26 Jan 2014 14:24:56 +0100 Subject: [PATCH 135/690] [nl] Retranslate chapter 05, first phase Replace strange character sequences with actual diacritics and hyphens. --- nl/05-distributed-git/01-chapter5.markdown | 336 +++++++++++---------- 1 file changed, 177 insertions(+), 159 deletions(-) diff --git a/nl/05-distributed-git/01-chapter5.markdown b/nl/05-distributed-git/01-chapter5.markdown index 1bfb363f2..cee8e7138 100644 --- a/nl/05-distributed-git/01-chapter5.markdown +++ b/nl/05-distributed-git/01-chapter5.markdown @@ -1,76 +1,76 @@ # Gedistribueerd Git # -Nu dat je een remote Git repository hebt ingesteld als een punt waar alle ontwikkelaars hun code kunnen delen, en je bekend bent met fundamentele Git commando's in een lokale werkwijze, zul je kijken hoe je een paar gedistribueerde werkwijzen kunt gebruiken die Git je toestaat. +Nu dat je een remote Git repository hebt ingesteld als een plaats waar alle ontwikkelaars hun code kunnen delen, en je bekend bent met fundamentele Git commando's in een lokale werkwijze, zul je hier zien hoe je een paar gedistribueerde werkwijzen kunt gebruiken die je met Git kunt bereiken. -In dit hoofdstuk zul je zien hoe je met Git kunt werken in een gedistribueerde omgeving als een bijdrager en als een integrator. Dat wil zeggen, je zult leren hoe je succesvol code kunt bijdragen aan een project en hoe je het zo makkelijk mogelijk maakt voor jou en de onderhouder van het project, en ook hoe je een project succesvol kunt onderhouden waarbij een aantal ontwikkelaars bijdragen. +In dit hoofdstuk zul je zien hoe je met Git kunt werken in een gedistribueerde omgeving als een bijdrager (contributor) en als een integrator. Dat wil zeggen, je zult leren hoe je succesvol code kunt bijdragen aan een project en hoe je het zo makkelijk mogelijk maakt voor jou en de onderhouder van het project, en ook hoe je een project succesvol kunt onderhouden waarbij een aantal ontwikkelaars bijdragen. ## Gedistribueerde werkwijzen ## -In tegenstelling tot gecentraliseerde versiebeheersystemen (CVCS), staat de gedistribueerde aard van Git je toe om veel flexibeler te zijn in de manier waarop ontwikkelaars bijdragen in projecten. Bij gecentraliseerde systemen is iedere ontwikkelaar een knooppunt dat min of meer gelijkwaardig werkt op een centraal punt. In Git is iedere ontwikkelaar zowel een knoop als een centraal punt – dat wil zeggen, iedere ontwikkelaar kan zowel code bijdragen aan andere repositories, als ook een publiek repository onderhouden waarop andere ontwikkelaars hun werk baseren en waaraan zij kunnen bijdragen. Dit stelt je project en of je team in staat om een enorm aantal werkwijzen er op na te houden, dus ik zal een aantal veel voorkomende manieren behandelen die gebruik maken van deze flexibiliteit. Ik zal de sterke en mogelijke zwakke punten van ieder ontwerp behandelen; je kunt er een kiezen om te gebruiken, of je kunt van iedere wijze een paar eigenschappen pakken en mengen. +In tegenstelling tot gecentraliseerde versiebeheersystemen (CVCSen), stelt de gedistribueerde aard van Git je in staat om veel flexibeler te zijn in de manier waarop ontwikkelaars samenwerken in projecten. Bij gecentraliseerde systemen is iedere ontwikkelaar een knooppunt dat min of meer gelijkwaardig werkt op een centraal punt. In Git is iedere ontwikkelaar zowel een knooppunt als een spil - dat wil zeggen, iedere ontwikkelaar kan zowel code bijdragen aan andere repositories, als ook een publiek repository beheren waarop andere ontwikkelaars hun werk baseren en waaraan zij kunnen bijdragen. Dit stelt je project en/of je team in staat om een enorm aantal werkwijzen er op na te houden, dus ik zal een aantal veel voorkomende manieren behandelen die gebruik maken van deze flexibiliteit. Ik zal de sterke en mogelijke zwakke punten van ieder ontwerp behandelen; je kunt er een kiezen om te gebruiken, of je kunt van iedere wijze een paar eigenschappen overnemen en mengen. ### Gecentraliseerde werkwijze ### -In gecentraliseerde systemen is er over het algemeen een enkel samenwerkingsmodel – de gecentraliseerde werkwijze. Eén centraal punt, of repository, kan code aanvaarden, en iedereen synchroniseert zijn werk daarmee. Een aantal ontwikkelaars zijn knopen – gebruikers van dat centrale punt – en synchroniseren met die plaats (zie Figuur 5-1). +In gecentraliseerde systemen is er over het algemeen een enkel samenwerkingsmodel - de gecentraliseerde werkwijze. En centraal punt, of repository, kan code aanvaarden, en iedereen synchroniseert zijn werk daarmee. Een aantal ontwikkelaars zijn knopen - gebruikers van dat centrale punt - en synchroniseren met die plaats (zie Figuur 5-1). Insert 18333fig0501.png Figuur 5-1. Gecentraliseerde Werkwijze. -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. +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 in Git zoals het ook werkt in Subversion (of ieder ander CVCS), en dit model werkt prima 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 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. +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 enkele repository in, en geef iedereen in je team push-toegang; 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. Ze zullen verteld worden dat ze een "non-fast-forward-wijziging" proberen te pushen en dat ze dat niet wordt toegestaan totdat ze hebben gefetched en gemerged. +Deze werkwijze is voor een hoop mensen aantrekkelijk omdat het er een 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 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): +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 (canonical) repository dat het "officile" 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 (pull request). Hij kan je repository toevoegen als een remote, je wijzigingen lokaal testen, ze in zijn branch mergen, 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 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. -6. De eigenaar zet samengevoegde wijzigingen terug in het hoofdrepository. +1. De projecteigenaar pushed naar de publieke repository. +2. Een bijdrager kloont die repository en maakt wijzigingen. +3. De bijdrager pushed naar zijn eigen publieke kopie. +4. De bijdrager stuurt de eigenaar een e-mail met de vraag om de wijzigingen binnen te halen (pull request). +5. De eigenaar voegt de repo van de bijdrager toe als een remote en merged lokaal. +6. De eigenaar pushed de gemergde wijzigingen terug in de hoofdrepository. Insert 18333fig0502.png Figuur 5-2. Integratie-manager werkwijze. -Dit is een veel voorkomende werkwijze bij websites zoals GitHub, waarbij het eenvoudig is om een project af te splitsen en je wijzigingen terug te zetten in jouw afgesplitste project zodat iedereen ze kan zien. Een van de grote voordelen van deze aanpak is dat je door kunt gaan met werken, en de eigenaar van het hoofdrepository jouw wijzigingen op ieder moment binnen kan halen. Bijdragers hoeven niet te wachten tot het project hun bijdragen invoegt – iedere partij kan op hun eigen tempo werken. +Dit is een veel voorkomende werkwijze bij websites zoals GitHub, waarbij het eenvoudig is om een project af te splitsen (fork) en je wijzigingen terug te zetten in jouw afgesplitste project waar iedereen ze kan zien. Een van de grote voordelen van deze aanpak is dat je door kunt gaan met werken, en de eigenaar van de hoofdrepository jouw wijzigingen op ieder moment binnen kan halen. Bijdragers hoeven niet te wachten tot het project hun bijdragen invoegt - iedere partij kan op zijn eigen tempo werken. ### Dictator en luitenanten werkwijze ### -Dit is een variant op de multi-repository werkwijze. Het wordt over het algemeen gebruikt bij enorme projecten met honderden bijdragers; een bekend voorbeeld is de Linux-kernel. Een aantal integrators geven de leiding over bepaalde delen van het repository; zij worden luitenanten genoemd. Alle luitenanten hebben één integrator die bekend staat als de welwillende dictator. Het repository van de welwillende dictator dient als het referentierepository vanwaar alle bijdragers dienen binnen te halen. Het proces werkt als volgt (zie Figuur 5-3): +Dit is een variant op de multi-repository werkwijze. Het wordt over het algemeen gebruikt bij enorme grote projecten met honderden bijdragers; een bekend voorbeeld is de Linux-kernel. Een aantal integrators geven de leiding over bepaalde delen van het repository, zij worden luitenanten genoemd. Alle luitenanten hebben n integrator die bekend staat als de welwillende dictator. De repository van de welwillende dictator dient als het referentierepository vanwaar alle bijdragers dienen binnen te halen. Het proces werkt als volgt (zie Figuur 5-3): -1. Reguliere ontwikkelaars werken op hun eigen onderwerp branch en rebasen hun werk op de hoofdbranch. De hoofdbranch is die van de dictator. -2. Luitenanten voegen de onderwerp branches van de ontwikkelaars samen in hun hoofdbranch. -3. De dictator voegt de hoofdbranches van de luitenanten samen in de "dictatorhoofdbranch". -4. De dictator zet zijn hoofdbranch terug naar het referentierepository zodat de andere ontwikkelaars kunnen rebasen. +1. Reguliere ontwikkelaars werken op hun eigen onderwerp (topic) branch en rebasen hun werk op de master. De masterbranch is die van de dictator. +2. Luitenanten mergen de topic branches van de ontwikkelaars in hun masterbranch. +3. De dictator merged de masterbranches van de luitenanten in de masterbranch van de dictator. +4. De dictator pushed zijn masterbranch terug naar het referentierepository zodat de andere ontwikkelaars kunnen rebasen. Insert 18333fig0503.png Figuur 5-3. Welwillende-dictatorwerkwijze. -Deze manier van werken komt niet vaak voor, maar kan handig zijn in hele grote projecten of in zeer hierarchische omgevingen, omdat het de projectleider (de dictator) toestaat om het meeste werk te delegeren en grote subsets van code te verzamelen op meerdere punten alvorens ze te integreren. +Deze manier van werken is niet gewoon, maar kan handig zijn in hele grote projecten of in zeer hirarchische omgevingen, omdat het de projectleider (de dictator) in staat stelt om het meeste werk te delegeren en grote subsets van code te verzamelen op meerdere punten alvorens ze te integreren. -Dit zijn veel voorkomende werkwijzen die mogelijk zijn met een gedistribueerd systeem als Git, maar je kunt zien dat er veel variaties mogelijk zijn die passen bij jouw specifieke werkwijze. Nu dat je (naar ik hoop) in staat bent om te bepalen welke werkwijze combinatie voor jou werkt, zal ik wat specifiekere voorbeelden behandelen over hoe je de hoofd rollen kunt vervullen, die in de verschillende werkwijzen voorkomen. +Dit zijn veel voorkomende werkwijzen die mogelijk zijn met een gedistribueerd systeem als Git, maar je kunt zien dat er veel variaties mogelijk zijn om ze te laten passen bij jouw specifieke werkwijze. Nu dat je (naar ik hoop) in staat bent om te bepalen welke combinatie van werkwijzen voor jou werkt, zal ik wat specifiekere voorbeelden behandelen over hoe je de belangrijkste rollen kunt vervullen, die in de verschillende werkwijzen voorkomen. ## Bijdragen aan een project ## -Je weet wat de verschillende werkwijzen zijn, en je zou een goed beeld moeten hebben van fundamenteel Git gebruik. In dit gedeelte zul je leren over een aantal voorkomende patronen voor het bijdragen aan een project. +Je weet wat de verschillende werkwijzen zijn, en je zou het fundamentele gebruik van Git in de vingers moeten hebben. In dit gedeelte zul je leren over een aantal voorkomende patronen voor het bijdragen aan een project. -De grote moeilijkheid bij het beschrijven van dit proces is dat er een enorm aantal variaties mogelijk zijn in hoe het gebeurd. Om dat Git erg flexibel is, kunnen en zullen mensen op vele manieren samenwerken, en het is lastig om te beschrijven hoe je zou moeten bijdragen aan een project – ieder project is een beetje anders. Een aantal van de betrokken variabelen zijn actieve bijdrage grootte, gekozen werkwijze, je commit toegang, een mogelijk de externe bijdrage methode. +De grote moeilijkheid bij het beschrijven van dit proces is dat er een enorm aantal variaties mogelijk zijn in hoe het gebeurt. Om dat Git erg flexibel is, kunnen en zullen mensen op vele manieren samenwerken, en het is lastig om te beschrijven hoe je zou moeten bijdragen aan een project - ieder project is een beetje anders. Een aantal van de betrokken variabelen zijn de grote van actieve bijdragen, gekozen werkwijze, je commit toegang, een mogelijk de manier waarop externe bijdragen worden gedaan. -De eerste variabele is de actieve bijdrage grootte. Hoeveel gebruikers dragen actief code bij aan dit project, en hoe vaak? In veel gevallen zul je twee of drie ontwikkelaars met een paar commits per dag hebben, of misschien minder voor wat slaperige projecten. Voor zeer grote bedrijven of projecten kan het aantal ontwikkelaars in de duizenden zijn, met tientallen of zelfs honderden patches die iedere dag binnenkomen. Dit is belangrijk omdat met meer en meer ontwikkelaars, je meer en meer problemen tegenkomt met het zeker zijn dat code netjes toegepast kan worden of eenvoudig samengevoegd kan worden. Wijzigingen die je toevoegt kunnen verouderd of zwaar beschadigd raken door werk dat samengevoegd is terwijl je er aan het werken was of terwijl je wijzigingen in de wacht stonden voor goedkeuring of toepassing. Hoe kun je je code consequent bij de tijd en je patches geldig houden? +De eerste variabele is de grootte van actieve bijdrage. Hoeveel gebruikers dragen actief code bij aan dit project, en hoe vaak? In veel gevallen zul je twee of drie ontwikkelaars met een paar commits per dag hebben, of misschien minder voor wat meer slapende projecten. Voor zeer grote bedrijven of projecten kan het aantal ontwikkelaars in de duizenden lopen, met tientallen of zelfs honderden patches die iedere dag binnenkomen. Dit is belangrijk omdat met meer en meer ontwikkelaars, je meer en meer problemen tegenkomt met het zeker zijn dat code netjes gepatched of eenvoudig gemerged kan worden. Wijzigingen die je indient kunnen verouderd of zwaar beschadigd raken door werk dat gemerged is terwijl je er aan het werken was of terwijl je wijzigingen in de wacht stonden voor goedkeuring of toepassing. Hoe kun je je code consequent bij de tijd en je patches geldig houden? -De volgende variabele is de gebruikte werkwijze in je project. Is het gecentraliseerd, waarbij iedere ontwikkelaar gelijkwaardige schrijftoegang heeft tot de hoofd codebasis? Heeft het project een eigenaar of integrator die alle patches nakijkt? Zijn alle patches gereviewed en goedgekeurd? Ben jij betrokken bij dat proces? Is er een luitenanten systeem in werking, en moet je je werk eerst bij hen inleveren? +De volgende variabele is de gebruikte werkwijze in het project. Is het gecentraliseerd, waarbij iedere ontwikkelaar gelijkwaardige schrijftoegang heeft tot de hoofd codebasis? Heeft het project een eigenaar of integrator die alle patches controleert? Worden alle patches gereviewed en goedgekeurd? Ben jij betrokken bij dat proces? Is er een luitenanten systeem neergezet, en moet je je werk eerst bij hen inleveren? -Het volgende probleem is je commit toegang. De benodigde werkwijze om bij te dragen aan een project is heel verschillend als je wel schrijftoegang hebt tot het project dan als je dat niet hebt. Als je geen schrijftoegang hebt, wat heeft het project dan als voorkeur om bijdragen te ontvangen? Heeft het wel een beleid? Hoeveel werk draag je per keer bij? Hoe vaak draag je bij? +Het volgende probleem is je commit toegang. De benodigde werkwijze om bij te dragen aan een project is heel verschillend als je schrijftoegang hebt tot het project dan wanneer je dat niet hebt. Als je geen schrijftoegang hebt, wat heeft de voorkeur van het project om bijdragen te ontvangen? Is er wel een beleid? Hoeveel werk draag je per keer bij? Hoe vaak draag je bij? -Al deze vragen kunnen van invloed zijn op hoe je effectief bijdraagt aan een project en welke werkwijzen de voorkeur hebben of die beschikbaar zijn voor je. Ik zal van ieder van deze aspecten wat behandelen in een aantal gevallen, waarbij ik van eenvoudig tot complex zal gaan; je zou in staat moeten zijn om de specifieke werkwijzen die je in de praktijk hebt te kunnen construeren vanuit deze voorbeelden. +Al deze vragen kunnen van invloed zijn op hoe je effectief bijdraagt aan een project en welke werkwijzen de voorkeur hebben of die beschikbaar zijn voor je. Ik zal een aantal van deze aspecten behandelen in een aantal voorbeelden, waarbij ik van eenvoudig tot complex zal gaan; je zou in staat moeten zijn om de specifieke werkwijzen die je in de praktijk hebt te kunnen herleiden vanuit deze voorbeelden. ### Commit richtlijnen ### -Voordat je gaat kijken naar de specifieke gebruiksscenario's, volgt hier een kort stukje over commit berichten. Het hebben van een goede richtlijn voor het maken commits en je daar aan houden maakt het werken met Git en samenwerken met anderen een stuk makkelijker. Het Git project levert een document waarin een aantal tips staan voor het maken van commits van waar je patches uit kunt indienen – je kunt het lezen in de Git broncode in het `Documentation/SubmittingPatches` bestand. +Voordat je gaat kijken naar de specifieke gebruiksscenario's, volgt hier een kort stukje over commit berichten. Het hebben van een goede richtlijn voor het maken commits en je daar aan houden maakt het werken met Git en samenwerken met anderen een stuk makkelijker. Het Git project levert een document waarin een aantal goede tips staan voor het maken van commits waaruit je patches kunt indienen - je kunt het lezen in de Git broncode in het `Documentation/SubmittingPatches` bestand. -Als eerste wil je geen witruimte fouten indienen. Git geeft je een eenvoudige manier om hierop te controleren – voordat je commit, voer `git diff --check` uit, wat mogelijke witruimte fouten identificeert en ze voor je afdrukt. Hier is een voorbeeld, waarbij ik een rode terminal kleur hebt vervangen door `X`en: +Als eerste wil je geen witruimte fouten indienen. Git geeft je een eenvoudige manier om hierop te controleren - voordat je commit, voer `git diff --check` uit, wat mogelijke witruimte fouten identificeert en ze voor je afdrukt. Hier is een voorbeeld, waarbij ik een rode terminal kleur hebt vervangen door `X`en: $ git diff --check lib/simplegit.rb:5: trailing whitespace. @@ -80,39 +80,40 @@ Als eerste wil je geen witruimte fouten indienen. Git geeft je een eenvoudige ma lib/simplegit.rb:26: trailing whitespace. + def command(git_cmd)XXXX -Als je dat commando uitvoert alvorens te committen, kun je al zien of je op het punt staat witruimte problemen te committen die andere ontwikkelaars boos kunnen maken. +Als je dat commando uitvoert alvorens te committen, kun je al zien of je op het punt staat witruimte problemen te committen die waaraan andere ontwikkelaars zich zullen ergeren. -Daarna, probeer om iedere van commit een logische set wijzigingen te maken. Probeer, als het je lukt, om je wijzigingen verteerbaar te maken – ga niet het hele weekend zitten coderen op vijf verschillende problemen om dat vervolgens op maandag als een gigantische commit in te dienen. Zelfs als je gedurende het weekend niet commit, gebruik dan het staging gebied op maandag om je werk in ten minste één commit per probleem op te splitsen, met een bruikbaar bericht per commit. Als een paar van de wijzigingen één bestand veranderen, probeer dan `git add --patch` te gebruiken om bestanden gedeeltelijk te stagen (wordt in detail behandeld in Hoofdstuk 6). Het snapshot van het project is gelijk of je nu één commit doet of vijf, zolang alle wijzigingen maar toegevoegd zijn op een bepaald punt, dus probeer om het je mede-ontwikkelaars makkelijk te maken als ze je wijzigingen moeten bekijken. Deze aanpak maakt het ook makkelijker om één wijziging op te halen of terug te draaien, mocht dat later nodig zijn. Hoofdstuk 6 beschrijft een aantal handige Git trucs om geschiedenis te herschrijven en bestanden interactief te stagen – gebruik deze applicaties om te helpen een schone en begrijpelijke historie op te bouwen. +Probeer vervolgens om van elke commit een logische set wijzigingen te maken. Probeer, als het je lukt, om je wijzigingen verteerbaar te maken - ga niet het hele weekend zitten coderen op vijf verschillende problemen om dat vervolgens op maandag als een gigantische commit in te dienen. Zelfs als je gedurende het weekend niet commit, gebruik dan het staging gebied op maandag om je werk in ten minste n commit per probleem op te splitsen, met een bruikbaar bericht per commit. Als een paar van de wijzigingen n bestand veranderen, probeer dan `git add --patch` te gebruiken om bestanden gedeeltelijk te stagen (wordt in detail behandeld in Hoofdstuk 6). De laatste snapshot van het project is gelijk of je nu n commit doet of vijf, zolang alle wijzigingen op een gegeven momment maar toegevoegd zijn, dus probeer om het je mede-ontwikkelaars makkelijk te maken als ze je wijzigingen moeten bekijken. Deze aanpak maakt het ook makkelijker om n wijziging te pullen of terug te draaien, mocht dat later nodig zijn. Hoofdstuk 6 beschrijft een aantal handige Git trucs om geschiedenis te herschrijven en bestanden interactief te stagen - gebruik deze gereedschappen een schone en begrijpelijke historie te helpen op te bouwen. -Het laatste ding om in gedachten te houden is het commit bericht. Als je er een gewoonte van maakt om een goede kwaliteit commit berichten aan te maken, dan maakt dat het gebruik van en samenwerken in Git een stuk eenvoudiger. Als een algemene regel, zouden je berichten moeten beginnen met een enkele regel, die niet langer is dan 50 karakters en die de set wijzigingen beknopt omschrijft, gevolgd door een lege regel. Daarna volgt de meer gedetailleerde uitleg. Het Git project vereist dat de meer gedetailleerde omschrijving ook je motivatie voor de verandering bevat, en de nieuwe implementatie tegen het oude gedrag afzet – dit is een goede richtlijn om te volgen. Het is ook een goed idee om de gebiedende wijs te gebruiken in deze berichten. Met andere woorden, gebruik commando's. In plaats van "Ik heb testen toegevoegd voor" of "Testen toegevoegd voor" gebruik je "Voeg testen toe voor". +Het laatste om in gedachten te houden is het commit bericht. Als je er een gewoonte van maakt om een goede kwaliteit commit berichten aan te maken, dan maakt dat het gebruik van en samenwerken in Git een stuk eenvoudiger. In het algemeen, zouden je berichten moeten beginnen met een enkele regel, die niet langer is dan 50 karakters en die de wijzigingen beknopt omschrijft, gevolgd door een lege regel en daarna een meer gedetailleerde uitleg. Het Git project vereist dat de meer gedetailleerde omschrijving ook je motivatie voor de verandering bevat, en de nieuwe implementatie tegen het oude gedrag afzet. Dit is een goede richtlijn om te volgen. Het is ook een goed idee om de gebiedende wijs te gebruiken in deze berichten. Met andere woorden, gebruik commando's. In plaats van "Ik heb testen toegevoegd voor" of "Testen toegevoegd voor" gebruik je "Voeg testen toe voor". Hier is een sjabloon dat origineel geschreven is door Tim Pope op tpope.net: Kort (50 karakters of minder) samenvatting van wijzigingen - Gedetailleerdere tekst uitleg, als nodig. Laat het in ongeveer 72 - karakters afbreken. In sommige contexten, wordt de eerste regel - behandeld als het onderwerp van een email en de rest als inhoud. - De lege regel die de samenvatting scheidt van de inhoud is van - kritiek belang (tenzij je de inhoud helemaal weglaat); applicaties - zoals rebase kunnen in de war raken als je ze samenvoegt. + Gedetailleerdere beschrijvende tekst, indien nodig. Laat het na + ongeveer 72 karakters afbreken. In sommige contexten, wordt de + eerste regel behandeld als het onderwerp van een email en de rest + als inhoud. De lege regel die de samenvatting scheidt van de + inhoud is essentieel (tenzij je de inhoud helemaal weglaat); + applicaties zoals rebase kunnen in de war raken als je ze + samenvoegt. Vervolg paragrafen komen na lege regels. - Aandachtspunten zijn ook goed. - - Typisch wordt een streepje of sterretje gebruikt als punt, voorafgegaan - door een enkele spatie, met ertussen lege regels, maar de conventies - variëren hierin. + - Typisch wordt een streepje of sterretje gebruikt als "bullet", + voorafgegaan door een enkele spatie, met ertussen lege regels, + maar de conventies variren hierin. -Als al je commit berichten er zo uit zien, dan zullen de dingen een stuk eenvoudiger zijn voor jou en de ontwikkelaars waar je mee werkt. Het Git project heeft goed geformatteerde commit berichten – ik raad je aan om `git log --no-merges` uit te voeren om te zien hoe een goed geformatteerde project-commit historie eruit ziet. +Als al je commit berichten er zo uit zien, dan zullen de dingen een stuk eenvoudiger zijn voor jou en de ontwikkelaars waar je mee samenwerkt. Het Git project heeft goed geformatteerde commit berichten - ik raad je aan om `git log --no-merges` uit te voeren om te zien hoe een goed geformatteerde project-commit historie eruit ziet. In de volgende voorbeelden, en verder door de rest van dit boek, zal ik omwille van bondigheid de berichten niet zo netjes als dit formatteren; in plaats daarvan gebruik ik de `-m` optie voor `git commit`. Doe wat ik zeg, niet wat ik doe. ### Besloten klein team ### -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. +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 push 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. +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 mergen, maar de werkwijze kan erg vergelijkbaar zijn. Het grote verschil is dat het mergen 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, 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 @@ -125,7 +126,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 – kloont 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 @@ -137,7 +138,7 @@ De tweede ontwikkelaar, Jessica, doet hetzelfde – kloont de repository en comm [master fbff5bc] add reset task 1 files changed, 1 insertions(+), 0 deletions(-) -Nu zet Jessica haar werk terug op de server: +Nu pushed Jessica haar werk naar de server: # Jessica's Machine $ git push origin master @@ -145,7 +146,7 @@ Nu zet Jessica haar werk terug op de server: To jessica@githost:simplegit.git 1edee6b..fbff5bc master -> master -John probeert ook zijn werk terug te zetten: +John probeert ook zijn werk te pushen: # John's Machine $ git push origin master @@ -153,31 +154,31 @@ John probeert ook zijn werk terug te zetten: ! [rejected] master -> master (non-fast forward) error: failed to push some refs to 'john@githost:simplegit.git' -John mag niet terugzetten omdat Jessica in de tussentijd teruggezet heeft. Dit is in het bijzonder belangrijk om te begrijpen als je gewoon bent aan Subversion, omdat het je zal opvallen dat de twee ontwikkelaars niet hetzelfde bestand hebben aangepast. Alhoewel Subversion automatisch zo'n samenvoeging op de server doet, als verschillende bestanden zijn aangepast, moet je in Git de commits lokaal samenvoegen. John moet Jessica's wijzigingen ophalen en ze samenvoegen voor hij terug mag zetten: +John mag niet terugzetten omdat Jessica in de tussentijd gepushed heeft. Dit is belangrijk om te begrijpen als je gewoon bent aan Subversion, omdat het je zal opvallen dat de twee ontwikkelaars niet hetzelfde bestand hebben aangepast. Waar Subversion automatisch zo'n merge op de server doet, als verschillende bestanden zijn aangepast, moet je in Git de commits lokaal mergen. John moet Jessica's wijzigingen ophalen (fetch) en ze mergen voor hij mag pushen: $ git fetch origin ... From john@githost:simplegit + 049d078...fbff5bc master -> origin/master -Op dit punt ziet John's lokale repository er ongeveer uit zoals Figuur 5-4. +Hierna ziet John's lokale repository er ongeveer uit zoals Figuur 5-4. Insert 18333fig0504.png -Figuur 5-4. John’s initiële repository. +Figuur 5-4. John's initile repository. -John heeft een referentie naar de wijzigingen die Jessica teruggezet heeft, maar hij moet ze samenvoegen met zijn eigen werk voordat hij het terug mag zetten: +John heeft een referentie naar de wijzigingen die Jessica gepushed heeft, maar hij moet ze mergen met zijn eigen werk voordat hij het mag pushen: $ git merge origin/master Merge made by recursive. TODO | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) -Het samenvoegen gaat soepel – de commit historie van John ziet er nu uit als Figuur 5-5. +Het samenvoegen gaat soepeltjes - de commit historie van John ziet er nu uit als Figuur 5-5. Insert 18333fig0505.png -Figuur 5-5. John’s repository na het samenvoegen van origin/master. +Figuur 5-5. John's repository na het samenvoegen van origin/master. -Nu kan John zijn code testen om er zeker van te zijn dat het nog steeds goed werkt, en dan kan hij zijn nieuwe samengevoegde werk terugzetten op de server: +Nu kan John zijn code testen om er zeker van te zijn dat het nog steeds goed werkt, en dan kan hij zijn nieuwe samengevoegde werk pushen naar de server: $ git push origin master ... @@ -187,12 +188,12 @@ Nu kan John zijn code testen om er zeker van te zijn dat het nog steeds goed wer Tenslotte ziet John's commit historie eruit als Figuur 5-6. Insert 18333fig0506.png -Figuur 5-6. John’s historie na teruggezet te hebben op de origin van de server. +Figuur 5-6. John's historie na gepushed te hebben naar de origin van de server. -In de tussentijd heeft Jessica gewerkt op een onderwerp branch. Ze heeft een onderwerp branch genaamd `issue54` aangemaakt en daar drie commits op gedaan. Ze heeft John's wijzigingen nog niet opgehaald, dus haar commit historie ziet er uit als Figuur 5-7. +In de tussentijd heeft Jessica gewerkt op een topic branch. Ze heeft een topic branch genaamd `issue54` aangemaakt en daar drie commits op gedaan. Ze heeft John's wijzigingen nog niet opgehaald, dus haar commit historie ziet er uit als Figuur 5-7. Insert 18333fig0507.png -Figuur 5-7. Jessica’s initiële commit historie. +Figuur 5-7. Jessica's initile commit historie. Jessica wil met John synchroniseren, dus ze haalt de wijzigingen op: @@ -202,12 +203,12 @@ Jessica wil met John synchroniseren, dus ze haalt de wijzigingen op: From jessica@githost:simplegit fbff5bc..72bbc59 master -> origin/master -Dit haalt het werk op dat John in de tussentijd teruggezet heeft. Jessica's historie ziet er nu uit als Figuur 5-8. +Dit haalt het werk op dat John in de tussentijd gepushed heeft. Jessica's historie ziet er nu uit als Figuur 5-8. Insert 18333fig0508.png -Figuur 5-8. Jessica’s historie na het ophalen van John's wijzigingen. +Figuur 5-8. Jessica's historie na het ophalen van John's wijzigingen. -Jessica denkt dat haar onderwerp branch nu klaar is, maar ze wil weten wat ze in haar werk moet samenvoegen zodat ze terug kan zetten. Ze voert `git log` uit om dat uit te zoeken: +Jessica denkt dat haar topic branch nu klaar is, maar ze wil weten wat ze in haar werk moet mergen zodat ze kan pushen. Ze voert `git log` uit om dat uit te zoeken: $ git log --no-merges origin/master ^issue54 commit 738ee872852dfaa9d6634e0dea7a324040193016 @@ -216,13 +217,13 @@ Jessica denkt dat haar onderwerp branch nu klaar is, maar ze wil weten wat ze in removed invalid default value -Nu kan Jessica het werk van haar onderwerp samenvoegen in haar master branch, John's werk (`origin/master`) in haar `master` branch samenvoegen, en dat naar de server terugzetten. Eerst schakelt ze terug naar haar master branch om al dit werk te integreren: +Nu kan Jessica het werk van haar onderwerp mergen in haar `master` branch, John's werk (`origin/master`) in haar `master` branch mergen, en dan naar de server pushen. Eerst schakelt ze terug naar haar `master` branch om al dit werk te integreren: $ git checkout master Switched to branch "master" Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. -Ze kan of `origin/master` of `issue54` als eerste samenvoegen – ze zijn beide stroomopwaarts dus de volgorde maakt niet uit. De snapshot aan het einde zou gelijk moeten zijn ongeacht welke volgorde ze kiest; alleen de geschiedenis zal iets verschillen. Ze kiest ervoor om `issue54` eerst samen te voegen: +Ze kan of `origin/master` of `issue54` als eerste samenvoegen - ze zijn beide stroomopwaarts dus de volgorde maakt niet uit. Op het eind zou de snapshot gelijk moeten zijn ongeacht welke volgorde ze kiest; alleen de geschiedenis zal iets verschillen. Ze kiest ervoor om `issue54` eerst samen te voegen: $ git merge issue54 Updating fbff5bc..4af4298 @@ -231,7 +232,7 @@ Ze kan of `origin/master` of `issue54` als eerste samenvoegen – ze zijn beide lib/simplegit.rb | 6 +++++- 2 files changed, 6 insertions(+), 1 deletions(-) -Er doen zich geen problemen voor; zoals je kunt zien was het een eenvoudige fast-forward. Nu voegt Jessica John's werk in (`origin/master`): +Er doen zich geen problemen voor, zoals je kunt zien was het een eenvoudige fast-forward. Nu merged Jessica John's werk (`origin/master`): $ git merge origin/master Auto-merging lib/simplegit.rb @@ -239,35 +240,35 @@ Er doen zich geen problemen voor; zoals je kunt zien was het een eenvoudige fast lib/simplegit.rb | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) -Alles voegt netjes samen, en Jessica's historie ziet er uit als Figuur 5-9. +Alles merged netjes, en Jessica's historie ziet er uit als Figuur 5-9. Insert 18333fig0509.png -Figuur 5-9. Jessica’s historie na het samenvoegen van John’s wijzigingen. +Figuur 5-9. Jessica's historie na het mergen van John's wijzigingen. -Nu is `origin/master` bereikbaar vanuit Jessica's `master` branch, dus ze zou in staat moeten zijn om succesvol terug te kunnen zetten (er vanuit gegaan dat John in de tussentijd niets teruggezet heeft): +Nu is `origin/master` bereikbaar vanuit Jessica's `master` branch, dus ze zou in staat moeten zijn om succesvol te pushen (even aangenomen dat John in de tussentijd niets gepushed heeft): $ git push origin master ... To jessica@githost:simplegit.git 72bbc59..8059c15 master -> master -Iedere ontwikkelaar heeft een paar keer gecommit en elkaars werk succesvol samengevoegd; zie Figuur 5-10. +Iedere ontwikkelaar heeft een paar keer gecommit en elkaars werk succesvol samengevoegd, zie Figuur 5-10. Insert 18333fig0510.png -Figuur 5-10. Jessica’s historie na alle wijzigingen teruggezet te hebben op de server. +Figuur 5-10. Jessica's historie na alle wijzigingen teruggezet te hebben op de server. -Dat is één van de eenvoudigste werkwijzen. Je werkt een tijdje, over het algemeen in een onderwerp branch, en voegt samen in je master branch als het klaar is om te worden geïntegreerd. Als je dat werk wilt delen, dan voeg je het samen in je eigen master branch, en vervolgens haal je `origin/master` op en voegt het samen als het gewijzigd is, en als laatste zet je terug op de `master` branch op de server. De algemene volgorde is zoiets als die getoond in Figuur 5-11. +Dit is n van de eenvoudigste werkwijzen. Je werkt een tijdje, over het algemeen in een topic branch, en merged in je `master` branch als het klaar is om te worden gentegreerd. Als je dat werk wilt delen, dan merge je het in je eigen `master` branch, en vervolgens fetch je `origin/master` en merge je deze als het gewijzigd is, en als laatste push je deze naar de `master` branch op de server. De algemene volgorde is zoiets als die getoond in Figuur 5-11. Insert 18333fig0511.png Figuur 5-11. Algemene volgorde van gebeurtenissen voor een eenvoudige multi-ontwikkelaar Git werkwijze. ### Besloten aangestuurd team ### -In het volgende scenario zul je kijken naar de rol van de bijdragers in een grotere besloten groep. Je zult leren hoe te werken in een omgeving waar kleine groepen samenwerken aan functies, waarna die team-gebaseerde bijdragen worden geïntegreerd door een andere partij. +In het volgende scenario zul je kijken naar de rol van de bijdragers in een grotere besloten groep. Je zult leren hoe te werken in een omgeving waar kleine groepen samenwerken aan functies, waarna die team-gebaseerde bijdragen worden gentegreerd door een andere partij. -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. +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 gentegreerd door bepaalde ontwikkelaars, en de `master` branch van het hoofd repo alleen kan worden vernieuwd door die ontwikkelaars. 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 gekloond 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 verschillende ontwikkelaars in deze omgeving. We nemen even aand dat ze haar repository al gekloond heeft, en dat ze besloten heeft 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 @@ -277,14 +278,14 @@ Laten we Jessica's werkwijze volgen terwijl ze aan haar twee functies werkt, in [featureA 3300904] add limit to log function 1 files changed, 1 insertions(+), 1 deletions(-) -Op dit punt, moet ze haar werk delen met John, dus ze zet haar commits op de `featureA` branch terug naar de server. Jessica heeft geen terugzet toegang op de `master` branch – alleen de integratoren hebben dat – dus ze moet naar een andere branch terugzetten om samen te kunnen werken met John: +Op dit punt, moet ze haar werk delen met John, dus ze pushed haar commits naar de `featureA` branch op de server. Jessica heeft geen push toegang op de `master` branch - alleen de integratoren hebben dat - dus ze moet naar een andere branch pushen om samen te kunnen werken met John: $ git push origin featureA ... To jessica@githost:simplegit.git * [new branch] featureA -> featureA -Jessica e-mailt John om hem te zeggen dat ze wat werk teruggezet heeft in een branch genaamd `featureA` en dat hij er nu naar kan kijken. Terwijl ze op terugkoppeling van John wacht, besluit Jessica te beginnen met het werken aan `featureB` met Josie. Om te beginnen start ze een nieuwe functie branch, gebaseerd op de `master` branch van de server: +Jessica mailt John om hem te zeggen dat ze wat werk gepushed heeft in een branch genaamd `featureA` en dat hij er nu naar kan kijken. Terwijl ze op terugkoppeling van John wacht, besluit Jessica te beginnen met het werken aan `featureB` met Josie. Om te beginnen start ze een nieuwe functie branch, gebaseerd op de `master` branch van de server: # Jessica's Machine $ git fetch origin @@ -305,16 +306,16 @@ Nu doet Jessica een paar commits op de `featureB` branch: Jessica's repository ziet eruit als Figuur 5-12. Insert 18333fig0512.png -Figuur 5-12. Jessica’s initiële commit historie. +Figuur 5-12. Jessica's initile commit historie. -Ze is klaar om haar werk terug te zetten, maar ze krijgt een e-mail van Josie dat een branch met wat initieel werk erin al teruggezet is naar de server als `featureBee`. Jessica moet die wijzigingen eerst samenvoegen met haar eigen voordat ze terug kan zetten naar de server. Ze kan dan Josie's wijzigingen ophalen met `git fetch`: +Ze is klaar om haar werk te pushen, maar ze krijgt een mail van Josie dat een branch met wat initieel werk erin al gepushed is naar de server in de `featureBee` branch. Jessica moet die wijzigingen eerst mergen met die van haar voordat ze kan pushen naar de server. Ze kan dan Josie's wijzigingen ophalen met `git fetch`: $ git fetch origin ... From jessica@githost:simplegit * [new branch] featureBee -> origin/featureBee -Jessica kan dit nu samenvoegen in haar werk met `git merge`: +Jessica kan dit nu mergen in het werk wat zij gedaan heeft met `git merge`: $ git merge origin/featureBee Auto-merging lib/simplegit.rb @@ -322,16 +323,16 @@ Jessica kan dit nu samenvoegen in haar werk met `git merge`: lib/simplegit.rb | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) -Er is wel een klein probleem – ze moet het samengevoegde werk in haar `featureB` branch naar de `featureBee` branch op de server zetten. Ze kan dat doen door de lokale branch te specificeren aan het `git push` commando, gevolgd door een dubbele punt (:), gevolgd door de remote branch: +Er is wel een klein probleempje - ze moet het gemergde werk in haar `featureB` branch naar de `featureBee` branch op de server zetten. Ze kan dat doen door de lokale branch te specificeren aan het `git push` commando, gevolgd door een dubbele punt (:), gevolgd door de remote branch: $ git push origin featureB:featureBee ... To jessica@githost:simplegit.git fba9af8..cd685d1 featureB -> featureBee -Dit wordt een _refspec_ genoemd. Zie Hoofdstuk 9 voor een gedetailleerdere discussie van Git refspecs en de verschillende dingen die je met ze kan doen. +Dit wordt een _refspec_ genoemd. Zie Hoofdstuk 9 voor een gedetailleerdere behandeling van Git refspecs en de verschillende dingen die je daarmee kan doen. -Vervolgens e-mailt John naar Jessica om te zeggen dat hij wat wijzigingen naar de `featureA` branch teruggezet heeft, en om haar te vragen die te verifiëren. Ze voert een `git fetch` uit om die wijzigingen op te halen: +Vervolgens mailt John naar Jessica om te zeggen dat hij wat wijzigingen naar de `featureA` branch gepushed heeft, en om haar te vragen die te verifiren. Ze voert een `git fetch` uit om die wijzigingen op te halen: $ git fetch origin ... @@ -347,7 +348,7 @@ Daarna kan ze zien wat er veranderd is met `git log`: changed log output to 30 from 25 -Uiteindelijk voegt ze John's werk in haar eigen `featureA` branch: +Uiteindelijk merged ze John's werk in haar eigen `featureA` branch: $ git checkout featureA Switched to branch "featureA" @@ -357,7 +358,7 @@ Uiteindelijk voegt ze John's werk in haar eigen `featureA` branch: lib/simplegit.rb | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) -Jessica wil iets fijnstellen, dus doet ze nog een commit en zet dit terug naar de server: +Jessica wil iets kleins wijzigen, dus doet ze nog een commit en pushed dit naar de server: $ git commit -am 'small tweak' [featureA ed774b3] small tweak @@ -370,24 +371,24 @@ Jessica wil iets fijnstellen, dus doet ze nog een commit en zet dit terug naar d Jessica's commit historie ziet er nu uit zoals Figuur 5-13. Insert 18333fig0513.png -Figuur 5-13. Jessica’s historie na het committen op een functie branch. +Figuur 5-13. Jessica's historie na het committen op een functie branch. -Jessica, Josie en John informeren de integrators nu dat de `featureA` en `featureBee` branches op de server klaar zijn voor integratie in de hoofdlijn. Nadat ze die branches in de hoofdlijn geïntegreerd hebben, zal een fetch de nieuwe samenvoeg commits ophalen, waardoor de commit historie er uit ziet zoals Figuur 5-14. +Jessica, Josie en John informeren de integrators nu dat de `featureA` en `featureBee` branches op de server klaar zijn voor integratie in de hoofdlijn. Nadat zij die branches in de hoofdlijn gentegreerd hebben, zal een fetch de nieuwe merge commits ophalen, waardoor de commit historie er uit ziet zoals Figuur 5-14. Insert 18333fig0514.png -Figuur 5-14. Jessica’s historie na het samenvoegen van allebei haar onderwerp branches. +Figuur 5-14. Jessica's historie na het samenvoegen van allebei haar onderwerp branches. -Veel groepen schakelen om naar Git voor deze mogelijkheid om meerdere teams in parallel te kunnen laten werken, waarbij de verschillende lijnen van werk laat in het proces samengevoegd worden. De mogelijkheid van kleinere subgroepen of een team om samen te werken via remote branches zonder het betrekken of dwarsliggen van het hele team is een enorm voordeel van Git. De volgorde van de werkwijze die je hier zag is ongeveer zoals Figuur 5-15. +Veel groepen schakelen om naar Git juist vanwege de mogelijkheid om meerdere teams in parallel te kunnen laten werken, waarbij de verschillende lijnen van werk laat in het proces gemerged worden. De mogelijkheid van kleinere subgroepen of een team om samen te werken via remote branches zonder het hele team erin te betrekken of te hinderen is een enorm voordeel van Git. De volgorde van de werkwijze die je hier zag is ongeveer zoals Figuur 5-15. Insert 18333fig0515.png -Figuur 5-15. Basale volgorde van de werkwijze van dit aangestuurde team. +Figuur 5-15. Eenvoudige volgorde in de werkwijze van dit aangestuurde team. -### Klein publiek project ### +### Klein openbaar project ### -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. +Het bijdragen aan openbare, of publieke, projecten gaat op een iets andere manier. Omdat je niet de toestemming hebt om de branches van het project te updaten, moet je het werk op een andere manier naar de beheerders krijgen. Dit eerste voorbeeld beschrijft het bijdragen via afsplitsen (forken) op Git hosts, die het makkelijk maken om te forken. De repo.or.cz en GitHub hosting sites ondersteunen dit beiden, en veel project beheerders verwachten deze manier van bijdragen. De volgende paragraaf behandelt projecten die de voorkeur hebben om bijdragen in de vorm van patches via e-mail te ontvangen. -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: +Eerst zal je waarschijnlijk de hoofdrepository klonen, een topic branch maken voor de patch of reeks patches die je van plan bent bij te dragen, en je werk daarop doen. De werkwijze ziet er zo uit: $ git clone (url) $ cd project @@ -397,19 +398,19 @@ Eerst wil je waarschijnlijk het hoofdrepository klonen, een onderwerp branch mak $ (work) $ git commit -Je wil misschien de `rebase -i` optie gebruiken om je werk in één enkele commit samen te persen, of het werk in de commits herschikken om de patch eenvoudiger te kunnen laten reviewen door de beheerders – zie Hoofdstuk 6 voor meer informatie over het interactief rebasen. +Je wil misschien de `rebase -i` optie gebruiken om je werk in n enkele commit samen te persen (squash), of het werk in de commits herschikken om de patch eenvoudiger te kunnen laten reviewen door de beheerders - zie Hoofdstuk 6 voor meer informatie over het interactief rebasen. -Als je werk op de branch af is, en je klaar bent om het bij te dragen aan de beheerders, ga dan naar de originele project pagina en klik op de "Fork" knop, waarmee je een eigen schrijfbare fork van het project maakt. Je moet dit dan in een nieuwe repository URL toevoegen als een tweede remote, in dit geval `myfork` genaamd: +Als je werk op de branch af is, en je klaar bent om het over te dragen aan de beheerders, ga je naar de originele project pagina en klik op de "Fork" knop, hiermee maak je een eigen schrijfbare fork van het project. Je moet dit dan in een nieuwe repository URL toevoegen als een tweede remote, in dit geval `myfork` genaamd: $ git remote add myfork (url) -Je moet je werk hier naar terugzetten. Het is het makkelijkst om de remote branch waar je op zit te werken terug te zetten naar je repository, in plaats van het samenvoegen in je master branch en die terug te zetten. De reden is dat als het werk niet wordt geaccepteerd of ge-cherry picked, je je master branch niet hoeft terug te draaien. Als de beheerders je werk samenvoegen, rebasen of cherry picken, dan krijg je het uiteindelijk toch terug door hun repository binnen te halen: +Je moet je werk hier naar pushen. Het is het makkelijkst om de remote branch waar je op zit te werken te pushen naar je repository, in plaats van het samenvoegen in je master branch en die terug te zetten. De reden hiervan is, dat als het werk niet wordt geaccepteerd of alleen ge-cherry picked, je jouw master branch niet hoeft terug te draaien. Als de beheerders je werk mergen, rebasen of cherry picken, dan krijg je het uiteindelijk toch terug door hun repository te pullen: $ git push myfork featureA -Als jouw werk teruggezet is naar je fork, dan moet je de beheerder waarschuwen. Dit wordt vaak een pull request (haal binnen verzoek) genoemd, en je kunt het of via de website genereren – GitHub heeft een "pull request" knop die de beheerder automatisch een bericht stuurt – of het `git request-pull` commando uitvoeren en de uitvoer handmatig naar de beheerder e-mailen. +Als jouw werk gepushed is naar jouw fork, dan moet je de beheerder een seintje geven. Dit wordt vaak een pull request (haal-binnen-verzoek) genoemd, en je kunt het via de website genereren - GitHub heeft een "pull request" knop die de beheerder automatisch een bericht stuurt - of het `git request-pull` commando uitvoeren en de uitvoer handmatig naar de projectbeheerder mailen. -Het `request-pull` commando accepteert de basis branch waarin je je onderwerp branch binnen gehaald wil hebben, en de URL van het Git repository waarvan je ze wil laten halen, en voert een samenvatting uit van alle wijzigingen die je binnengehaald wenst te hebben. Bijvoorbeeld, als Jessica John een pull request wil sturen, en ze heeft twee commits gedaan op de onderwerp branch die ze zojuist teruggezet heeft, dan kan ze dit uitvoeren: +Het `request-pull` commando neemt de branch waarin je je topic branch gepulled wil hebben, en de URL van de Git repository waar je ze uit wil laten pullen, en maakt een samenvatting van alle wijzigingen die je gepulled wenst te hebben. Bijvoorbeeld, als Jessica John een pull request wil sturen, en ze heeft twee commits gedaan op de topic branch die ze zojuist gepushed heeft, dan kan ze dit uitvoeren: $ git request-pull origin/master myfork The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40: @@ -427,9 +428,9 @@ Het `request-pull` commando accepteert de basis branch waarin je je onderwerp br lib/simplegit.rb | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) -De uitvoer kan naar de beheerder gestuurd worden – het verteld ze waar het werk vanaf gebranched is, vat de commits samen, en verteld waar ze dit werk vandaan kunnen halen. +De uitvoer kan naar de beheerder gestuurd worden: het verteld ze waar het werk vanaf gebranched is, vat de commits samen, en verteld waar vandaan ze dit werk kunnen pullen. -Bij een project waarvan je niet de beheerder bent, is het over het algemeen eenvoudiger om een branch zoals `master` altijd de `origin/master` te laten volgen, en je werk te doen in onderwerp branches die je eenvoudig weg kunt gooien als ze geweigerd worden. Als je je werk thema's gescheiden hebt in onderwerp branches maakt dat het ook eenvoudiger voor jou om je werk te rebasen als de punt van het hoof repository in de tussentijd verschoven is en je commits niet langer netjes toegepast kunnen worden. Bijvoorbeeld, als je een tweede onderwerp wil bijdragen aan een project, ga dan niet verder werken op de onderwerp branch die je zojuist teruggezet hebt – begin opnieuw vanaf de `master` branch van het hoofd repository: +Bij een project waarvan je niet de beheerder bent, is het over het algemeen eenvoudiger om een branch zoals `master` altijd de `origin/master` te laten volgen, en je werk te doen in topic branches die je eenvoudig weg kunt gooien als ze geweigerd worden. Als je je werkthema's gescheiden houdt in topic branches maakt dat het ook eenvoudiger voor jou om je werk te rebasen als de punt van het hoofd repository in de tussentijd verschoven is en je commits niet langer netjes toegepast kunnen worden. Bijvoorbeeld, als je een tweede onderwerp wil bijdragen aan een project, ga dan niet verder werken op de topic branch die je zojuist gepushed hebt - begin opnieuw vanaf de `master` branch van het hoofd repository: $ git checkout -b featureB origin/master $ (work) @@ -438,25 +439,25 @@ Bij een project waarvan je niet de beheerder bent, is het over het algemeen eenv $ (email maintainer) $ git fetch origin -Nu zijn al je onderwerpen opgeslagen in een silo – vergelijkbaar met een patch rij – die je kunt herschrijven, rebasen en wijzigen zonder dat de onderwerpen elkaar in de weg zitten of afhankelijk zijn zoals in Figuur 5-16. +Nu zijn al je onderwerpen opgeslagen in een silo - vergelijkbaar met een patch rij - die je kunt herschrijven, rebasen en wijzigen zonder dat de onderwerpen elkaar benvloeden of van elkaar afhankelijk zijn zoals in Figuur 5-16. Insert 18333fig0516.png -Figuur 5-16. Initiële commit historie met werk van featureB. +Figuur 5-16. Initile commit historie met werk van featureB. -Stel dat de project beheerder een berg andere patches binnengehaald heeft en je eerste branch geprobeerd heeft, maar dat die niet langer netjes samenvoegt. In dit geval kun je proberen die branch te rebasen op de punt van `origin/master`, de conflicten proberen op te lossen voor de beheerder, en dan je wijzigingen opnieuw aanbieden: +Stel dat de project beheerder een berg andere patches binnengehaald heeft en je eerste branch geprobeerd heeft, maar dat die niet langer netjes merged. In dat geval kun je proberen die branch te rebasen op de punt van `origin/master`, de conflicten op te lossen voor de beheerder, en dan je wijzigingen opnieuw aanbieden: $ git checkout featureA $ git rebase origin/master - $ git push –f myfork featureA + $ git push -f myfork featureA Dit herschrijft je geschiedenis zodat die eruit ziet als in Figuur 5-17. Insert 18333fig0517.png Figuur 5-17. Commit historie na werk van featureA. -Omdat je de branch gerebased hebt, moet je de `-f` specificeren met je push commando om in staat te zijn de `featureA` branch op de server te vervangen met een commit die er geen afstammeling van is. Een alternatief zou zijn dit nieuwe werk naar een andere branch op de server terug te zetten (misschien `featureAv2` genaamd). +Omdat je de branch gerebased hebt, moet je de `-f` specificeren met je push commando om in staat te zijn de `featureA` branch op de server te vervangen met een commit die er geen afstammeling van is. Een alternatief zou zijn dit nieuwe werk naar een andere branch op de server te pushen (misschien `featureAv2` genaamd). -Laten we eens kijken naar nog een mogelijk scenario: de beheerder heeft je werk bekeken in je tweede branch en vind het concept goed, maar zou willen dat je een implementatie detail veranderd. Je zult deze kans ook gebruiken om het werk dat gebaseerd is van de huidige `master` branch van het project af te halen. Je begint een nieuwe branch gebaseerd op de huidige `origin/master` branch, perst de `featureB` wijzigingen hier samen, lost conflicten op, doet de implementatie wijziging, en zet dat terug als een nieuwe branch: +Laten we eens kijken naar nog een mogelijk scenario: de beheerder heeft je werk bekeken in je tweede branch en vind het concept goed, maar zou willen dat je een implementatie detail verandert. Je zult deze gelegenheid ook gebruiken om het werk te baeren op de huidige `master` branch van het project. Je begint een nieuwe branch gebaseerd op de huidige `origin/master` branch, squashed de `featureB` wijzigingen er naartoe, lost conflicten op, doet de implementatie wijziging, en zet dat terug als een nieuwe branch: $ git checkout -b featureBv2 origin/master $ git merge --no-commit --squash featureB @@ -464,18 +465,18 @@ Laten we eens kijken naar nog een mogelijk scenario: de beheerder heeft je werk $ git commit $ git push myfork featureBv2 -De `--squash` optie pakt al het werk op de samengevoegde branch en perst dat samen in één non-merge commit bovenop de branch waar je op zit. De `--no-commit` optie verteld Git dat hij niet automatisch een commit moet vastleggen. Dit staat je toe om alle wijzigingen van een andere branch te introduceren en dan meer wijzigingen te doen, alvorens de commit vast te leggen. +De `--squash` optie pakt al het werk op de gemergde branch en perst dat samen in n non-merge commit bovenop de branch waar je op zit. De `--no-commit` optie vertelt Git dat hij niet automatisch een commit moet doen. Dit stelt je in staat om alle wijzigingen van een andere branch te introduceren en dan meer wijzigingen te doen, alvorens de nieuwe commit te doen. Nu kun je de beheerder een bericht sturen dat je de gevraagde wijzigingen gemaakt hebt en dat ze die wijzigingen kunnen vinden in je `featureBv2` branch (zie Figuur 5-18). Insert 18333fig0518.png Figuur 5-18. Commit historie na het featureBv2 werk. -### Publiek groot project ### +### Openbaar groot project ### -Veel grote projecten hebben procedures voor het accepteren van patches vastgelegd – je zult de specifieke regels voor ieder project moeten bekijken, omdat ze zullen verschillen. Maar, veel grote projecten accepteren patches via ontwikkelaar maillijsten, dus ik zal zo'n voorbeeld nu laten zien. +Veel grote projecten hebben vastgestelde procedures voor het accepteren van patches - je zult de specifieke regels voor ieder project goed moeten bekijken, omdat ze zullen verschillen. Maar, veel grote projecten accepteren patches via ontwikkelaar maillijsten, dus ik zal zo'n voorbeeld nu laten zien. -De werkwijze is vergelijkbaar met het vorige geval – je maakt onderwerp branches voor iedere patch waar je aan werkt. Het verschil is hoe je die indient bij het project. In plaats van het project te forken en naar je eigen schrijfbare versie terug te zetten, genereer je e-mail versies van iedere commit serie en e-mailt die naar de ontwikkelaar maillijst: +De werkwijze is vergelijkbaar met het vorige geval - je maakt topic branches voor iedere patch waar je aan werkt. Het verschil is hoe je die aanlevert bij het project. In plaats van het project te forken en naar je eigen schrijfbare versie te pushen, genereer je e-mail versies van iedere commit serie en mailt die naar de ontwikkelaar maillijst: $ git checkout -b topicA $ (work) @@ -483,13 +484,13 @@ De werkwijze is vergelijkbaar met het vorige geval – je maakt onderwerp branch $ (work) $ git commit -Nu heb je twee commits die je wil sturen naar de maillijst. Je gebruikt `git format-patch` om de mbox-geformatteerde bestanden te genereren, die je kunt e-mailen naar de lijst – het vormt ieder commit om naar een e-mail bericht met de eerste regel van het commit bericht als de onderwerp regel, en de rest van het bericht plus de patch die de commit introduceert als de inhoud. Het fijne hieraan is dat het toepassen van een patch uit een e-mail die gegenereerd is met `format-patch` alle commit informatie goed behoudt, zoals je in het volgende gedeelte meer zult zien als je deze commits toepast: +Nu heb je twee commits die je wil sturen naar de maillijst. Je gebruikt `git format-patch` om de mbox-geformatteerde bestanden te genereren, die je kunt e-mailen naar de lijst. Dit vormt iedere commit om naar een e-mail bericht met de eerste regel van het commit bericht als de onderwerp regel, en de rest van het bericht plus de patch die door de commit wordt gentroduceerd als de inhoud. Het prettige hieraan is dat het toepassen van een patch uit een mail die gegenereerd is met `format-patch` alle commit informatie goed behoudt, zoals je in de volgende paragraaf meer zult zien als je deze commits toepast: $ git format-patch -M origin/master 0001-add-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch -Het `format-patch` commando voert de namen uit van de patch bestanden die het maakt. De `-M` optie verteld Git te kijken naar hernoemingen. De bestanden komen er uiteindelijk zo uit te zien: +Het `format-patch` commando drukt de namen af van de patch bestanden die het maakt. De `-M` optie vertelt Git te kijken naar hernoemingen. De bestanden komen er uiteindelijk zo uit te zien: $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 @@ -519,11 +520,11 @@ 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 verschijnen. 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. +Om dit te mailen naar een maillijst, kun je het bestand in je mail applicatie plakken of het sturen via een commandoregel programma. Het plakken van de tekst veroorzaakt vaak formaterings problemen, in het bijzonder bij "slimmere" clients die geen newlines en andere witruimte juist behouden. Gelukkig levert Git een gereedschap die je helpt om juist geformatteerde patches via IMAP te versturen, wat makkelijker voor je kan zijn. Ik zal zal je laten zien hoe je een patch via Gmail stuurt, wat de 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. -Eerst moet je de imap sectie in je `~/.gitconfig` bestand instellen. Je kunt iedere waarde apart instellen met een serie `git config` commando's, of je kunt ze handmatig toevoegen; maar aan het einde moet je config bestand er ongeveer zo uitzien: +Eerst moet je de imap sectie in je `~/.gitconfig` bestand instellen. Je kunt iedere waarde apart instellen met een serie `git config` commando's, of je kunt ze handmatig toevoegen; maar op het eind moet je config bestand er ongeveer zo uitzien: [imap] folder = "[Gmail]/Drafts" @@ -534,7 +535,26 @@ Eerst moet je de imap sectie in je `~/.gitconfig` bestand instellen. Je kunt ied sslverify = false Als je IMAP server geen SSL gebruikt, zijn de laatste twee regels waarschijnlijk niet nodig, en de waarde voor host zal `imap://` zijn in plaats van `imaps://`. -Als dat ingesteld is, kun je `git send-email` gebruiken om de patch serie in de Drafts map van de gespecificeerde IMAP server te zetten: +Als dat ingesteld is, kun je `git send-email` gebruiken om de patch reeks in de Drafts map van de gespecificeerde IMAP server te zetten: + + $ cat *.patch |git imap-send + Resolving imap.gmail.com... ok + Connecting to [74.125.142.109]:993... ok + Logging in... + sending 2 messages + 100% (2/2) done + +Nu kan je naar je Drafts folder gaan, het To veld te wijzigen naar de maillijst waar je de patch naartoe stuurt en mogelijk de beheerder of verantwoordelijke voor dat deel in de CC zetten en dan versturen. + +Je kunt de patches ook via een SMTP server sturen. Zoals eerder kan je elke waarde apart instellen met een serie `git config` commando's, of je kunt ze handmatig in de sendmail sectie in je `~/.gitconfig` bestand zetten: + + [sendemail] + smtpencryption = tls + smtpserver = smtp.gmail.com + smtpuser = user@gmail.com + smtpserverport = 587 + +Als dit gebeurt is, kan je `git send-email` gebruiken om je patches te sturen: $ git send-email *.patch 0001-added-limit-to-log-function.patch @@ -544,7 +564,7 @@ Als dat ingesteld is, kun je `git send-email` gebruiken om de patch serie in de Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y -Dan spuugt Git een berg log informatie uit, die er zoiets als dit uitziet, voor iedere patch die je stuurt: +Dan spuuwt Git een bergje log-informatie uit voor iedere patch die je stuurt, en dat ziet er ongeveer zo uit: (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' @@ -561,19 +581,17 @@ Dan spuugt Git een berg log informatie uit, die er zoiets als dit uitziet, voor Result: OK -Op dit punt zou je in staat moeten zijn om naar je Drafts map te gaan, het To veld te wijzigen in de maillijst waarnaar je de patch stuurt, misschien de beheerder of verantwoordelijke persoon voor dat gebied op de CC te zetten, en het weg te sturen. - ### Samenvatting ### -Dit gedeelte heeft een aantal vaak voorkomende werkwijzen behandeld, om om te gaan met een aantal zeer verschillende typen Git projecten die je waarschijnlijk zult tegen komen en een aantal nieuwe programma's geïntroduceerd, die je helpen om dit proces te beheren. Vervolgens zul je zien hoe je aan de andere kant van de medaille werkt: een Git project beheren. Je zult leren hoe een welwillende dictator of integratie manager te zijn. +In dit hoofdstuk is een aantal veel voorkomende werkwijzen behandeld, die je kunt gebruiken om te kunnen werken in een aantal zeer verschillende typen Git projecten die je misschien zult tegenkomen en een aantal nieuwe gereedschappen gentroduceerd, die je helpen om dit proces te beheren. Wat hierna volgt zal je laten zien hoe je aan de andere kant van de medaille werkt: een Git project beheren. Je zult leren hoe een welwillende dictator of integratie manager te zijn. -## Projectonderhoud ## +## Het beheren van een project ## -Naast weten hoe effectief bij te dragen aan een project, moet je waarschijnlijk ook weten hoe je deze onderhoud. Dit kan bestaan uit het accepteren en toepassen van patches gegenereerd via 'format-patch' die naar jou gemaild zijn, of het integreren van veranderingen in de remote branches voor repositories die je hebt toegevoegd als remotes aan je project. Of je nu een canonieke repository onderhoud, of wilt bijdragen door het controleren of goedkeuren van patches, je moet weten hoe werk te aanvaarden op een manier die het duidelijkst is voor andere medewerkers en duurzaam door jou op de lange termijn. +Naast weten hoe effectief bij te dragen aan een project, moet je waarschijnlijk ook moeten weten hoe je er een beheert. Dit kan bestaan uit het accepteren en toepassen van patches die met `format-patch` gemaakt en naar je gemaild zijn, of het integreren van wijzigingen in de remote branches van repositories die je hebt toegevoegd als remotes van je project. Of je nu een canonieke repository beheert, of wilt bijdragen door het controleren of goedkeuren van patches, je moet weten hoe werk te ontvangen op een dusdanige manier die het duidelijkst is voor andere bijdragers en voor jou op langere termijn vol te houden. -### Werken in onderwerp branches ### +### Werken in topic branches ### -Als je overweegt om nieuw werk te integreren, is het normaliter een goed idee om het uit te proberen in een onderwerp branch – een tijdelijke branch, speciaal gemaakt om dat nieuwe werk te proberen. Op deze manier is het handig om een patch individueel af te stemmen en het weg te laten als het niet werkt, totdat je tijd hebt om er op terug te komen. Als je een eenvoudige branchnaam maakt, gebaseerd op het thema van het werk dat je gaat proberen, bijvoorbeeld `ruby_client` of zoiets beschrijvends, dan kun je het makkelijk onthouden als je het voor een tijdje moet achterlaten en er later op terug moet komen. De beheerder van het Git project heeft de neiging om deze branches ook van een naamruimte te voorzien – zoals `sc/ruby_client`, waarbij `sc` een afkorting is van de persoon die het werk heeft bijgedragen. +Als je overweegt om nieuw werk te integreren, is het over het algemeen een goed idee om het uit te proberen in een topic branch - een tijdelijke branch, speciaal gemaakt om dat nieuwe werk uit te proberen. Op deze manier is het handig om een patch individueel te behandelen en het even opzij te zetten als het niet werkt, totdat je tijd hebt om er op terug te komen. Als je een eenvoudige branchnaam maakt, gebaseerd op het onderwerp van het werk dat je aan het proberen bent, bijvoorbeeld `ruby_client` of zoiets beschrijvends, dan is het makkelijk om te herinneren als je het voor een tijdje moet achterlaten en er later op terug komt. De beheerder van het Git project heeft de neiging om deze branches ook van een naamsruimte (namespace) te voorzien - zoals `sc/ruby_client`, waarbij `sc` een afkorting is van de persoon die het werk heeft bijgedragen. Zoals je je zult herinneren, kun je de branch gebaseerd op je master branch zo maken: $ git branch sc/ruby_client master @@ -582,11 +600,11 @@ Of, als je er ook meteen naar wilt omschakelen, kun je de `checkout -b` optie ge $ git checkout -b sc/ruby_client master -Nu ben je klaar om je bijgedragen werk in deze onderwerp branch toe te voegen, en te bepalen of je het wilt samenvoegen in je lange termijn branches. +Nu ben je klaar om het bijgedragen werk in deze topic branch toe te voegen, en te bepalen of je het wilt mergen in je meer permanente branches. ### Patches uit e-mail toepassen ### -Als je een patch per e-mail ontvangt, die je moet integreren in je project, moet je de patch in je onderwerp branch toepassen om het te evalueren. Er zijn twee manieren om een ge-emailde patch toe te passen: met `git apply` of met `git am`. +Als je een patch per e-mail ontvangt, die je moet integreren in je project, moet je de patch in je onderwerp branch toepassen om het te evalueren. Er zijn twee manieren om een ge-mailde patch toe te passen: met `git apply` of met `git am`. #### Een patch toepassen met apply #### @@ -594,21 +612,21 @@ Als je de patch ontvangen hebt van iemand die het gegenereerd heeft met de `git $ git apply /tmp/patch-ruby-client.patch -Dit wijzigt de bestanden in je werkmap. Het is vrijwel gelijk aan het uitvoeren van een `patch -p1` commando om de patch toe te passen, alhoewel het meer paranoïde is en minder wazige paren dan patch. Het handelt ook bestandstoevoegingen af, verwijderingen, en hernoemingen als ze beschreven staan in het `git diff` formaat, wat `patch` niet doet. Als laatste is `git apply` een "pas alles toe of laat alles weg" model, waarbij alles of niets wordt toegepast, waarbij `patch` gedeeltelijke patches kan toepassen, zodat je werkmap in een vreemde status achterblijft. `git apply` is over het algemeen meer paranoïde dan `patch`. Het zal geen commit voor je aanmaken – na het uitgevoerd te hebben, moet je de geïntroduceerde wijzigingen handmatig stagen en committen. +Dit wijzigt de bestanden in je werk directory. Het is vrijwel gelijk aan het uitvoeren van een `patch -p1` commando om de patch toe te passen, alhoewel het meer paranode is en minder fuzzy matches accepteert dan patch. Het handelt ook bestandstoevoegingen af, -verwijderingen, en hernoemingen als ze beschreven staan in het `git diff` formaat, wat `patch` niet doet. Als laatste volgt `git apply` een "pas alles toe of laat alles weg" model, waarbij alles of niets wordt toegepast, en `patch` gedeeltelijke patches kan toepassen, waardoor je werk directory in een vreemde status achterblijft. `git apply` is over het algemeen meer paranode dan `patch`. Het zal geen commit voor je aanmaken - na het uitgevoerd te zijn, je moet de gentroduceerde wijzigingen handmatig stagen en committen. -Je kunt ook git apply gebruiken om te zien of een patch netjes toepast, voordat je het echt toepast – je kunt `git apply --check` uitvoeren met de patch: +Je kunt ook git apply gebruiken om te zien of een patch netjes wordt toepast voordat je het echt toepast - je kunt `git apply --check` uitvoeren met de 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 -Als er geen uitvoer is, dan zou de patch netjes toe moeten passen. Dit commando eindigt ook met een status niet gelijk aan nul als de controle faalt, zodat je het kunt gebruiken in scripts als je dat wilt. +Als er geen uitvoer is, dan zou de patch netjes moeten passen. Dit commando eindigt ook met een niet-nul status als de controle faalt, zodat je het kunt gebruiken in scripts als je dat wilt. #### Een patch met am toepassen #### -Als de bijdrager een Git gebruiker is en zo goed was om het `format-patch` commando te gebruiken om hun patch te genereren, dan is je werk eenvoudiger omdat de patch auteur informatie en een commit bericht voor je bevat. Als je kunt, moedig je bijdragers aan om `format-patch` te gebruiken in plaats van `diff` om patches te genereren voor je. Je zou alleen `git apply` hoeven te gebruiken voor oude patches en dat soort dingen. +Als de bijdrager een Git gebruiker is en zo vriendelijk was om het `format-patch` commando te gebruiken om hun patch te genereren, dan is je werk eenvoudiger omdat de patch de auteur informatie en een commit bericht voor je bevat. Als je kunt, moedig je bijdragers aan om `format-patch` te gebruiken in plaats van `diff` om patches te genereren voor je. Je zou alleen `git apply` hoeven te gebruiken voor oude patches en dat soort dingen. -Om een patch gegenereerd met `format-patch` toe te passen, gebruik je `git am`. Technisch is `git am` gemaakt om een mbox bestand te lezen, dat een eenvoudig gewone tekst formaat of is om één of meer e-mail berichten in een tekst bestand op te slaan. Het ziet er zoiets als dit uit: +Om een patch gegenereerd met `format-patch` toe te passen, gebruik je `git am`. Technisch is `git am` gemaakt om een mbox bestand te lezen, dat een eenvoudig gewone platte tekstformaat is om n of meer e-mail berichten in een tekst bestand op te slaan. Het ziet er ongeveer zo uit: From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith @@ -617,14 +635,14 @@ Om een patch gegenereerd met `format-patch` toe te passen, gebruik je `git am`. Limit log functionality to the first 20 -Dit is het begin van de uitvoer van het format-patch commando dat je gezien hebt in het vorige gedeelte. Dit is ook een geldig mbox e-mail formaat. Als iemand jou de patch goed gemaild heeft door gebruik te maken van git send-email, en je download dat in een mbox formaat, dan kun je git am naar dat mbox bestand wijzen, en het zal beginnen met alle patches die het ziet toe te passen. Als je een mail client uitvoert die meerdere e-mails kan opslaan in mbox formaat, dan kun je hele patch series in een bestand opslaan en dan git am gebruiken om ze stuk voor stuk toe te passen. +Dit is het begin van de uitvoer van het format-patch commando dat je gezien hebt in de vorige paragraaf. Dit is ook een geldig mbox e-mail formaat. Als iemand jou de patch correct gemaild heeft door gebruik te maken van git send-email en je downloadt dat in een mbox formaat, dan kan je het git am naar dat mbox bestand verwijzen, en het zal beginnen met alle patches die het ziet toe te passen. Als je een mail client gebruikt die meerdere e-mails kan opslaan in mbox formaat, dan kun je hele patch series in een bestand opslaan en dan git am gebruiken om ze een voor een toe te passen. -Maar, als iemand een patch bestand heeft ge-upload die gegenereerd is met `format-patch` naar een ticket systeem of zoiets, kun je het bestand lokaal opslaan en dan dat bestand dat bewaard is op je schijf aan `git am` geven om het toe te passen: +Maar, als iemand een patch bestand heeft ge-upload die gegenereerd is met `format-patch` naar een ticket systeem of zoiets, kun je het bestand lokaal opslaan en dan dat opgeslagen bestand aan `git am` doorgeven om het toe te passen: $ git am 0001-limit-log-function.patch Applying: add limit to log function -Je kunt zien dat het netjes is toegepast, en automatisch een nieuwe commit voor je heeft aangemaakt. De auteur informatie wordt gehaald uit het `From` en `Date` veld in de kop, en het bericht van de commit wordt gehaald uit de `Subject` en inhoud (voor de patch van de e-mail. Bijvoorbeeld, als deze patch was toegepast van het mbox voorbeeld dat ik zojuist getoond heb, dan zou de gegenereerde commit er ongeveer zo uit zien: +Je kunt zien dat het netjes is toegepast, en automatisch een nieuwe commit voor je heeft aangemaakt. De auteursinformatie wordt gehaald uit de `From` en `Date` velden in de kop, en het bericht van de commit wordt gehaald uit de `Subject` en inhoud (voor de patch) van het mail bericht. Bijvoorbeeld, als deze patch was toegepast van het mbox voorbeeld dat ik zojuist getoond heb, dan zou de gegenereerde commit er ongeveer zo uit zien: $ git log --pretty=fuller -1 commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 @@ -637,9 +655,9 @@ Je kunt zien dat het netjes is toegepast, en automatisch een nieuwe commit voor Limit log functionality to the first 20 -De `Commit` informatie laat de persoon die de patch toepaste en de tijd waarop het was toegepast zien. De `Author` informatie is het individueel die de patch origineel gemaakt heeft en wanneer het origineel gemaakt is. +De `Commit` informatie laat de persoon die de patch toepaste en de tijd waarop het is toegepast zien. De `Author` informatie het individu die de patch oorspronkelijk gemaakt heeft en wanneer het gemaakt is. -Maar, het is mogelijk dat de patch niet netjes toepast. Misschien is je hoofdbranch te ver afgeweken van de branch waarop de patch gebouwd is, of hangt de patch van een andere patch af, die je nog niet hebt toegepast. In dat geval zal het `git am` proces falen en je vragen wat je wilt doen: +Maar het is mogelijk dat de patch niet netjes toegepast kan worden. Misschien is je hoofdbranch te ver afgeweken van de branch waarop de patch gebouwd is, of is de patch van een andere patch, die je nog niet hebt toegepast, afhankelijk. In dat geval zal het `git am` proces falen en je vragen wat je wilt doen: $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem @@ -650,14 +668,14 @@ Maar, het is mogelijk dat de patch niet netjes toepast. Misschien is je hoofdbra 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". -Dit commando stopt conflict markeringen in alle bestanden waar het problemen mee heeft, net zoals een conflicterende samenvoeging of rebase operatie. Je lost dit probleem in een vergelijkbare manier op – wijzig het bestand om het conflict op te lossen, stage het bestand, en voer dan `git am --resolved` uit om door te gaan met de volgende patch: +Dit commando stopt conflict markeringen in alle bestanden waar het problemen mee heeft, net zoals een conflicterende merge of rebase operatie. Je lost dit probleem op een vergelijkbare manier op - wijzig het bestand om het conflict op te lossen, stage het bestand, en voer dan `git am --resolved` uit om door te gaan met de volgende patch: $ (fix the file) $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem -Als je wil dat Git een beetje meer intelligent probeert om het conflict op te lossen, kun je een `-3` optie eraan meegeven, wat zorgt dat Git een drieweg samenvoeging probeert. Deze optie staat standaard niet aan, omdat het niet werkt als de commit waarvan de patch zegt dat het op gebaseerd is niet in je repository zit. Als je die commit wel hebt – als de patch gebaseerd was op een publieke commit – dan is de `-3` over het algemeen veel slimmer in het toepassen van een conflicterende patch: +Als je wil dat Git een beetje meer intelligentie toepast om het conflict op te lossen, kun je een `-3` optie eraan meegeven, wat ervoor zorgt dat Git een driewegs-merge probeert. Deze optie staat standaard niet aan, omdat het niet werkt als de commit waarvan de patch zegt dat het op gebaseerd is niet in je repository zit. Als je die commit wel hebt - als de patch gebaseerd was op een publieke commit - dan is de `-3` over het algemeen veel slimmer in het toepassen van een conflicterende patch: $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem @@ -667,7 +685,7 @@ Als je wil dat Git een beetje meer intelligent probeert om het conflict op te lo Falling back to patching base and 3-way merge... No changes -- Patch already applied. -In dit geval, probeerde ik een patch toe te passen die ik reeds toegepast had. Zonder de `-3` optie ziet het eruit als een conflict. +In dit geval, probeerde ik een patch toe te passen die ik al eerder toegepast had. Zonder de `-3` optie ziet het eruit als een conflict. Als je een aantal patches van een mbox toepast, kun je ook het `am` commando in een interactieve modus uitvoeren, wat bij iedere patch die het vind stopt en je vraagt of je het wilt toepassen: @@ -678,36 +696,36 @@ Als je een aantal patches van een mbox toepast, kun je ook het `am` commando in -------------------------- Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all -Dit is fijn als je een aantal patches bewaard hebt, omdat je de patch eerst kunt zien als je je niet kunt herinneren wat het is, of de patch niet wilt toepassen als je het al gedaan hebt. +Dit is prettig als je een aantal patches bewaard hebt, omdat je de patch eerst kunt zien als je je niet kunt herinneren wat het is, of de patch niet wilt toepassen als je dat al gedaan hebt. -Als alle patches voor je onderwerp branch zijn toegepast en gecommit zijn op je branch, kun je kiezen of en hoe ze te integreren in een langer lopende branch. +Als alle patches voor je topic branch zijn toegepast en gecommit zijn op je branch, kun je kiezen of en hoe ze te integreren in een branch met een langere looptijd. -### Remote branches bekijken ### +### Remote branches uitchecken ### -Als je bijdrage van een Git gebruiker komt, die zijn eigen repository ingesteld heeft, een aantal patches daarin teruggezet heeft, en jou de URL naar de repository gestuurd heeft en de naam van de remote branch waarin de wijzigingen zitten, dan kun je ze toevoegen als een remote en de samenvoegingen lokaal doen. +Als je bijdrage van een Git gebruiker komt, die zijn eigen repository opgezet heeft, een aantal patches daarin gepushed heeft, en jou de URL naar de repository gestuurd heeft en de naam van de remote branch waarin de wijzigingen zitten, kan je ze toevoegen als een remote en het mergen lokaal doen. -Bijvoorbeeld, als Jessica je een e-mail stuurt waarin staat dat ze een mooie nieuw eigenschap in de `ruby-client` branch van haar repository heeft, kun je het testen door de remote toe te voegen en die branch lokaal te bekijken: +Bijvoorbeeld, als Jessica je een e-mail stuurt waarin staat dat ze een mooie nieuw feature in de `ruby-client` branch van haar repository heeft, kun je het testen door de remote toe te voegen en die branch lokaal te bekijken: $ git remote add jessica git://github.com/jessica/myproject.git $ git fetch jessica $ git checkout -b rubyclient jessica/ruby-client -Als ze je later opnieuw e-mailt met een andere branch die een andere mooie eigenschap bevat, dan kun je die ophalen en bekijken omdat je de remote al ingesteld hebt. +Als ze je later opnieuw e-mailt met een andere branch die een andere mooie feature bevat, dan kun je die ophalen en bekijken omdat je de remote al ingesteld hebt. -Dit is erg handig als je consistent met een persoon werkt. Als iemand een enkele patch eens in de zoveel tijd bij te dragen heeft, dan is het accepteren per e-mail misschien minder tijdrovend dan eisen dat iedereen hun eigen server moet draaien en doorlopend remotes toevoegen en verwijderen om een paar patches te krijgen. Je zult waarschijnlijk ook honderden remotes hebben, elk voor iemand die maar een patch of twee bijdraagt. Maar, scripts en gehoste diensten maken dit misschien makkelijker – het hangt veel af van hoe jij ontwikkeld en hoe je bijdragers ontwikkelen. +Dit is meest nuttig als je vaak met een persoon werkt. Als iemand een enkele patch eens in de zoveel tijd bij te dragen heeft, dan is het accepteren per e-mail misschien minder tijdrovend dan eisen dat iedereen hun eigen server moet draaien en doorlopend remotes toevoegen en verwijderen om een paar patches te krijgen. Je zult waarschijnlijk ook niet honderden remotes willen hebben, elk voor iemand die maar een patch of twee bijdraagt. Aan de andere kant, scripts en gehoste diensten maken dit misschien makkelijker - het hangt veel af van hoe jij ontwikkelt en hoe je bijdragers ontwikkelen. -Het andere voordeel van deze aanpak is dat je de historie van de commits ook krijgt. Alhoewel je misschien geldige samenvoeg problemen hebt, weet je waar in je historie hun werk is gebaseerd; een goede drieweg samenvoeging is de standaard in plaats van een `-3` te moeten meegeven en hopen dat de patch gegenereerd was van een publieke commit waar je toegang toe hebt. +Het andere voordeel van deze aanpak is dat je de historie van de commits ook krijgt. Alhoewel je misschien terechte merge problemen hebt, weet je op welk punt in de historie hun werk is gebaseerd; een echte drieweg merge is de standaard in plaats van een `-3` te moeten meegeven en hopen dat de patch gegenereerd was van een publieke commit waar je toegang toe hebt. -Als je niet consistent met een persoon werkt, maar toch op deze manier van hen wilt ophalen, dan kun je de URL van het remote repository geven aan het `git pull` commando. Dit haalt eenmalig op en bewaart de URL niet als een remote referentie: +Als je maar af en toe met een persoon werkt, maar toch op deze manier van hen wilt pullen, dan kun je de URL van de remote repository geven aan het `git pull` commando. Dit haalt eenmalig op en bewaart de URL niet als een remote referentie: $ git pull git://github.com/onetimeguy/project.git From git://github.com/onetimeguy/project * branch HEAD -> FETCH_HEAD Merge made by recursive. -### Bepalen wat geïntroduceerd wordt ### +### Bepalen wat gentroduceerd wordt ### -Nu heb je een onderwerp branch dat bijgedragen werk bevat. Op dit punt kun je bepalen wat je er mee wilt doen. Deze sectie bezoekt een paar commando's opnieuw zodat je kunt zien hoe je ze kunt gebruiken om precies te reviewen wat je zult introduceren als je dit samenvoegt in je hoofd branch. +Je hebt een topic branch dat bijgedragen werk bevat. Nu kan je bepalen wat je er mee wilt doen. Deze paragraaf bekijkt een paar commando's opnieuw om te laten zien hoe je ze kunt gebruiken om precies te reviewen wat je zult introduceren als je dit merged in je hoofd branch. Het is vaak behulpzaam om een review te krijgen van alle commits die in deze branch zitten, maar die niet in je master branch zitten. Je kunt commits weglaten in de master branch door de `--not` optie mee te geven voor de branch naam. Bijvoorbeeld, als je bijdrager je twee patches stuurt en je wil een branch genaamd `contrib` maken en die patches daar toepassen, dan kun je dit uitvoeren: @@ -724,7 +742,7 @@ Het is vaak behulpzaam om een review te krijgen van alle commits die in deze bra updated the gemspec to hopefully work better -Om te zien welke wijzigingen iedere commit introduceert, onthoud dan dat je de `-p` optie kunt meegeven aan `git log` en dan zal het de diff geïntroduceerd bij iedere commit weergeven. +Om te zien welke wijzigingen iedere commit introduceert, onthoud dan dat je de `-p` optie kunt meegeven aan `git log` en dan zal het de diff gentroduceerd bij iedere commit weergeven. Om een volledige diff te zien van wat zou gebeuren als je deze onderwerp branch samenvoegt met een andere branch, zul je misschien een vreemde truc moeten toepassen om de juiste resultaten te krijgen. Je zult misschien denken om dit uit te voeren: @@ -734,7 +752,7 @@ Dit commando geeft je een diff, maar het zou misleidend kunnen zijn. Als je `mas Als `master` een directe afstammeling is van je onderwerp branch, is dit geen probleem; maar als de twee histories uit elkaar zijn gegaan, zal de diff eruit zien alsof je alle nieuwe spullen in je onderwerp branch toevoegt en al het unieke weghaalt in de `master` branch. -Wat je echt wil zien zijn de wijzigingen die in de onderwerp branch zijn toegevoegd – het werk dat je zult introduceren als je deze branch met master samenvoegt. Je doet dat door Git de laatste commit op je onderwerp branch te laten vergelijken met de eerste gezamenlijke voorouder die het heeft met de master branch. +Wat je echt wil zien zijn de wijzigingen die in de onderwerp branch zijn toegevoegd - het werk dat je zult introduceren als je deze branch met master samenvoegt. Je doet dat door Git de laatste commit op je onderwerp branch te laten vergelijken met de eerste gezamenlijke voorouder die het heeft met de master branch. Technisch, kun je dat doen door de gezamenlijke voorouder expliciet uit te zoeken en dan daar je diff op uit te voeren: @@ -746,11 +764,11 @@ Maar, dat is niet handig, dus levert Git een andere korte manier om hetzelfde te $ git diff master...contrib -Dit commando toont je alleen het werk dat je huidige onderwerp branch heeft geïntroduceerd sinds zijn gezamenlijke voorouder met master. Dat is een erg handige syntax om te onthouden. +Dit commando toont je alleen het werk dat je huidige onderwerp branch heeft gentroduceerd sinds zijn gezamenlijke voorouder met master. Dat is een erg handige syntax om te onthouden. ### Bijgedragen werk integreren ### -Als al het werk in je onderwerp branch klaar is om te worden geïntegreerd in een meer hoofdlijn branch, dan is de vraag hoe het te doen. En daarna, welke algemene werkwijze wil je gebruiken om je project te onderhouden? Je hebt een aantal keuzes, dus ik zal er een paar behandelen. +Als al het werk in je onderwerp branch klaar is om te worden gentegreerd in een meer hoofdlijn branch, dan is de vraag hoe het te doen. En daarna, welke algemene werkwijze wil je gebruiken om je project te onderhouden? Je hebt een aantal keuzes, dus ik zal er een paar behandelen. #### Samenvoeg werkwijzen #### @@ -764,7 +782,7 @@ Figuur 5-20. Na het samenvoegen van een onderwerp branch. Dat is waarschijnlijk de eenvoudigste werkwijze, maar het is problematisch als je werkt met grotere repositories of projecten. -Als je meer ontwikkelaars hebt, of een groter project, dan zul je waarschijnlijk een minstens twee fasen samenvoeg cyclus willen gebruiken. In dit scenario, heb je twee langlopende branches, `master` en `develop`, waarin je bepaald dat `master` alleen vernieuwd wordt als een zeer stabiele vrijgave gedaan wordt en alle nieuwe code geïntegreerd is in de `develop` branch. Je zet beide branches regelmatig terug naar het publieke repository. Iedere keer als je een nieuw onderwerp branch hebt om samen te voegen (Figuur 5-21), voeg je het in `develop` (Figuur 5-22); daarna, als je een tag maakt van een vrijgave, dan doe je een fast-forward van `master` naar waar de nu stabiele `develop` branch is (Figuur 5-23). +Als je meer ontwikkelaars hebt, of een groter project, dan zul je waarschijnlijk een minstens twee fasen samenvoeg cyclus willen gebruiken. In dit scenario, heb je twee langlopende branches, `master` en `develop`, waarin je bepaald dat `master` alleen vernieuwd wordt als een zeer stabiele vrijgave gedaan wordt en alle nieuwe code gentegreerd is in de `develop` branch. Je zet beide branches regelmatig terug naar het publieke repository. Iedere keer als je een nieuw onderwerp branch hebt om samen te voegen (Figuur 5-21), voeg je het in `develop` (Figuur 5-22); daarna, als je een tag maakt van een vrijgave, dan doe je een fast-forward van `master` naar waar de nu stabiele `develop` branch is (Figuur 5-23). Insert 18333fig0521.png Figuur 5-21. Voor een samenvoeging van een onderwerp branch. @@ -780,7 +798,7 @@ Je kunt dit concept ook doortrekken, waarbij je een integratie branch hebt waar #### Werkwijzen met grote samenvoegingen #### -Het Git project heeft vier langlopende branches: `master`, `next`, en `pu` (proposed updates, voorgestelde vernieuwingen), en `maint` voor onderhoudswerk. Als nieuw werk wordt geïntroduceerd door bijdragers, wordt het samengeraapt in onderwerp branches in het repository van de beheerder op een manier gelijk aan wat ik omschreven heb (zie Figuur 5-24). Op dit punt, worden de onderwerpen geëvalueerd om te bepalen of ze veilig zijn en klaar voor consumptie of dat ze nog wat werk nodig hebben. Als ze veilig zijn, worden ze in `next` samengevoegd, en wordt die branch teruggezet zodat iedereen de onderwerpen geïntegreerd kan proberen. +Het Git project heeft vier langlopende branches: `master`, `next`, en `pu` (proposed updates, voorgestelde vernieuwingen), en `maint` voor onderhoudswerk. Als nieuw werk wordt gentroduceerd door bijdragers, wordt het samengeraapt in onderwerp branches in het repository van de beheerder op een manier gelijk aan wat ik omschreven heb (zie Figuur 5-24). Op dit punt, worden de onderwerpen gevalueerd om te bepalen of ze veilig zijn en klaar voor consumptie of dat ze nog wat werk nodig hebben. Als ze veilig zijn, worden ze in `next` samengevoegd, en wordt die branch teruggezet zodat iedereen de onderwerpen gentegreerd kan proberen. Insert 18333fig0524.png Figuur 5-24. Een complexe serie van parallelle bijgedragen onderwerp branches beheren. @@ -796,7 +814,7 @@ Als een onderwerp branch uiteindelijk is samengevoegd in `master`, dan wordt het Andere beheerders geven de voorkeur aan rebasen of bijgedragen werk te cherry picken bovenop hun master branch, in plaats van het er in samen te voegen, om een lineaire historie te behouden. Als je werk in een onderwerp branch hebt en hebt besloten dat je het wil integreren, dan ga je naar die branch en voert het rebase commando uit om de wijzigingen bovenop je huidige master branch te bouwen (of `develop`, enzovoorts). Als dat goed werkt, dan kun je je `master` branch fast-forwarden, en dan eindig je met een lineaire project historie. -De andere manier om geïntroduceerd werk van de ene naar de andere branch te verplaatsen is om het te cherry picken. Een cherry-pick in Git is een soort rebase voor een enkele commit. Het pakt de patch die was geïntroduceerd in een commit en probeert die opnieuw toe te passen op de branch waar je nu op zit. Dit is handig als je een aantal commits op een onderwerp branch hebt en je er slechts één van wilt integreren, of als je alleen één commit op een onderwerp branch hebt en er de voorkeur aan geeft om het te cherry-picken in plaats van rebase uit te voeren. Bijvoorbeeld, stel dat je een project hebt dat eruit ziet als Figuur 5-26. +De andere manier om gentroduceerd werk van de ene naar de andere branch te verplaatsen is om het te cherry picken. Een cherry-pick in Git is een soort rebase voor een enkele commit. Het pakt de patch die was gentroduceerd in een commit en probeert die opnieuw toe te passen op de branch waar je nu op zit. Dit is handig als je een aantal commits op een onderwerp branch hebt en je er slechts n van wilt integreren, of als je alleen n commit op een onderwerp branch hebt en er de voorkeur aan geeft om het te cherry-picken in plaats van rebase uit te voeren. Bijvoorbeeld, stel dat je een project hebt dat eruit ziet als Figuur 5-26. Insert 18333fig0526.png Figuur 5-26. Voorbeeld historie voor een cherry pick. @@ -808,7 +826,7 @@ Als je commit `e43a6` in je master branch wil halen, dan kun je dit uitvoeren [master]: created a0a41a9: "More friendly message when locking the index fails." 3 files changed, 17 insertions(+), 3 deletions(-) -Dit haalt dezelfde wijziging binnen als geïntroduceerd in `e43a6`, maar je krijgt een nieuwe SHA-1 waarde, omdat de gegevens op een andere manier toegepast zijn. Nu ziet je historie eruit als Figuur 5-27. +Dit haalt dezelfde wijziging binnen als gentroduceerd in `e43a6`, maar je krijgt een nieuwe SHA-1 waarde, omdat de gegevens op een andere manier toegepast zijn. Nu ziet je historie eruit als Figuur 5-27. Insert 18333fig0527.png Figuur 5-27. Historie na het cherry-picken van een commit op een onderwerp branch. @@ -842,11 +860,11 @@ Nu dat je de inhoud van je sleutel in Git hebt, kun je een tag aanmaken die dire $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92 -Als je `git push --tags` uitvoert, zal de `maintainer-pgp-pub` tag met iedereen gedeeld worden. Als iemand een tag wil verifiëren, dan kunnen ze je PGP sleutel direct importeren door de blob direct uit de gegevensbank te halen en het in GPG te importeren: +Als je `git push --tags` uitvoert, zal de `maintainer-pgp-pub` tag met iedereen gedeeld worden. Als iemand een tag wil verifiren, dan kunnen ze je PGP sleutel direct importeren door de blob direct uit de gegevensbank te halen en het in GPG te importeren: $ git show maintainer-pgp-pub | gpg --import -Ze kunnen die sleutel gebruiken om als je gesigneerde tags te verifiëren. Als je de instructies in het tag bericht zet, dan zal `git show ` je eindgebruikers meer specifieke instructies geven over tag verificatie. +Ze kunnen die sleutel gebruiken om als je gesigneerde tags te verifiren. Als je de instructies in het tag bericht zet, dan zal `git show ` je eindgebruikers meer specifieke instructies geven over tag verificatie. ### Een bouw nummer genereren ### @@ -857,7 +875,7 @@ Omdat Git geen monotone oplopende nummers heeft zoals 'v123' of iets gelijkwaard 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. +Het `git describe` commando heeft de voorkeur voor beschreven tags (tags gecreerd 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. ### Een vrijgave voorbereiden ### From 6b57e66b40545eb3f062fa8500f7ef6e7c7b1954 Mon Sep 17 00:00:00 2001 From: cor Date: Wed, 29 Jan 2014 20:43:14 +0100 Subject: [PATCH 136/690] [nl] Retranslate chapter. Reword and remove a number of Babelfishes in the text. Introduce diacritics. --- nl/05-distributed-git/01-chapter5.markdown | 188 ++++++++++----------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/nl/05-distributed-git/01-chapter5.markdown b/nl/05-distributed-git/01-chapter5.markdown index cee8e7138..d84874a81 100644 --- a/nl/05-distributed-git/01-chapter5.markdown +++ b/nl/05-distributed-git/01-chapter5.markdown @@ -386,9 +386,9 @@ Figuur 5-15. Eenvoudige volgorde in de werkwijze van dit aangestuurde team. ### Klein openbaar project ### -Het bijdragen aan openbare, of publieke, projecten gaat op een iets andere manier. Omdat je niet de toestemming hebt om de branches van het project te updaten, moet je het werk op een andere manier naar de beheerders krijgen. Dit eerste voorbeeld beschrijft het bijdragen via afsplitsen (forken) op Git hosts, die het makkelijk maken om te forken. De repo.or.cz en GitHub hosting sites ondersteunen dit beiden, en veel project beheerders verwachten deze manier van bijdragen. De volgende paragraaf behandelt projecten die de voorkeur hebben om bijdragen in de vorm van patches via e-mail te ontvangen. +Het bijdragen aan openbare, of publieke, projecten gaat op een iets andere manier. Omdat je niet de toestemming hebt om de branches van het project rechtstreeks te updaten, moet je het werk op een andere manier naar de beheerders krijgen. Dit eerste voorbeeld beschrijft het bijdragen via afsplitsen (forken) op Git hosts die het eenvoudig aanmaken van forks ondersteunen. De repo.or.cz en GitHub hosting sites ondersteunen dit beide, en veel project beheerders verwachten deze manier van bijdragen. De volgende paragraaf behandelt projecten die de voorkeur hebben om bijdragen in de vorm van patches via e-mail te ontvangen. -Eerst zal je waarschijnlijk de hoofdrepository klonen, een topic branch maken voor de patch of reeks patches die je van plan bent bij te dragen, en je werk daarop doen. De werkwijze ziet er zo uit: +Eerst zal je waarschijnlijk de hoofdrepository klonen, een topic branch maken voor de patch of reeks patches die je van plan bent bij te dragen, en je werk daarop doen. De te volgen stappen zien er zo uit: $ git clone (url) $ cd project @@ -398,19 +398,19 @@ Eerst zal je waarschijnlijk de hoofdrepository klonen, een topic branch maken vo $ (work) $ git commit -Je wil misschien de `rebase -i` optie gebruiken om je werk in n enkele commit samen te persen (squash), of het werk in de commits herschikken om de patch eenvoudiger te kunnen laten reviewen door de beheerders - zie Hoofdstuk 6 voor meer informatie over het interactief rebasen. +Je kunt eventueel besluiten `rebase -i` te gebruiken om je werk in n enkele commit samen te persen (squash), of het werk in de commits te herschikken om de patch eenvoudiger te kunnen laten reviewen door de beheerders - zie Hoofdstuk 6 voor meer informatie over het interactief rebasen. -Als je werk op de branch af is, en je klaar bent om het over te dragen aan de beheerders, ga je naar de originele project pagina en klik op de "Fork" knop, hiermee maak je een eigen schrijfbare fork van het project. Je moet dit dan in een nieuwe repository URL toevoegen als een tweede remote, in dit geval `myfork` genaamd: +Als je werk op de branch af is, en je klaar bent om het over te dragen aan de beheerders, ga je naar de originele project pagina en klik op de "Fork" knop. Hiermee maak je een eigen overschrijfbare fork van het project. Je moet de URL van deze nieuwe repository URL toevoegen als een tweede remote, in dit geval `myfork` genaamd: $ git remote add myfork (url) -Je moet je werk hier naar pushen. Het is het makkelijkst om de remote branch waar je op zit te werken te pushen naar je repository, in plaats van het samenvoegen in je master branch en die terug te zetten. De reden hiervan is, dat als het werk niet wordt geaccepteerd of alleen ge-cherry picked, je jouw master branch niet hoeft terug te draaien. Als de beheerders je werk mergen, rebasen of cherry picken, dan krijg je het uiteindelijk toch terug door hun repository te pullen: +Je moet je werk daar naartoe pushen. Het is het makkelijkst om de remote branch waar je op zit te werken te pushen naar je repository, in plaats van het samenvoegen in je master branch en die te pushen. De reden hiervan is, dat als het werk niet wordt geaccepteerd of alleen ge-cherry picked (deels overgenomen), je jouw master branch niet hoeft terug te draaien. Als de beheerders je werk mergen, rebasen of cherry picken, dan krijg je het uiteindelijk toch binnen door hun repository te pullen: $ git push myfork featureA -Als jouw werk gepushed is naar jouw fork, dan moet je de beheerder een seintje geven. Dit wordt vaak een pull request (haal-binnen-verzoek) genoemd, en je kunt het via de website genereren - GitHub heeft een "pull request" knop die de beheerder automatisch een bericht stuurt - of het `git request-pull` commando uitvoeren en de uitvoer handmatig naar de projectbeheerder mailen. +Als jouw werk gepushed is naar jouw fork, dan moet je de beheerder inlichten. Dit wordt een pull request (haal-binnen-verzoek) genoemd, en je kunt deze via de website genereren - GitHub heeft een "pull request" knop die de beheerder automatisch een bericht stuurt - of het `git request-pull` commando uitvoeren en de uitvoer handmatig naar de projectbeheerder mailen. -Het `request-pull` commando neemt de branch waarin je je topic branch gepulled wil hebben, en de URL van de Git repository waar je ze uit wil laten pullen, en maakt een samenvatting van alle wijzigingen die je gepulled wenst te hebben. Bijvoorbeeld, als Jessica John een pull request wil sturen, en ze heeft twee commits gedaan op de topic branch die ze zojuist gepushed heeft, dan kan ze dit uitvoeren: +Het `request-pull` commando neemt de basis branch waarin je de topic branch gepulled wil hebben, en de URL van de Git repository waar je ze uit wil laten pullen, en maakt een samenvatting van alle wijzigingen die je gepulled wenst te hebben. Bijvoorbeeld, als Jessica John een pull request wil sturen, en ze heeft twee commits gedaan op de topic branch die ze zojuist gepushed heeft, dan kan ze dit uitvoeren: $ git request-pull origin/master myfork The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40: @@ -428,9 +428,9 @@ Het `request-pull` commando neemt de branch waarin je je topic branch gepulled w lib/simplegit.rb | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) -De uitvoer kan naar de beheerder gestuurd worden: het verteld ze waar het werk vanaf gebranched is, vat de commits samen, en verteld waar vandaan ze dit werk kunnen pullen. +De uitvoer kan naar de beheerders gestuurd worden: het verteld ze waar het werk vanaf gebranched is, vat de commits samen en verteld waar vandaan ze dit werk kunnen pullen. -Bij een project waarvan je niet de beheerder bent, is het over het algemeen eenvoudiger om een branch zoals `master` altijd de `origin/master` te laten volgen, en je werk te doen in topic branches die je eenvoudig weg kunt gooien als ze geweigerd worden. Als je je werkthema's gescheiden houdt in topic branches maakt dat het ook eenvoudiger voor jou om je werk te rebasen als de punt van het hoofd repository in de tussentijd verschoven is en je commits niet langer netjes toegepast kunnen worden. Bijvoorbeeld, als je een tweede onderwerp wil bijdragen aan een project, ga dan niet verder werken op de topic branch die je zojuist gepushed hebt - begin opnieuw vanaf de `master` branch van het hoofd repository: +Bij een project waarvan je niet de beheerder bent, is het over het algemeen eenvoudiger om een branch zoals `master` altijd de `origin/master` te laten volgen, en je werk te doen in topic branches die je eenvoudig weg kunt gooien als ze geweigerd worden. Als je je werkthema's gescheiden houdt in topic branches maakt dat het ook eenvoudiger voor jou om je werk te rebasen als de punt van het hoofd repository in de tussentijd verschoven is en je commits niet langer netjes toegepast kunnen worden. Bijvoorbeeld, als je een tweede onderwerp wilt bijdragen aan een project, ga dan niet verder werken op de topic branch die je zojuist gepushed hebt - begin opnieuw vanaf de `master` branch van het hoofd repository: $ git checkout -b featureB origin/master $ (work) @@ -439,12 +439,12 @@ Bij een project waarvan je niet de beheerder bent, is het over het algemeen eenv $ (email maintainer) $ git fetch origin -Nu zijn al je onderwerpen opgeslagen in een silo - vergelijkbaar met een patch rij - die je kunt herschrijven, rebasen en wijzigen zonder dat de onderwerpen elkaar benvloeden of van elkaar afhankelijk zijn zoals in Figuur 5-16. +Nu zijn al je onderwerpen opgeslagen in een silo - vergelijkbaar met een patch reeks (queue) - die je kunt herschrijven, rebasen en wijzigen zonder dat de onderwerpen elkaar benvloeden of van elkaar afhankelijk zijn zoals in Figuur 5-16. Insert 18333fig0516.png Figuur 5-16. Initile commit historie met werk van featureB. -Stel dat de project beheerder een berg andere patches binnengehaald heeft en je eerste branch geprobeerd heeft, maar dat die niet langer netjes merged. In dat geval kun je proberen die branch te rebasen op de punt van `origin/master`, de conflicten op te lossen voor de beheerder, en dan je wijzigingen opnieuw aanbieden: +Stel dat de project beheerder een verzameling andere patches binnengehaald heeft en jouw eerste branch geprobeerd heeft, maar dat die niet meer netjes merged. In dat geval kun je proberen die branch te rebasen op de punt van `origin/master`, de conflicten op te lossen voor de beheerder, en dan je wijzigingen opnieuw aanbieden: $ git checkout featureA $ git rebase origin/master @@ -457,7 +457,7 @@ Figuur 5-17. Commit historie na werk van featureA. Omdat je de branch gerebased hebt, moet je de `-f` specificeren met je push commando om in staat te zijn de `featureA` branch op de server te vervangen met een commit die er geen afstammeling van is. Een alternatief zou zijn dit nieuwe werk naar een andere branch op de server te pushen (misschien `featureAv2` genaamd). -Laten we eens kijken naar nog een mogelijk scenario: de beheerder heeft je werk bekeken in je tweede branch en vind het concept goed, maar zou willen dat je een implementatie detail verandert. Je zult deze gelegenheid ook gebruiken om het werk te baeren op de huidige `master` branch van het project. Je begint een nieuwe branch gebaseerd op de huidige `origin/master` branch, squashed de `featureB` wijzigingen er naartoe, lost conflicten op, doet de implementatie wijziging, en zet dat terug als een nieuwe branch: +Laten we eens kijken naar nog een mogelijk scenario: de beheerder heeft je werk bekeken in je tweede branch en vind het concept goed, maar zou willen dat je een implementatie detail verandert. Je moet deze gelegenheid meteen gebruiken om het werk te baseren op de huidige `master` branch van het project. Je begint een nieuwe branch gebaseerd op de huidige `origin/master` branch, squashed de `featureB` wijzigingen er naartoe, lost conflicten op, doet de implementatie wijziging en pushed deze terug als een nieuwe branch: $ git checkout -b featureBv2 origin/master $ git merge --no-commit --squash featureB @@ -474,9 +474,9 @@ Figuur 5-18. Commit historie na het featureBv2 werk. ### Openbaar groot project ### -Veel grote projecten hebben vastgestelde procedures voor het accepteren van patches - je zult de specifieke regels voor ieder project goed moeten bekijken, omdat ze zullen verschillen. Maar, veel grote projecten accepteren patches via ontwikkelaar maillijsten, dus ik zal zo'n voorbeeld nu laten zien. +Veel grote projecten hebben vastgestelde procedures voor het accepteren van patches - je zult de specifieke regels voor ieder project goed moeten bekijken, omdat ze verschillend zullen zijn. Veel grote projecten accepteren patches veelal via ontwikkelaar maillijsten, daarom zal ik zo'n voorbeeld nu laten zien. -De werkwijze is vergelijkbaar met het vorige geval - je maakt topic branches voor iedere patch waar je aan werkt. Het verschil is hoe je die aanlevert bij het project. In plaats van het project te forken en naar je eigen schrijfbare versie te pushen, genereer je e-mail versies van iedere commit serie en mailt die naar de ontwikkelaar maillijst: +De werkwijze is vergelijkbaar met het vorige geval - je maakt topic branches voor iedere patch waar je aan werkt. Het verschil is hoe je die aanlevert bij het project. In plaats van het project te forken en naar je eigen schrijfbare versie te pushen, genereer je e-mail versies van iedere reeks commits en mailt die naar de ontwikkelaar maillijst: $ git checkout -b topicA $ (work) @@ -484,7 +484,7 @@ De werkwijze is vergelijkbaar met het vorige geval - je maakt topic branches voo $ (work) $ git commit -Nu heb je twee commits die je wil sturen naar de maillijst. Je gebruikt `git format-patch` om de mbox-geformatteerde bestanden te genereren, die je kunt e-mailen naar de lijst. Dit vormt iedere commit om naar een e-mail bericht met de eerste regel van het commit bericht als de onderwerp regel, en de rest van het bericht plus de patch die door de commit wordt gentroduceerd als de inhoud. Het prettige hieraan is dat het toepassen van een patch uit een mail die gegenereerd is met `format-patch` alle commit informatie goed behoudt, zoals je in de volgende paragraaf meer zult zien als je deze commits toepast: +Nu heb je twee commits die je wil sturen naar de maillijst. Je gebruikt `git format-patch` om de mbox-geformatteerde bestanden te genereren die je kunt mailen naar de lijst. Dit vormt iedere commit om naar een e-mail bericht met de eerste regel van het commit bericht als de onderwerp regel, en de rest van het bericht plus de patch die door de commit wordt gentroduceerd als de inhoud. Het prettige hieraan is dat met het toepassen van een patch uit een mail die gegenereerd is met `format-patch` alle commit informatie blijft behouden. In de volgende paragraaf zal je hiervan meer zien, als je deze commits gaat toepassen: $ git format-patch -M origin/master 0001-add-limit-to-log-function.patch @@ -520,11 +520,11 @@ Het `format-patch` commando drukt de namen af van de patch bestanden die het maa -- 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 verschijnen. 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, die je niet in het commit bericht wil laten verschijnen, voor de maillijst toe te voegen . 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 mailen naar een maillijst, kun je het bestand in je mail applicatie plakken of het sturen via een commandoregel programma. Het plakken van de tekst veroorzaakt vaak formaterings problemen, in het bijzonder bij "slimmere" clients die geen newlines en andere witruimte juist behouden. Gelukkig levert Git een gereedschap die je helpt om juist geformatteerde patches via IMAP te versturen, wat makkelijker voor je kan zijn. Ik zal zal je laten zien hoe je een patch via Gmail stuurt, wat de 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. +Om dit te mailen naar een maillijst, kun je het bestand in je mail applicatie plakken of het sturen via een commandoregel programma. Het plakken van de tekst veroorzaakt vaak formaterings problemen, in het bijzonder bij "slimmere" clients die de newlines en andere witruimte niet juist behouden. Gelukkig levert Git een gereedschap die je helpt om juist geformatteerde patches via IMAP te versturen, wat het alweer een stuk makkelijker voor je maakt. Ik zal zal je laten zien hoe je een patch via Gmail stuurt, wat de mail applicatie is die ik toevallig 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. -Eerst moet je de imap sectie in je `~/.gitconfig` bestand instellen. Je kunt iedere waarde apart instellen met een serie `git config` commando's, of je kunt ze handmatig toevoegen; maar op het eind moet je config bestand er ongeveer zo uitzien: +Eerst moet je de imap sectie in je `~/.gitconfig` bestand instellen. Je kunt iedere waarde apart instellen met een serie `git config` commando's, of je kunt ze handmatig toevoegen, maar uiteindelijk moet je config bestand er ongeveer zo uitzien: [imap] folder = "[Gmail]/Drafts" @@ -544,7 +544,7 @@ Als dat ingesteld is, kun je `git send-email` gebruiken om de patch reeks in de sending 2 messages 100% (2/2) done -Nu kan je naar je Drafts folder gaan, het To veld te wijzigen naar de maillijst waar je de patch naartoe stuurt en mogelijk de beheerder of verantwoordelijke voor dat deel in de CC zetten en dan versturen. +Nu kan je naar die Drafts folder gaan, het To veld te wijzigen naar de maillijst waar je de patch naartoe stuurt en misschien de beheerder of verantwoordelijke voor dat deel in de CC zetten en dan versturen. Je kunt de patches ook via een SMTP server sturen. Zoals eerder kan je elke waarde apart instellen met een serie `git config` commando's, of je kunt ze handmatig in de sendmail sectie in je `~/.gitconfig` bestand zetten: @@ -554,7 +554,7 @@ Je kunt de patches ook via een SMTP server sturen. Zoals eerder kan je elke waar smtpuser = user@gmail.com smtpserverport = 587 -Als dit gebeurt is, kan je `git send-email` gebruiken om je patches te sturen: +Als dit gebeurd is, kan je `git send-email` gebruiken om je patches te sturen: $ git send-email *.patch 0001-added-limit-to-log-function.patch @@ -564,7 +564,7 @@ Als dit gebeurt is, kan je `git send-email` gebruiken om je patches te sturen: Who should the emails be sent to? jessica@example.com Message-ID to be used as In-Reply-To for the first email? y -Dan spuuwt Git een bergje log-informatie uit voor iedere patch die je stuurt, en dat ziet er ongeveer zo uit: +Dan spuuwt Git een bergje log-informatie uit voor elke patch die je stuurt, wat er ongeveer zo uitziet: (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' @@ -583,15 +583,15 @@ Dan spuuwt Git een bergje log-informatie uit voor iedere patch die je stuurt, en ### Samenvatting ### -In dit hoofdstuk is een aantal veel voorkomende werkwijzen behandeld, die je kunt gebruiken om te kunnen werken in een aantal zeer verschillende typen Git projecten die je misschien zult tegenkomen en een aantal nieuwe gereedschappen gentroduceerd, die je helpen om dit proces te beheren. Wat hierna volgt zal je laten zien hoe je aan de andere kant van de medaille werkt: een Git project beheren. Je zult leren hoe een welwillende dictator of integratie manager te zijn. +In dit hoofdstuk is een aantal veel voorkomende werkwijzen behandeld, die je kunt gebruiken om te kunnen werken in een aantal zeer verschillende typen Git projecten die je misschien zult tegenkomen, en een aantal nieuwe gereedschappen gentroduceerd die je helpen om dit proces te beheren. Wat hierna volgt zal je laten zien hoe je aan de andere kant van de tafel werkt: een Git project beheren. Je zult leren hoe een welwillende dictator of integratie manager te zijn. ## Het beheren van een project ## -Naast weten hoe effectief bij te dragen aan een project, moet je waarschijnlijk ook moeten weten hoe je er een beheert. Dit kan bestaan uit het accepteren en toepassen van patches die met `format-patch` gemaakt en naar je gemaild zijn, of het integreren van wijzigingen in de remote branches van repositories die je hebt toegevoegd als remotes van je project. Of je nu een canonieke repository beheert, of wilt bijdragen door het controleren of goedkeuren van patches, je moet weten hoe werk te ontvangen op een dusdanige manier die het duidelijkst is voor andere bijdragers en voor jou op langere termijn vol te houden. +Naast weten hoe effectief bij te dragen aan een project, moet je waarschijnlijk ook moeten weten hoe je er een beheert. Dit kan bestaan uit het accepteren en toepassen van patches die met `format-patch` gemaakt en naar je gemaild zijn, of het integreren van wijzigingen in de remote branches van repositories die je hebt toegevoegd als remotes van je project. Of je nu een canonieke repository beheert, of wilt bijdragen door het controleren of goedkeuren van patches, je moet weten hoe werk te ontvangen op een zodanige manier die het duidelijkst is voor andere bijdragers en voor jou op langere termijn vol te houden. ### Werken in topic branches ### -Als je overweegt om nieuw werk te integreren, is het over het algemeen een goed idee om het uit te proberen in een topic branch - een tijdelijke branch, speciaal gemaakt om dat nieuwe werk uit te proberen. Op deze manier is het handig om een patch individueel te behandelen en het even opzij te zetten als het niet werkt, totdat je tijd hebt om er op terug te komen. Als je een eenvoudige branchnaam maakt, gebaseerd op het onderwerp van het werk dat je aan het proberen bent, bijvoorbeeld `ruby_client` of zoiets beschrijvends, dan is het makkelijk om te herinneren als je het voor een tijdje moet achterlaten en er later op terug komt. De beheerder van het Git project heeft de neiging om deze branches ook van een naamsruimte (namespace) te voorzien - zoals `sc/ruby_client`, waarbij `sc` een afkorting is van de persoon die het werk heeft bijgedragen. +Als je overweegt om nieuw werk te integreren, is het over het algemeen een goed idee om het uit te proberen in een topic branch - een tijdelijke branch, speciaal gemaakt om dat nieuwe werk uit te proberen. Op deze manier is het handig om een patch individueel te behandelen en het even opzij te zetten als het niet werkt, totdat je tijd hebt om er op terug te komen. Als je een eenvoudige branchnaam maakt, gebaseerd op het onderwerp van het werk dat je aan het proberen bent, bijvoorbeeld `ruby_client` of zoiets beschrijvends, dan is het makkelijk om te herinneren als je het voor een tijdje opzij moet leggen en er later op terug komt. De beheerder van het Git project heeft de neiging om deze branches ook van een naamsruimte (namespace) te voorzien - zoals `sc/ruby_client`, waarbij `sc` een afkorting is van de persoon die het werk heeft bijgedragen. Zoals je je zult herinneren, kun je de branch gebaseerd op je master branch zo maken: $ git branch sc/ruby_client master @@ -604,7 +604,7 @@ Nu ben je klaar om het bijgedragen werk in deze topic branch toe te voegen, en t ### Patches uit e-mail toepassen ### -Als je een patch per e-mail ontvangt, die je moet integreren in je project, moet je de patch in je onderwerp branch toepassen om het te evalueren. Er zijn twee manieren om een ge-mailde patch toe te passen: met `git apply` of met `git am`. +Als je een patch per e-mail ontvangt, en je moet die integreren in je project, moet je de patch in je topic branch toepassen om het te evalueren. Er zijn twee manieren om een ge-mailde patch toe te passen: met `git apply` of met `git am`. #### Een patch toepassen met apply #### @@ -612,21 +612,21 @@ Als je de patch ontvangen hebt van iemand die het gegenereerd heeft met de `git $ git apply /tmp/patch-ruby-client.patch -Dit wijzigt de bestanden in je werk directory. Het is vrijwel gelijk aan het uitvoeren van een `patch -p1` commando om de patch toe te passen, alhoewel het meer paranode is en minder fuzzy matches accepteert dan patch. Het handelt ook bestandstoevoegingen af, -verwijderingen, en hernoemingen als ze beschreven staan in het `git diff` formaat, wat `patch` niet doet. Als laatste volgt `git apply` een "pas alles toe of laat alles weg" model, waarbij alles of niets wordt toegepast, en `patch` gedeeltelijke patches kan toepassen, waardoor je werk directory in een vreemde status achterblijft. `git apply` is over het algemeen meer paranode dan `patch`. Het zal geen commit voor je aanmaken - na het uitgevoerd te zijn, je moet de gentroduceerde wijzigingen handmatig stagen en committen. +Dit wijzigt de bestanden in je werk directory. Het is vrijwel gelijk aan het uitvoeren van een `patch -p1` commando om de patch toe te passen, alhoewel het meer paranode is en minder "fuzzy matches" accepteert dan patch. Het handelt ook bestandstoevoegingen af, -verwijderingen, en hernoemingen als ze beschreven staan in het `git diff` formaat, wat `patch` niet doet. Als laatste volgt `git apply` een "pas alles toe of laat alles weg" model waarbij alles of niets wordt toegepast. Dit in tegenstelling tot `patch` die gedeeltelijke patches kan toepassen, waardoor je werk directory in een vreemde status achterblijft. Over het algemeen is `git apply` meer paranode dan `patch`. Het zal geen commit voor je aanmaken; na het uitvoeren moet je de gentroduceerde wijzigingen handmatig stagen en committen. -Je kunt ook git apply gebruiken om te zien of een patch netjes wordt toepast voordat je het echt toepast - je kunt `git apply --check` uitvoeren met de patch: +Je kunt ook git apply gebruiken om te zien of een patch netjes kan worden toepast voordat je het echt doet; je kunt `git apply --check` uitvoeren met de 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 -Als er geen uitvoer is, dan zou de patch netjes moeten passen. Dit commando eindigt ook met een niet-nul status als de controle faalt, zodat je het kunt gebruiken in scripts als je dat wilt. +Als er geen uitvoer is, dan zou de patch netjes moeten passen. Dit commando retourneert ook een niet-nul status als de controle faalt, zodat je het kunt gebruiken in scripts als je dat zou willen. #### Een patch met am toepassen #### -Als de bijdrager een Git gebruiker is en zo vriendelijk was om het `format-patch` commando te gebruiken om hun patch te genereren, dan is je werk eenvoudiger omdat de patch de auteur informatie en een commit bericht voor je bevat. Als je kunt, moedig je bijdragers aan om `format-patch` te gebruiken in plaats van `diff` om patches te genereren voor je. Je zou alleen `git apply` hoeven te gebruiken voor oude patches en dat soort dingen. +Als de bijdrager een Git gebruiker is en zo vriendelijk is geweest om het `format-patch` commando te gebruiken om de patch te genereren, dan is je werk eenvoudiger omdat de patch de auteur informatie en een commit bericht voor je bevat. Als het enigzins kan, probeer dan je bijdragers aan te moedigen om `format-patch` te gebruiken in plaats van `diff` om patches te genereren voor je. Je zou alleen `git apply` willen hoeven te gebruiken voor oude patches en dat soort dingen. -Om een patch gegenereerd met `format-patch` toe te passen, gebruik je `git am`. Technisch is `git am` gemaakt om een mbox bestand te lezen, dat een eenvoudig gewone platte tekstformaat is om n of meer e-mail berichten in een tekst bestand op te slaan. Het ziet er ongeveer zo uit: +Om een patch gegenereerd met `format-patch` toe te passen, gebruik je `git am`. Technisch is `git am` gemaakt om een mbox bestand te lezen, dat een eenvoudig gewone platte tekstformaat is om n of meer e-mail berichten in een tekstbestand op te slaan. Het ziet er ongeveer zo uit: From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith @@ -635,14 +635,14 @@ Om een patch gegenereerd met `format-patch` toe te passen, gebruik je `git am`. Limit log functionality to the first 20 -Dit is het begin van de uitvoer van het format-patch commando dat je gezien hebt in de vorige paragraaf. Dit is ook een geldig mbox e-mail formaat. Als iemand jou de patch correct gemaild heeft door gebruik te maken van git send-email en je downloadt dat in een mbox formaat, dan kan je het git am naar dat mbox bestand verwijzen, en het zal beginnen met alle patches die het ziet toe te passen. Als je een mail client gebruikt die meerdere e-mails kan opslaan in mbox formaat, dan kun je hele patch series in een bestand opslaan en dan git am gebruiken om ze een voor een toe te passen. +Dit is het begin van de uitvoer van het format-patch commando dat je gezien hebt in de vorige paragraaf. Dit is ook een geldig mbox e-mail formaat. Als iemand jou de patch correct gemaild heeft door gebruik te maken van git send-email en je downloadt dat in een mbox formaat, dan kan je het git am naar dat mbox bestand verwijzen, en het zal beginnen met alle patches die het tegenkomt toe te passen. Als je een mail client gebruikt die meerdere e-mails kan opslaan in mbox formaat, dan kun je hele reeksen patches in een bestand opslaan en dan git am gebruiken om ze n voor n toe te passen. -Maar, als iemand een patch bestand heeft ge-upload die gegenereerd is met `format-patch` naar een ticket systeem of zoiets, kun je het bestand lokaal opslaan en dan dat opgeslagen bestand aan `git am` doorgeven om het toe te passen: +Maar, als iemand een patch bestand heeft gepload die gegenereerd is met `format-patch` naar een ticket systeem of zoiets, kun je het bestand lokaal opslaan en dan dat opgeslagen bestand aan `git am` doorgeven om het toe te passen: $ git am 0001-limit-log-function.patch Applying: add limit to log function -Je kunt zien dat het netjes is toegepast, en automatisch een nieuwe commit voor je heeft aangemaakt. De auteursinformatie wordt gehaald uit de `From` en `Date` velden in de kop, en het bericht van de commit wordt gehaald uit de `Subject` en inhoud (voor de patch) van het mail bericht. Bijvoorbeeld, als deze patch was toegepast van het mbox voorbeeld dat ik zojuist getoond heb, dan zou de gegenereerde commit er ongeveer zo uit zien: +Je ziet dat het netjes is toegepast, en automatisch een nieuwe commit voor je heeft aangemaakt. De auteursinformatie wordt gehaald uit de `From` en `Date` velden in de kop, en het bericht van de commit wordt gehaald uit de `Subject` en de inhoud (voor de patch) uit het mailbericht zelf. Bijvoorbeeld, als deze patch was toegepast van het mbox voorbeeld dat ik zojuist getoond heb, dan zou de gegenereerde commit er ongeveer zo uit zien: $ git log --pretty=fuller -1 commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 @@ -655,9 +655,9 @@ Je kunt zien dat het netjes is toegepast, en automatisch een nieuwe commit voor Limit log functionality to the first 20 -De `Commit` informatie laat de persoon die de patch toepaste en de tijd waarop het is toegepast zien. De `Author` informatie het individu die de patch oorspronkelijk gemaakt heeft en wanneer het gemaakt is. +De `Commit` informatie toont de persoon die de patch toepaste en de tijd waarop het is toegepast. De `Author` informatie de persoon die de patch oorspronkelijk gemaakt heeft en wanneer het gemaakt is. -Maar het is mogelijk dat de patch niet netjes toegepast kan worden. Misschien is je hoofdbranch te ver afgeweken van de branch waarop de patch gebouwd is, of is de patch van een andere patch, die je nog niet hebt toegepast, afhankelijk. In dat geval zal het `git am` proces falen en je vragen wat je wilt doen: +Maar het is mogelijk dat de patch niet netjes toegepast kan worden. Misschien is jouw hoofdbranch te ver afgeweken van de branch waarop de patch gebouwd is, of is de patch afhankelijk van een andere patch, die je nog niet hebt toegepast. In dat geval zal het `git am` proces falen en je vragen wat je wilt doen: $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem @@ -668,14 +668,14 @@ Maar het is mogelijk dat de patch niet netjes toegepast kan worden. Misschien is 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". -Dit commando stopt conflict markeringen in alle bestanden waar het problemen mee heeft, net zoals een conflicterende merge of rebase operatie. Je lost dit probleem op een vergelijkbare manier op - wijzig het bestand om het conflict op te lossen, stage het bestand, en voer dan `git am --resolved` uit om door te gaan met de volgende patch: +Dit commando zet conflict markeringen in alle bestanden waar het problemen mee heeft, net zoals een conflicterende merge of rebase operatie. Je lost dit probleem op een vergelijkbare manier op: wijzig het bestand om het conflict op te lossen, stage het bestand en voer dan `git am --resolved` uit om door te gaan met de volgende patch: $ (fix the file) $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem -Als je wil dat Git een beetje meer intelligentie toepast om het conflict op te lossen, kun je een `-3` optie eraan meegeven, wat ervoor zorgt dat Git een driewegs-merge probeert. Deze optie staat standaard niet aan, omdat het niet werkt als de commit waarvan de patch zegt dat het op gebaseerd is niet in je repository zit. Als je die commit wel hebt - als de patch gebaseerd was op een publieke commit - dan is de `-3` over het algemeen veel slimmer in het toepassen van een conflicterende patch: +Als je wil dat Git iets meer intelligentie toepast om het conflict op te lossen, kun je een `-3` optie eraan meegeven, dit zorgt ervoor dat Git een driewegs-merge probeert. Deze optie staat standaard niet aan omdat het niet werkt als de commit waarvan de patch zegt dat het op gebaseerd is niet in je repository zit. Als je die commit wel hebt - als de patch gebaseerd was op een publieke commit - dan is de `-3` over het algemeen veel slimmer in het toepassen van een conflicterende patch: $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem @@ -696,23 +696,23 @@ Als je een aantal patches van een mbox toepast, kun je ook het `am` commando in -------------------------- Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all -Dit is prettig als je een aantal patches bewaard hebt, omdat je de patch eerst kunt zien als je je niet kunt herinneren wat het is, of de patch niet wilt toepassen als je dat al gedaan hebt. +Dit is prettig als je een aantal patches bewaard hebt, omdat je de patch eerst kunt zien als je je niet kunt herinneren wat het is, of de patch niet wilt toepassen omdat je dat al eerder gedaan hebt. -Als alle patches voor je topic branch zijn toegepast en gecommit zijn op je branch, kun je kiezen of en hoe ze te integreren in een branch met een langere looptijd. +Als alle patches voor je topic branch zijn toegepast en gecommit zijn op je branch, kan je besluiten of en hoe ze te integreren in een branch met een langere looptijd. ### Remote branches uitchecken ### -Als je bijdrage van een Git gebruiker komt, die zijn eigen repository opgezet heeft, een aantal patches daarin gepushed heeft, en jou de URL naar de repository gestuurd heeft en de naam van de remote branch waarin de wijzigingen zitten, kan je ze toevoegen als een remote en het mergen lokaal doen. +Als je bijdrage van een Git gebruiker komt die zijn eigen repository opgezet heeft, een aantal patches daarin gepushed heeft, en jou de URL naar de repository gestuurd heeft en de naam van de remote branch waarin de wijzigingen zitten, kan je ze toevoegen als een remote en het mergen lokaal doen. -Bijvoorbeeld, als Jessica je een e-mail stuurt waarin staat dat ze een mooie nieuw feature in de `ruby-client` branch van haar repository heeft, kun je het testen door de remote toe te voegen en die branch lokaal te bekijken: +Bijvoorbeeld, als Jessica je een e-mail stuurt waarin staat dat ze een prachtig mooie nieuwe feature in de `ruby-client` branch van haar repository heeft, kun je deze testen door de remote toe te voegen en die branch lokaal te bekijken: $ git remote add jessica git://github.com/jessica/myproject.git $ git fetch jessica $ git checkout -b rubyclient jessica/ruby-client -Als ze je later opnieuw e-mailt met een andere branch die een andere mooie feature bevat, dan kun je die ophalen en bekijken omdat je de remote al ingesteld hebt. +Als ze je later opnieuw mailt met een andere branch die weer een andere mooie feature bevat, dan kun je die ophalen en bekijken omdat je de remote al ingesteld hebt. -Dit is meest nuttig als je vaak met een persoon werkt. Als iemand een enkele patch eens in de zoveel tijd bij te dragen heeft, dan is het accepteren per e-mail misschien minder tijdrovend dan eisen dat iedereen hun eigen server moet draaien en doorlopend remotes toevoegen en verwijderen om een paar patches te krijgen. Je zult waarschijnlijk ook niet honderden remotes willen hebben, elk voor iemand die maar een patch of twee bijdraagt. Aan de andere kant, scripts en gehoste diensten maken dit misschien makkelijker - het hangt veel af van hoe jij ontwikkelt en hoe je bijdragers ontwikkelen. +Dit is meest practisch als je vaak met een persoon werkt. Als iemand een enkele patch eens in de zoveel tijd bij te dragen heeft, dan is het accepteren per mail misschien minder tijdrovend dan te eisen dat iedereen hun eigen server moet beheren, en daarna voortdurend remotes te moeten toevoegen en verwijderen voor die paar patches. Je zult daarbij waarschijnlijk ook niet honderden remotes willen hebben, elk voor iemand die maar een patch of twee bijdraagt. Aan de andere kant, scripts en gehoste diensten maken het wellicht eenvoudiger; het hangt sterk af van de manier waarop ontwikkelt en hoe je bijdragers ontwikkelen. Het andere voordeel van deze aanpak is dat je de historie van de commits ook krijgt. Alhoewel je misschien terechte merge problemen hebt, weet je op welk punt in de historie hun werk is gebaseerd; een echte drieweg merge is de standaard in plaats van een `-3` te moeten meegeven en hopen dat de patch gegenereerd was van een publieke commit waar je toegang toe hebt. @@ -725,9 +725,9 @@ Als je maar af en toe met een persoon werkt, maar toch op deze manier van hen wi ### Bepalen wat gentroduceerd wordt ### -Je hebt een topic branch dat bijgedragen werk bevat. Nu kan je bepalen wat je er mee wilt doen. Deze paragraaf bekijkt een paar commando's opnieuw om te laten zien hoe je ze kunt gebruiken om precies te reviewen wat je zult introduceren als je dit merged in je hoofd branch. +Je hebt een topic branch dat bijgedragen werk bevat. Nu kan je bepalen wat je er mee wilt doen. Deze paragraaf bekijkt een paar commando's nogmaals om te laten zien hoe je ze kunt gebruiken om precies te reviewen wat je zult introduceren als je dit merged in je hoofd branch. -Het is vaak behulpzaam om een review te krijgen van alle commits die in deze branch zitten, maar die niet in je master branch zitten. Je kunt commits weglaten in de master branch door de `--not` optie mee te geven voor de branch naam. Bijvoorbeeld, als je bijdrager je twee patches stuurt en je wil een branch genaamd `contrib` maken en die patches daar toepassen, dan kun je dit uitvoeren: +Het is vaak handig om een review te krijgen van alle commits die in deze branch zitten, maar die niet in je master branch zitten. Je kunt commits weglaten die al in de master branch zitten door de `--not` optie mee te geven voor de branch naam. Bijvoorbeeld, als je bijdrager je twee patches stuurt, je hebt een branch genaamd `contrib` gemaakt en hebt die patches daar toegepast, dan kun je dit uitvoeren: $ git log contrib --not master commit 5b6235bd297351589efc4d73316f0a68d484f118 @@ -742,107 +742,107 @@ Het is vaak behulpzaam om een review te krijgen van alle commits die in deze bra updated the gemspec to hopefully work better -Om te zien welke wijzigingen iedere commit introduceert, onthoud dan dat je de `-p` optie kunt meegeven aan `git log` en dan zal het de diff gentroduceerd bij iedere commit weergeven. +Om te zien welke wijzigingen door iedere commit worden gentroduceert, onthoud dan dat je de `-p` optie kunt meegeven aan `git log` en dan zal het de diff weergeven die bij iedere commit wordt gentroduceerd. -Om een volledige diff te zien van wat zou gebeuren als je deze onderwerp branch samenvoegt met een andere branch, zul je misschien een vreemde truc moeten toepassen om de juiste resultaten te krijgen. Je zult misschien denken om dit uit te voeren: +Om een volledige diff te zien van wat zou gebeuren als je deze topic branch merged met een andere branch, zul je misschien een vreemde truc moeten toepassen om de juiste resultaten te krijgen. Je zult misschien denken om dit uit te voeren: $ git diff master -Dit commando geeft je een diff, maar het zou misleidend kunnen zijn. Als je `master` branch vooruit geschoven is sinds je de onderwerp branch er vanaf hebt gebaseerd, dan zul je ogenschijnlijk vreemde resultaten krijgen. Bijvoorbeeld, als je een regel in een bestand hebt toegevoegd op de `master` branch, dan zal een directe vergelijking van de snapshots eruit zien alsof de onderwerp branch die regel gaat verwijderen. +Dit commando geeft je een diff, maar het kan misleidend zijn. Als je `master` branch vooruit geschoven is sinds je de topic branch er vanaf hebt gemaakt, dan zul je ogenschijnlijk vreemde resultaten krijgen. Dit gebeurt omdat Git de snapshots van de laatste commit op de topic branch waar je op zit vergelijkt met het laatste snapshot van de `master` branch. Bijvoorbeeld, als je een regel in een bestand hebt toegevoegd op de `master` branch, dan zal een directe vergelijking van de snapshots eruit zien alsof de topic branch die regel gaat verwijderen. -Als `master` een directe afstammeling is van je onderwerp branch, is dit geen probleem; maar als de twee histories uit elkaar zijn gegaan, zal de diff eruit zien alsof je alle nieuwe spullen in je onderwerp branch toevoegt en al het unieke weghaalt in de `master` branch. +Als `master` een directe voorganger is van je topic branch is dit geen probleem, maar als de twee histories uit elkaar zijn gegaan, zal de diff eruit zien alsof je alle nieuwe spullen in je topic branch toevoegt en al hetgeen wat alleen in de `master` branch staat weghaalt. -Wat je echt wil zien zijn de wijzigingen die in de onderwerp branch zijn toegevoegd - het werk dat je zult introduceren als je deze branch met master samenvoegt. Je doet dat door Git de laatste commit op je onderwerp branch te laten vergelijken met de eerste gezamenlijke voorouder die het heeft met de master branch. +Wat je eigenlijk had willen zien zijn de wijzigingen die in de topic branch zijn toegevoegd: het werk dat je zult introduceren als je deze branch met master merged. Je doet dat door Git de laatste commit op je topic branch te laten vergelijken met de eerste gezamenlijke voorouder die het heeft met de master branch. -Technisch, kun je dat doen door de gezamenlijke voorouder expliciet uit te zoeken en dan daar je diff op uit te voeren: +Technisch, kun je dat doen door de gezamenlijke voorouder op te zoeken en dan daar je diff op uit te voeren: $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 $ git diff 36c7db -Maar, dat is niet handig, dus levert Git een andere korte manier om hetzelfde te doen: de driedubbele punt syntax. In de context van het `diff` commando, kun je drie punten achter een andere branch zetten, om een `diff` te doen tussen de laatste commit van de branch waar je op zit en zijn gezamenlijke voorouder met een andere branch: +Maar, dat is niet handig, dus levert Git een andere verkorte manier om hetzelfde te doen: de driedubbele punt syntax. In de context van het `diff` commando, kun je drie punten achter een andere branch zetten om een `diff` te doen tussen de laatste commit van de branch waar je op zit en de gezamenlijke voorouder met een andere branch: $ git diff master...contrib -Dit commando toont je alleen het werk dat je huidige onderwerp branch heeft gentroduceerd sinds zijn gezamenlijke voorouder met master. Dat is een erg handige syntax om te onthouden. +Dit commando laat alleen het werk zien dat je huidige topic branch heeft gentroduceerd sinds de gezamenlijke voorouder met master. Dat is een erg handige syntax om te onthouden. ### Bijgedragen werk integreren ### -Als al het werk in je onderwerp branch klaar is om te worden gentegreerd in een meer hoofdlijn branch, dan is de vraag hoe het te doen. En daarna, welke algemene werkwijze wil je gebruiken om je project te onderhouden? Je hebt een aantal keuzes, dus ik zal er een paar behandelen. +Als al het werk in je onderwerp branch klaar is om te worden gentegreerd in een hogere branch, dan is de vraag hoe het te doen. En daarnaast, welke werkwijze wil je gebruiken om je project te beheren? Je hebt een aantal keuzes, dus ik zal er een paar behandelen. -#### Samenvoeg werkwijzen #### +#### Merge werkwijzen #### -Een eenvoudige werkwijze voegt je werk in je `master` branch. In dit scenario, heb je een `master` branch die in feite stabiele code bevat. Als je werk in een onderwerp branch hebt dat jij gedaan hebt, of dat iemand anders heeft bijgedragen en jij hebt nagekeken, dan voeg je het in je master branch, verwijderd de onderwerp branch en vervolgt het proces. Als we een repository hebben met werk in twee branches genaamd `ruby_client` en `php_client`, dat eruit ziet zoals Figuur 5-19 en voegen `ruby_client` eerst in en vervolgens `php_client`, dan zal je historie er uit gaan zien zoals in Figuur 5-20. +Een eenvoudige werkwijze merged je werk in de `master` branch. In dit scenario, heb je een `master` branch die feitelijk de stabiele code bevat. Als je werk in een topic branch hebt waaraan je gewerkt hebt, of dat iemand anders heeft bijgedragen en wat je hebt nagekeken, dan merge je het in de master branch, verwijdert de topic branch en vervolgt het proces. Als we een repository hebben met werk in twee branches genaamd `ruby_client` en `php_client`, wat eruit ziet zoals Figuur 5-19 en mergen eerst `ruby_client` en daarna `php_client`, dan zal je historie er uit gaan zien zoals in Figuur 5-20. Insert 18333fig0519.png -Figuur 5-19. Historie met een aantal onderwerp branches. +Figuur 5-19. Historie met een aantal topic branches. Insert 18333fig0520.png -Figuur 5-20. Na het samenvoegen van een onderwerp branch. +Figuur 5-20. Na het mergen van een topic branch. -Dat is waarschijnlijk de eenvoudigste werkwijze, maar het is problematisch als je werkt met grotere repositories of projecten. +Dat is waarschijnlijk de eenvoudigste werkwijze, maar het wordt problematisch als je werkt met grotere repositories of projecten. -Als je meer ontwikkelaars hebt, of een groter project, dan zul je waarschijnlijk een minstens twee fasen samenvoeg cyclus willen gebruiken. In dit scenario, heb je twee langlopende branches, `master` en `develop`, waarin je bepaald dat `master` alleen vernieuwd wordt als een zeer stabiele vrijgave gedaan wordt en alle nieuwe code gentegreerd is in de `develop` branch. Je zet beide branches regelmatig terug naar het publieke repository. Iedere keer als je een nieuw onderwerp branch hebt om samen te voegen (Figuur 5-21), voeg je het in `develop` (Figuur 5-22); daarna, als je een tag maakt van een vrijgave, dan doe je een fast-forward van `master` naar waar de nu stabiele `develop` branch is (Figuur 5-23). +Als je meer ontwikkelaars hebt of een groter project, dan zul je waarschijnlijk minstens een twee-fasen merge cyclus willen toepassen. In dat geval heb je twee langlopende branches, `master` en `develop`, waarbij je bepaalt dat `master` alleen vernieuwd wordt als een zeer stabiele release is gemaakt en alle nieuwe code gentegreerd is in de `develop` branch. Je pushed beide branches op regelmatige basis naar de publieke repository. Iedere keer als je een nieuw topic branch hebt om te mergen (Figuur 5-21), merge je het in `develop` (Figuur 5-22). En als je een tag gemaakt heb van een release, doe je een fast-forward van `master` naar waar de nu stabiele `develop` branch is (Figuur 5-23). Insert 18333fig0521.png -Figuur 5-21. Voor een samenvoeging van een onderwerp branch. +Figuur 5-21. Voor een merge van een topic branch. Insert 18333fig0522.png -Figuur 5-22. Na een samenvoeging van een onderwerp branch. +Figuur 5-22. Na een merge van een topic branch. Insert 18333fig0523.png -Figuur 5-23. Na een vrijgave van een onderwerp branch. +Figuur 5-23. Na een release van een topic branch. -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. +Op deze manier, als mensen de repository van je project klonen, dan kunnen ze kiezen om master uit checken en daarmee de laatste stabiele versie te bouwen en die eenvoudig up-to-date kunnen houden, of ze kunnen develop uit checken waar het nieuwere materiaal in staat. +Je kunt dit concept ook verder doorvoeren, waarbij je een integratie branch hebt waar al het werk gemerged wordt. Als de codebasis op die branch stabiel is en de alle tests daar slagen, dan merge je het in een develop branch. Pas als het daar een periode stabiel is gebleken, dan fast-forward je de master branch. -#### Werkwijzen met grote samenvoegingen #### +#### Werkwijzen met grote merges #### -Het Git project heeft vier langlopende branches: `master`, `next`, en `pu` (proposed updates, voorgestelde vernieuwingen), en `maint` voor onderhoudswerk. Als nieuw werk wordt gentroduceerd door bijdragers, wordt het samengeraapt in onderwerp branches in het repository van de beheerder op een manier gelijk aan wat ik omschreven heb (zie Figuur 5-24). Op dit punt, worden de onderwerpen gevalueerd om te bepalen of ze veilig zijn en klaar voor consumptie of dat ze nog wat werk nodig hebben. Als ze veilig zijn, worden ze in `next` samengevoegd, en wordt die branch teruggezet zodat iedereen de onderwerpen gentegreerd kan proberen. +Het Git project heeft vier langlopende branches: `master`, `next`, en `pu` (proposed updates, voorgestelde vernieuwingen) voor nieuw spul, en `maint` voor onderhoudswerk. Als nieuw werk wordt gentroduceerd door bijdragers, wordt het samengeraapt in topic branches in de repository van de beheerder op een manier die lijkt op wat ik omschreven heb (zie Figuur 5-24). Hier worden de topics gevalueerd om te bepalen of ze veilig zijn en klaar voor verdere verwerking of dat ze nog wat werk nodig hebben. Als ze veilig zijn, worden ze in `next` gemerged, en wordt die branch gepushed zodat iedereen de gentegreerde topics kan uitproberen. Insert 18333fig0524.png -Figuur 5-24. Een complexe serie van parallelle bijgedragen onderwerp branches beheren. +Figuur 5-24. Een complexe serie van parallel bijgedragen topic branches beheren. -Als de onderwerpen nog werk nodig hebben, dan worden ze in plaats daarvan samengevoegd in `pu`. Als bepaald wordt dat ze helemaal stabiel zijn, dan worden de onderwerpen opnieuw samengevoegd in `master` en worden dan herbouwd van de onderwerpen die in `next` waren, maar nog niet geslaagd waren voor `master`. Dit betekend dat `master` vrijwel altijd vooruit beweegt, `next` eens in de zoveel tijd gerebased wordt, en `pu` nog vaker gerebased wordt (zie Figuur 5-25). +Als de topics nog werk nodig hebben, dan worden ze in plaats daarvan gemerged in `pu`. Zodra vastgesteld is dat ze helemaal stabiel zijn, dan worden de topics opnieuw gemerged in `master` en worden dan herbouwd van de topics die in `next` waren, maar nog niet gepromoveerd waren naar `master`. Dit betekent dat `master` vrijwel altijd vooruit beweegt, `next` eens in de zoveel tijd gerebased wordt, en `pu` nog vaker gerebased wordt (zie Figuur 5-25). Insert 18333fig0525.png -Figuur 5-25. Bijgedragen onderwerp branches samenvoegen in langlopende integratie branches. +Figuur 5-25. Bijgedragen topic branches mergen 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 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. +Als een onderwerp branch uiteindelijk is gemerged in `master`, dan wordt het verwijderd van het repository. Het Git project heeft ook een `main` branch, die geforked is van de laatste release om teruggewerkte (backported) patches te leveren in het geval dat een onderhoudsrelease nodig is. Dus als je de 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 beheerders hebben een gestructureerde werkwijze om ze te helpen nieuwe bijdragen aan de tand te voelen. #### Rebasen en cherry pick werkwijzen #### -Andere beheerders geven de voorkeur aan rebasen of bijgedragen werk te cherry picken bovenop hun master branch, in plaats van het er in samen te voegen, om een lineaire historie te behouden. Als je werk in een onderwerp branch hebt en hebt besloten dat je het wil integreren, dan ga je naar die branch en voert het rebase commando uit om de wijzigingen bovenop je huidige master branch te bouwen (of `develop`, enzovoorts). Als dat goed werkt, dan kun je je `master` branch fast-forwarden, en dan eindig je met een lineaire project historie. +Andere beheerders geven de voorkeur aan rebasen of bijgedragen werk te cherry picken naar hun master branch in plaats van ze erin te mergen, om een vrijwel lineaire historie te behouden. Als je werk in een topic branch hebt en hebt besloten dat je het wil integreren, dan ga je naar die branch en voert het rebase commando uit om de wijzigingen op je huidige master branch te baseren (of `develop`, enzovoorts). Als dat goed werkt, dan kun je de `master` branch fast-forwarden, en eindig je met een lineaire project historie. -De andere manier om gentroduceerd werk van de ene naar de andere branch te verplaatsen is om het te cherry picken. Een cherry-pick in Git is een soort rebase voor een enkele commit. Het pakt de patch die was gentroduceerd in een commit en probeert die opnieuw toe te passen op de branch waar je nu op zit. Dit is handig als je een aantal commits op een onderwerp branch hebt en je er slechts n van wilt integreren, of als je alleen n commit op een onderwerp branch hebt en er de voorkeur aan geeft om het te cherry-picken in plaats van rebase uit te voeren. Bijvoorbeeld, stel dat je een project hebt dat eruit ziet als Figuur 5-26. +De andere manier om gentroduceerd werk van de ene naar de andere branch te verplaatsen is om het te cherry picken. Een cherry-pick in Git is een soort rebase voor een enkele commit. Het pakt de patch die was gentroduceerd in een commit en probeert die weer toe te passen op de branch waar je nu op zit. Dit is handig als je een aantal commits op een topic branch hebt en je er slechts n van wilt integreren, of als je alleen n commit op een topic branch hebt en er de voorkeur aan geeft om het te cherry-picken in plaats van rebase uit te voeren. Bijvoorbeeld, stel dat je een project hebt dat eruit ziet als Figuur 5-26. Insert 18333fig0526.png Figuur 5-26. Voorbeeld historie voor een cherry pick. -Als je commit `e43a6` in je master branch wil halen, dan kun je dit uitvoeren +Als je commit `e43a6` in je master branch wilt pullen, dan kun je dit uitvoeren $ 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(-) -Dit haalt dezelfde wijziging binnen als gentroduceerd in `e43a6`, maar je krijgt een nieuwe SHA-1 waarde, omdat de gegevens op een andere manier toegepast zijn. Nu ziet je historie eruit als Figuur 5-27. +Dit pulled dezelfde wijziging zoals gentroduceerd in `e43a6`, maar je krijgt een nieuwe SHA-1 waarde, omdat de gegevens op een andere manier toegepast zijn. Nu ziet je historie eruit als Figuur 5-27. Insert 18333fig0527.png -Figuur 5-27. Historie na het cherry-picken van een commit op een onderwerp branch. +Figuur 5-27. Historie na het cherry-picken van een commit op een topic branch. -Nu kun je je onderwerp branch verwijderen en de commits die je niet wou binnenhalen weggooien. +Nu kun je de topic branch verwijderen en de commits die je niet wilde pullen weggooien. -### Je vrijgaven taggen ### +### Je releases taggen ### -Als je hebt besloten om een vrijgave te doen, zul je waarschijnlijk een tag willen aanmaken zodat je die vrijgave op ieder punt in de toekomst kunt namaken. Je kunt een nieuwe tag maken zoals ik heb beschreven in Hoofdstuk 2. Als je besluit om de tag als de beheerder te signeren, dan ziet het taggen er misschien zo uit: +Als je hebt besloten om een release te maken, zul je waarschijnlijk een tag willen aanmaken zodat je die release op elk moment in de toekomst kunt namaken. Je kunt een nieuwe tag maken zoals ik heb beschreven in Hoofdstuk 2. Als je besluit om de tag als de beheerder te signeren, dan ziet het taggen er misschien zo uit: $ 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 -Als je je tags signeert, dan heb je misschien een problem om de publieke PGP sleutel te distribueren, die gebruikt is om de tags te signeren. De beheerder van het Git project heeft dit probleem opgelost door hun publieke sleutel als een blob in het repository mee te nemen en dan een tag toe te voegen die direct naar die inhoud wijst. Om dit te doen kun je uitvinden welke sleutel je wilt door `gpg --list-keys` uit te voeren: +Als je tags signeert, dan heb je misschien een problem om de publieke PGP sleutel, die gebruikt is om de tags te signeren, te distribueren. De beheerder van het Git project heeft dit probleem opgelost door hun publieke sleutel als een blob in het repository mee te nemen en een tag te maken die direct naar die inhoud wijst. Om dit te doen kun je uitvinden welke sleutel je wilt door `gpg --list-keys` uit te voeren: $ gpg --list-keys /Users/schacon/.gnupg/pubring.gpg @@ -851,7 +851,7 @@ Als je je tags signeert, dan heb je misschien een problem om de publieke PGP sle uid Scott Chacon sub 2048g/45D02282 2009-02-09 [expires: 2010-02-09] -Daarna kun je de sleutel direct in de Git gegevensbank importeren, door het te exporteren en om te leiden door `git hash-object`, wat een nieuwe blob schrijft in Git met die inhoud en je de SHA-1 van de blob teruggeeft: +Daarna kun je de sleutel direct in de Git database importeren, door het te exporteren en te "pipen" naar `git hash-object`, wat een nieuwe blob schrijft in Git met die inhoud en je de SHA-1 van de blob teruggeeft: $ gpg -a --export F721C45A | git hash-object -w --stdin 659ef797d181633c87ec71ac3f9ba29fe5775b92 @@ -860,40 +860,40 @@ Nu dat je de inhoud van je sleutel in Git hebt, kun je een tag aanmaken die dire $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92 -Als je `git push --tags` uitvoert, zal de `maintainer-pgp-pub` tag met iedereen gedeeld worden. Als iemand een tag wil verifiren, dan kunnen ze je PGP sleutel direct importeren door de blob direct uit de gegevensbank te halen en het in GPG te importeren: +Als je `git push --tags` uitvoert, zal de `maintainer-pgp-pub` tag met iedereen gedeeld worden. Als iemand een tag wil verifiren, dan kunnen ze jouw PGP sleutel direct importeren door de blob direct uit de database te halen en het in GPG te importeren: $ git show maintainer-pgp-pub | gpg --import -Ze kunnen die sleutel gebruiken om als je gesigneerde tags te verifiren. Als je de instructies in het tag bericht zet, dan zal `git show ` je eindgebruikers meer specifieke instructies geven over tag verificatie. +Ze kunnen die sleutel gebruiken om al je gesigneerde tags te verifiren. Als je instructies in het tag bericht zet, dan zal `git show ` je eindgebruikers meer specifieke instructies geven over tag verificatie. ### Een bouw nummer genereren ### -Omdat Git geen monotone oplopende nummers heeft zoals 'v123' of iets gelijkwaardigs om bij iedere commit mee te gaan, zul je als je een voor mensen leesbare naam wilt hebben bij een commit, `git describe` kunnen uitvoeren op die commit. Git geeft je de naam van de dichtstbijzijnde tag met het aantal commits bovenop die dag en een gedeeltelijke SHA-1 waarde van de commit die je omschrijft: +Omdat Git geen monotone oplopende nummers heeft zoals 'v123' of iets gelijkwaardigs om bij iedere commit mee te worden genomen, en je een voor mensen leesbare naam wilt hebben bij een commit, kan je `git describe` uitvoeren op die commit. Git geeft je de naam van de dichtstbijzijnde tag met het aantal commits achter die tag en een gedeeltelijke SHA-1 waarde van de commit die je omschrijft: $ 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, 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. +Op deze manier kun je een snapshot of "build" exporteren en het vernoemen naar iets dat begrijpelijk is voor mensen. Sterker nog: als je Git, gekloond van het Git repository, vanaf broncode bouwt geeft `git --version` je iets dat er zo uitziet. Als je een commit omschrijft die je direct getagged hebt, dan krijg je de tag naam. -Het `git describe` commando heeft de voorkeur voor beschreven tags (tags gecreerd 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. +Het `git describe` commando geeft beschreven tags de voorkeur (tags gecreerd met de `-a` of `-s` vlag), dus release tags moeten op deze manier aangemaakt 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 ook gebruiken als het doel van een checkout of show commando, alhoewel het afhankelijk is van de verkorte SHA-1 waarde aan het einde, dus het zou niet eeuwig 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, oudere `git describe` commando's werden daardoor ongeldig. -### Een vrijgave voorbereiden ### +### Een release voorbereiden ### -Nu wil je een bouw vrijgeven. Een van de dingen die je wilt doen is een archief maken van het laatste snapshot van je code voor die arme zielen die geen Git gebruiken. Het commando om dit te doen is `git archive`: +Nu wil je een build vrijgeven. Een van de dingen die je wilt doen is een archief maken van de laatste snapshot van je code voor de arme stumperds die geen Git gebruiken. Het commando om dit te doen 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 -Als iemand die tarball opent, dan krijgen ze ze laatste snapshot van je project onder een project map. Je kunt op vrijwel dezelfde manier ook een zip archief maken, maar dan door de `format=zip` optie mee te geven aan `git archive`: +Als iemand die tarball opent, dan krijgen ze de laatste snapshot van je project onder een project directory. Je kunt op vrijwel dezelfde manier ook een zip archief maken, maar dan door de `format=zip` optie mee te geven aan `git archive`: $ git archive master --prefix='project/' --format=zip > `git describe master`.zip -Je hebt nu een fijne tarball en een zip archief van je project vrijgave, die je kunt uploaden naar je website of naar mensen kunt e-mailen. +Je hebt nu een mooie tarball en een zip archief van je project release, die je kunt uploaden naar je website of naar mensen kunt e-mailen. -### Het shortlog ### +### De shortlog ### -Het is tijd geworden om je maillijst van mensen die willen weten wat er gebeurt in je project te e-mailen. Een fijne manier om een soort van veranderingslog te krijgen van wat er is toegevoegd in je project sinds je laatste vrijgave of e-mail is om het `git shortlog` commando te gebruiken. Het vat alle commits samen in de reeks die je het geeft; bijvoorbeeld, het volgende geeft je een samenvatting van alle commits sinds je vorige vrijgave, als je laatste vrijgave v1.0.1 heette: +De tijd is gekomen om de maillijst met mensen die willen weten wat er gebeurt in je project te mailen. Een prettige manier om een soort van wijzigingsverslag te krijgen van wat er is toegevoegd in je project sinds je laatste release of e-mail is om het `git shortlog` commando te gebruiken. Het vat alle commits samen binnen de grenswaarden die je het geeft. Bijvoorbeeld het volgende geeft je een samenvatting van alle commits sinds je vorige release, als je laatste release v1.0.1 heette: $ git shortlog --no-merges master --not v1.0.1 Chris Wanstrath (8): @@ -910,8 +910,8 @@ Het is tijd geworden om je maillijst van mensen die willen weten wat er gebeurt Version bump to 1.0.2 Regenerated gemspec for version 1.0.2 -Je krijgt een schone samenvatting van alle commits sinds v1.0.1, gegroepeerd op auteur, die je naar je lijst kunt e-mailen. +Je krijgt een opgeschoonde samenvatting van alle commits sinds v1.0.1, gegroepeerd op auteur, die je naar de lijst kunt e-mailen. ## Samenvatting ## -Je moet je vrij gemakkelijk voelen om aan een project bij te kunnen dragen in Git, als ook om je eigen project te beheren of de bijdragen van andere gebruikers te integreren. Gefeliciteerd met het worden van een effectieve Git ontwikkelaar! In het volgende hoofdstuk zul je krachtigere applicaties en trucs leren voor het omgaan met complexe situaties, die je een echte Git meester zullen maken. +Je zou je nu redelijk op je gemak moeten voelen om aan een project bij te dragen met Git, maar ook om je eigen project te beheren of de bijdragen van andere gebruikers te integreren. Gefeliciteerd met het worden van een effectieve Git ontwikkelaar! In het volgende hoofdstuk zul je nog krachtigere tools en trucs leren voor het omgaan met complexe situaties, die je een echte Git meester zullen maken. From b8d3ef3ce77bc9e967bc1f5c3894594683863649 Mon Sep 17 00:00:00 2001 From: Matt Deacalion Stevens Date: Thu, 30 Jan 2014 01:25:41 -0700 Subject: [PATCH 137/690] Update command line output in Chapter 3.2 The command line output in the examples is from an older version of Git (1.7.*) and is slightly inconsistent with the latest version. --- en/03-git-branching/01-chapter3.markdown | 92 +++++++++++++----------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/en/03-git-branching/01-chapter3.markdown b/en/03-git-branching/01-chapter3.markdown index bf0028744..754006b6c 100644 --- a/en/03-git-branching/01-chapter3.markdown +++ b/en/03-git-branching/01-chapter3.markdown @@ -117,7 +117,7 @@ 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" + Switched to a new branch 'iss53' This is shorthand for: @@ -142,18 +142,18 @@ Now you get the call that there is an issue with the web site, and you need to f 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" + 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" + 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(-) + [hotfix 3a0874c] fixed the broken email address + 1 files changed, 1 deletion(-) Insert 18333fig0313.png Figure 3-13. hotfix branch based back at your master branch point. @@ -163,11 +163,11 @@ You can run your tests, make sure the hotfix is what you want, and merge it back $ git checkout master $ git merge hotfix Updating f42c576..3a0874c - Fast forward - README | 1 - - 1 files changed, 0 insertions(+), 1 deletions(-) + Fast-forward + README | 1 - + 1 file changed, 1 deletion(-) -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". +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). @@ -177,16 +177,16 @@ Figure 3-14. Your master branch points to the same place as your hotfix branch a 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). + Deleted branch hotfix (was 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" + 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(-) + [iss53 ad82d7a] finished the new footer [issue 53] + 1 file changed, 1 insertion(+) Insert 18333fig0315.png Figure 3-15. Your iss53 branch can move forward independently. @@ -199,9 +199,10 @@ Suppose you’ve decided that your issue #53 work is complete and ready to be me $ git checkout master $ git merge iss53 - Merge made by recursive. - README | 1 + - 1 files changed, 1 insertions(+), 0 deletions(-) + Auto-merging README + Merge made by the 'recursive' strategy. + README | 1 + + 1 file changed, 1 insertion(+) 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. @@ -230,25 +231,27 @@ Occasionally, this process doesn’t go smoothly. If you changed the same part o 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 - # + $ git status + On branch master + You have unmerged paths. + (fix conflicts and run "git commit") + + Unmerged paths: + (use "git add ..." to mark resolution) + + both modified: index.html + + no changes added to commit (use "git add" and/or "git commit -a") 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 + <<<<<<< HEAD ======= - >>>>>>> iss53:index.html + >>>>>>> iss53 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: @@ -260,12 +263,17 @@ This resolution has a little of each section, and I’ve fully removed the `<<<< 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 + + This message is displayed because 'merge.tool' is not configured. + See 'git mergetool --tool-help' or 'git help config' for more details. + 'git mergetool' will now attempt to use one of the following tools: + opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge + Merging: + index.html Normal merge conflict for 'index.html': - {local}: modified - {remote}: modified + {local}: modified file + {remote}: modified file 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. @@ -275,12 +283,12 @@ After you exit the merge tool, Git asks you if the merge was successful. If 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 - # + 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: @@ -289,9 +297,9 @@ If you’re happy with that, and you verify that everything that had conflicts h Conflicts: index.html # - # It looks like you may be committing a MERGE. + # It looks like you may be committing a merge. # If this is not correct, please remove the file - # .git/MERGE_HEAD + # .git/MERGE_HEAD # and try again. # @@ -440,7 +448,7 @@ To merge this work into your current working branch, you can run `git merge orig $ git checkout -b serverfix origin/serverfix Branch serverfix set up to track remote branch refs/remotes/origin/serverfix. - Switched to a new branch "serverfix" + Switched to a new branch 'serverfix' This gives you a local branch that you can work on that starts where `origin/serverfix` is. @@ -452,13 +460,13 @@ When you clone a repository, it generally automatically creates a `master` branc $ git checkout --track origin/serverfix Branch serverfix set up to track remote branch refs/remotes/origin/serverfix. - Switched to a new branch "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" + Switched to a new branch 'sf' Now, your local branch `sf` will automatically push to and pull from `origin/serverfix`. From d88a43da71fb28dba9a7ae623a94d8c8baa06565 Mon Sep 17 00:00:00 2001 From: Matt Deacalion Stevens Date: Thu, 30 Jan 2014 01:36:22 -0700 Subject: [PATCH 138/690] Update command line output in Chapter 3.3 The command line output in the examples is from an older version of Git (1.7.*) and is slightly inconsistent with the latest version. --- 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 754006b6c..484d957ec 100644 --- a/en/03-git-branching/01-chapter3.markdown +++ b/en/03-git-branching/01-chapter3.markdown @@ -339,7 +339,7 @@ To see all the branches that contain work you haven’t yet merged in, you can r 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. + error: The branch 'testing' is not fully merged. 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. From 37d443f64a7862c04099f0fb4efe4f78214983c7 Mon Sep 17 00:00:00 2001 From: Matt Deacalion Stevens Date: Thu, 30 Jan 2014 01:45:54 -0700 Subject: [PATCH 139/690] Update command line output in Chapter 3.5 The command line output in the examples is from an older version of Git (1.7.*) and is slightly inconsistent with the latest version. --- en/03-git-branching/01-chapter3.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/en/03-git-branching/01-chapter3.markdown b/en/03-git-branching/01-chapter3.markdown index 484d957ec..e8294da74 100644 --- a/en/03-git-branching/01-chapter3.markdown +++ b/en/03-git-branching/01-chapter3.markdown @@ -447,7 +447,7 @@ It’s important to note that when you do a fetch that brings down new remote br 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. + Branch serverfix set up to track remote branch serverfix from origin. Switched to a new branch 'serverfix' This gives you a local branch that you can work on that starts where `origin/serverfix` is. @@ -459,13 +459,13 @@ Checking out a local branch from a remote branch automatically creates what is c 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. + Branch serverfix set up to track remote branch serverfix from origin. 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. + Branch sf set up to track remote branch serverfix from origin. Switched to a new branch 'sf' Now, your local branch `sf` will automatically push to and pull from `origin/serverfix`. From 1f4e6e2052093fa15d2fe64a4360485a6da66f37 Mon Sep 17 00:00:00 2001 From: Zack Date: Thu, 30 Jan 2014 16:58:52 +0100 Subject: [PATCH 140/690] [fr] Update 01-chapter2.markdown Change "le liste" to "la liste" --- fr/02-git-basics/01-chapter2.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fr/02-git-basics/01-chapter2.markdown b/fr/02-git-basics/01-chapter2.markdown index 8f1fe37c6..1ed5f012e 100644 --- a/fr/02-git-basics/01-chapter2.markdown +++ b/fr/02-git-basics/01-chapter2.markdown @@ -1000,7 +1000,7 @@ Si vous lancez cette commande avec un nom court particulier, tel que `origin`, v ticgit -Cela donne le liste des URL pour le dépôt distant ainsi que la liste des branches distantes suivies. +Cela donne la liste des URL pour le dépôt distant ainsi que la liste des branches distantes suivies. Cette commande vous informe que si vous êtes sur la branche `master` et si vous lancez `git pull`, il va automatiquement fusionner la branche `master` du dépôt distant après avoir récupéré toutes les références sur le serveur distant. Cela donne aussi la liste des autres références qu'il aura tirées. From bfc5f0ab83b5f6c36492cdcc48c007838fe513bf Mon Sep 17 00:00:00 2001 From: Cor Date: Fri, 31 Jan 2014 08:30:31 +0100 Subject: [PATCH 141/690] [nl] Repair the mangled diacritics. --- nl/05-distributed-git/01-chapter5.markdown | 82 +++++++++++----------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/nl/05-distributed-git/01-chapter5.markdown b/nl/05-distributed-git/01-chapter5.markdown index d84874a81..25c320dc3 100644 --- a/nl/05-distributed-git/01-chapter5.markdown +++ b/nl/05-distributed-git/01-chapter5.markdown @@ -10,7 +10,7 @@ In tegenstelling tot gecentraliseerde versiebeheersystemen (CVCSen), stelt de ge ### Gecentraliseerde werkwijze ### -In gecentraliseerde systemen is er over het algemeen een enkel samenwerkingsmodel - de gecentraliseerde werkwijze. En centraal punt, of repository, kan code aanvaarden, en iedereen synchroniseert zijn werk daarmee. Een aantal ontwikkelaars zijn knopen - gebruikers van dat centrale punt - en synchroniseren met die plaats (zie Figuur 5-1). +In gecentraliseerde systemen is er over het algemeen een enkel samenwerkingsmodel - de gecentraliseerde werkwijze. Eén centraal punt, of repository, kan code aanvaarden, en iedereen synchroniseert zijn werk daarmee. Een aantal ontwikkelaars zijn knopen - gebruikers van dat centrale punt - en synchroniseren met die plaats (zie Figuur 5-1). Insert 18333fig0501.png Figuur 5-1. Gecentraliseerde Werkwijze. @@ -22,7 +22,7 @@ Deze werkwijze is voor een hoop mensen aantrekkelijk omdat het er een is waarmee ### 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 (canonical) repository dat het "officile" 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 (pull request). Hij kan je repository toevoegen als een remote, je wijzigingen lokaal testen, ze in zijn branch mergen, 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 (canonical) 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 (pull request). Hij kan je repository toevoegen als een remote, je wijzigingen lokaal testen, ze in zijn branch mergen, en naar zijn repository terugzetten. Het proces werkt als volgt (zie Figuur 5-2): 1. De projecteigenaar pushed naar de publieke repository. 2. Een bijdrager kloont die repository en maakt wijzigingen. @@ -38,7 +38,7 @@ Dit is een veel voorkomende werkwijze bij websites zoals GitHub, waarbij het een ### Dictator en luitenanten werkwijze ### -Dit is een variant op de multi-repository werkwijze. Het wordt over het algemeen gebruikt bij enorme grote projecten met honderden bijdragers; een bekend voorbeeld is de Linux-kernel. Een aantal integrators geven de leiding over bepaalde delen van het repository, zij worden luitenanten genoemd. Alle luitenanten hebben n integrator die bekend staat als de welwillende dictator. De repository van de welwillende dictator dient als het referentierepository vanwaar alle bijdragers dienen binnen te halen. Het proces werkt als volgt (zie Figuur 5-3): +Dit is een variant op de multi-repository werkwijze. Het wordt over het algemeen gebruikt bij enorme grote projecten met honderden bijdragers; een bekend voorbeeld is de Linux-kernel. Een aantal integrators geven de leiding over bepaalde delen van het repository, zij worden luitenanten genoemd. Alle luitenanten hebben één integrator die bekend staat als de welwillende dictator. De repository van de welwillende dictator dient als het referentierepository vanwaar alle bijdragers dienen binnen te halen. Het proces werkt als volgt (zie Figuur 5-3): 1. Reguliere ontwikkelaars werken op hun eigen onderwerp (topic) branch en rebasen hun werk op de master. De masterbranch is die van de dictator. 2. Luitenanten mergen de topic branches van de ontwikkelaars in hun masterbranch. @@ -48,7 +48,7 @@ Dit is een variant op de multi-repository werkwijze. Het wordt over het algemeen Insert 18333fig0503.png Figuur 5-3. Welwillende-dictatorwerkwijze. -Deze manier van werken is niet gewoon, maar kan handig zijn in hele grote projecten of in zeer hirarchische omgevingen, omdat het de projectleider (de dictator) in staat stelt om het meeste werk te delegeren en grote subsets van code te verzamelen op meerdere punten alvorens ze te integreren. +Deze manier van werken is niet gewoon, maar kan handig zijn in hele grote projecten of in zeer hiërarchische omgevingen, omdat het de projectleider (de dictator) in staat stelt om het meeste werk te delegeren en grote subsets van code te verzamelen op meerdere punten alvorens ze te integreren. Dit zijn veel voorkomende werkwijzen die mogelijk zijn met een gedistribueerd systeem als Git, maar je kunt zien dat er veel variaties mogelijk zijn om ze te laten passen bij jouw specifieke werkwijze. Nu dat je (naar ik hoop) in staat bent om te bepalen welke combinatie van werkwijzen voor jou werkt, zal ik wat specifiekere voorbeelden behandelen over hoe je de belangrijkste rollen kunt vervullen, die in de verschillende werkwijzen voorkomen. @@ -82,7 +82,7 @@ Als eerste wil je geen witruimte fouten indienen. Git geeft je een eenvoudige ma Als je dat commando uitvoert alvorens te committen, kun je al zien of je op het punt staat witruimte problemen te committen die waaraan andere ontwikkelaars zich zullen ergeren. -Probeer vervolgens om van elke commit een logische set wijzigingen te maken. Probeer, als het je lukt, om je wijzigingen verteerbaar te maken - ga niet het hele weekend zitten coderen op vijf verschillende problemen om dat vervolgens op maandag als een gigantische commit in te dienen. Zelfs als je gedurende het weekend niet commit, gebruik dan het staging gebied op maandag om je werk in ten minste n commit per probleem op te splitsen, met een bruikbaar bericht per commit. Als een paar van de wijzigingen n bestand veranderen, probeer dan `git add --patch` te gebruiken om bestanden gedeeltelijk te stagen (wordt in detail behandeld in Hoofdstuk 6). De laatste snapshot van het project is gelijk of je nu n commit doet of vijf, zolang alle wijzigingen op een gegeven momment maar toegevoegd zijn, dus probeer om het je mede-ontwikkelaars makkelijk te maken als ze je wijzigingen moeten bekijken. Deze aanpak maakt het ook makkelijker om n wijziging te pullen of terug te draaien, mocht dat later nodig zijn. Hoofdstuk 6 beschrijft een aantal handige Git trucs om geschiedenis te herschrijven en bestanden interactief te stagen - gebruik deze gereedschappen een schone en begrijpelijke historie te helpen op te bouwen. +Probeer vervolgens om van elke commit een logische set wijzigingen te maken. Probeer, als het je lukt, om je wijzigingen verteerbaar te maken - ga niet het hele weekend zitten coderen op vijf verschillende problemen om dat vervolgens op maandag als een gigantische commit in te dienen. Zelfs als je gedurende het weekend niet commit, gebruik dan het staging gebied op maandag om je werk in ten minste één commit per probleem op te splitsen, met een bruikbaar bericht per commit. Als een paar van de wijzigingen één bestand veranderen, probeer dan `git add --patch` te gebruiken om bestanden gedeeltelijk te stagen (wordt in detail behandeld in Hoofdstuk 6). De laatste snapshot van het project is gelijk of je nu één commit doet of vijf, zolang alle wijzigingen op een gegeven momment maar toegevoegd zijn, dus probeer om het je mede-ontwikkelaars makkelijk te maken als ze je wijzigingen moeten bekijken. Deze aanpak maakt het ook makkelijker om één wijziging te pullen of terug te draaien, mocht dat later nodig zijn. Hoofdstuk 6 beschrijft een aantal handige Git trucs om geschiedenis te herschrijven en bestanden interactief te stagen - gebruik deze gereedschappen een schone en begrijpelijke historie te helpen op te bouwen. Het laatste om in gedachten te houden is het commit bericht. Als je er een gewoonte van maakt om een goede kwaliteit commit berichten aan te maken, dan maakt dat het gebruik van en samenwerken in Git een stuk eenvoudiger. In het algemeen, zouden je berichten moeten beginnen met een enkele regel, die niet langer is dan 50 karakters en die de wijzigingen beknopt omschrijft, gevolgd door een lege regel en daarna een meer gedetailleerde uitleg. Het Git project vereist dat de meer gedetailleerde omschrijving ook je motivatie voor de verandering bevat, en de nieuwe implementatie tegen het oude gedrag afzet. Dit is een goede richtlijn om te volgen. Het is ook een goed idee om de gebiedende wijs te gebruiken in deze berichten. Met andere woorden, gebruik commando's. In plaats van "Ik heb testen toegevoegd voor" of "Testen toegevoegd voor" gebruik je "Voeg testen toe voor". Hier is een sjabloon dat origineel geschreven is door Tim Pope op tpope.net: @@ -103,7 +103,7 @@ Hier is een sjabloon dat origineel geschreven is door Tim Pope op tpope.net: - Typisch wordt een streepje of sterretje gebruikt als "bullet", voorafgegaan door een enkele spatie, met ertussen lege regels, - maar de conventies variren hierin. + maar de conventies variëren hierin. Als al je commit berichten er zo uit zien, dan zullen de dingen een stuk eenvoudiger zijn voor jou en de ontwikkelaars waar je mee samenwerkt. Het Git project heeft goed geformatteerde commit berichten - ik raad je aan om `git log --no-merges` uit te voeren om te zien hoe een goed geformatteerde project-commit historie eruit ziet. @@ -111,7 +111,7 @@ In de volgende voorbeelden, en verder door de rest van dit boek, zal ik omwille ### Besloten klein team ### -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 push toegang op het repository. +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 push 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 mergen, maar de werkwijze kan erg vergelijkbaar zijn. Het grote verschil is dat het mergen 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, kloont de repository, maakt een wijziging, en commit lokaal. (Ik vervang de protocol berichten met `...` in deze voorbeelden om ze iets in te korten.) @@ -154,7 +154,7 @@ John probeert ook zijn werk te pushen: ! [rejected] master -> master (non-fast forward) error: failed to push some refs to 'john@githost:simplegit.git' -John mag niet terugzetten omdat Jessica in de tussentijd gepushed heeft. Dit is belangrijk om te begrijpen als je gewoon bent aan Subversion, omdat het je zal opvallen dat de twee ontwikkelaars niet hetzelfde bestand hebben aangepast. Waar Subversion automatisch zo'n merge op de server doet, als verschillende bestanden zijn aangepast, moet je in Git de commits lokaal mergen. John moet Jessica's wijzigingen ophalen (fetch) en ze mergen voor hij mag pushen: +John mag niet pushen omdat Jessica in de tussentijd gepushed heeft. Dit is belangrijk om te begrijpen als je gewend bent aan Subversion, omdat het je zal opvallen dat de twee ontwikkelaars niet hetzelfde bestand hebben aangepast. Waar Subversion automatisch zo'n merge op de server doet, als verschillende bestanden zijn aangepast, moet je in Git de commits lokaal mergen. John moet Jessica's wijzigingen ophalen (fetch) en ze mergen voor hij mag pushen: $ git fetch origin ... @@ -164,7 +164,7 @@ John mag niet terugzetten omdat Jessica in de tussentijd gepushed heeft. Dit is Hierna ziet John's lokale repository er ongeveer uit zoals Figuur 5-4. Insert 18333fig0504.png -Figuur 5-4. John's initile repository. +Figuur 5-4. John's initiële repository. John heeft een referentie naar de wijzigingen die Jessica gepushed heeft, maar hij moet ze mergen met zijn eigen werk voordat hij het mag pushen: @@ -173,12 +173,12 @@ John heeft een referentie naar de wijzigingen die Jessica gepushed heeft, maar h TODO | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) -Het samenvoegen gaat soepeltjes - de commit historie van John ziet er nu uit als Figuur 5-5. +Het mergen gaat soepeltjes - de commit historie van John ziet er nu uit als Figuur 5-5. Insert 18333fig0505.png -Figuur 5-5. John's repository na het samenvoegen van origin/master. +Figuur 5-5. John's repository na het mergen van origin/master. -Nu kan John zijn code testen om er zeker van te zijn dat het nog steeds goed werkt, en dan kan hij zijn nieuwe samengevoegde werk pushen naar de server: +Nu kan John zijn code testen om er zeker van te zijn dat het nog steeds goed werkt, en dan kan hij zijn nieuwe gemergede werk pushen naar de server: $ git push origin master ... @@ -193,7 +193,7 @@ Figuur 5-6. John's historie na gepushed te hebben naar de origin van de server. In de tussentijd heeft Jessica gewerkt op een topic branch. Ze heeft een topic branch genaamd `issue54` aangemaakt en daar drie commits op gedaan. Ze heeft John's wijzigingen nog niet opgehaald, dus haar commit historie ziet er uit als Figuur 5-7. Insert 18333fig0507.png -Figuur 5-7. Jessica's initile commit historie. +Figuur 5-7. Jessica's initiële commit historie. Jessica wil met John synchroniseren, dus ze haalt de wijzigingen op: @@ -257,16 +257,16 @@ Iedere ontwikkelaar heeft een paar keer gecommit en elkaars werk succesvol samen Insert 18333fig0510.png Figuur 5-10. Jessica's historie na alle wijzigingen teruggezet te hebben op de server. -Dit is n van de eenvoudigste werkwijzen. Je werkt een tijdje, over het algemeen in een topic branch, en merged in je `master` branch als het klaar is om te worden gentegreerd. Als je dat werk wilt delen, dan merge je het in je eigen `master` branch, en vervolgens fetch je `origin/master` en merge je deze als het gewijzigd is, en als laatste push je deze naar de `master` branch op de server. De algemene volgorde is zoiets als die getoond in Figuur 5-11. +Dit is één van de eenvoudigste werkwijzen. Je werkt een tijdje, over het algemeen in een topic branch, en merged in je `master` branch als het klaar is om te worden geïntegreerd. Als je dat werk wilt delen, dan merge je het in je eigen `master` branch, en vervolgens fetch je `origin/master` en merge je deze als het gewijzigd is, en als laatste push je deze naar de `master` branch op de server. De algemene volgorde is zoiets als die getoond in Figuur 5-11. Insert 18333fig0511.png Figuur 5-11. Algemene volgorde van gebeurtenissen voor een eenvoudige multi-ontwikkelaar Git werkwijze. ### Besloten aangestuurd team ### -In het volgende scenario zul je kijken naar de rol van de bijdragers in een grotere besloten groep. Je zult leren hoe te werken in een omgeving waar kleine groepen samenwerken aan functies, waarna die team-gebaseerde bijdragen worden gentegreerd door een andere partij. +In het volgende scenario zul je kijken naar de rol van de bijdragers in een grotere besloten groep. Je zult leren hoe te werken in een omgeving waar kleine groepen samenwerken aan functies, waarna die team-gebaseerde bijdragen worden ge�ntegreerd door een andere partij. -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 gentegreerd door bepaalde ontwikkelaars, en de `master` branch van het hoofd repo alleen kan worden vernieuwd door die ontwikkelaars. In dit scenario wordt al het werk gedaan in team-gebaseerde branches en later door de integrators samengevoegd. +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 ontwikkelaars, en de `master` branch van het hoofd repo alleen kan worden vernieuwd door die ontwikkelaars. 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 verschillende ontwikkelaars in deze omgeving. We nemen even aand dat ze haar repository al gekloond heeft, en dat ze besloten heeft als eerste te werken aan `featureA`. Ze maakt een nieuwe branch aan voor de functie en doet daar wat werk: @@ -306,7 +306,7 @@ Nu doet Jessica een paar commits op de `featureB` branch: Jessica's repository ziet eruit als Figuur 5-12. Insert 18333fig0512.png -Figuur 5-12. Jessica's initile commit historie. +Figuur 5-12. Jessica's initiële commit historie. Ze is klaar om haar werk te pushen, maar ze krijgt een mail van Josie dat een branch met wat initieel werk erin al gepushed is naar de server in de `featureBee` branch. Jessica moet die wijzigingen eerst mergen met die van haar voordat ze kan pushen naar de server. Ze kan dan Josie's wijzigingen ophalen met `git fetch`: @@ -332,7 +332,7 @@ Er is wel een klein probleempje - ze moet het gemergde werk in haar `featureB` b Dit wordt een _refspec_ genoemd. Zie Hoofdstuk 9 voor een gedetailleerdere behandeling van Git refspecs en de verschillende dingen die je daarmee kan doen. -Vervolgens mailt John naar Jessica om te zeggen dat hij wat wijzigingen naar de `featureA` branch gepushed heeft, en om haar te vragen die te verifiren. Ze voert een `git fetch` uit om die wijzigingen op te halen: +Vervolgens mailt John naar Jessica om te zeggen dat hij wat wijzigingen naar de `featureA` branch gepushed heeft, en om haar te vragen die te verifiëren. Ze voert een `git fetch` uit om die wijzigingen op te halen: $ git fetch origin ... @@ -373,7 +373,7 @@ Jessica's commit historie ziet er nu uit zoals Figuur 5-13. Insert 18333fig0513.png Figuur 5-13. Jessica's historie na het committen op een functie branch. -Jessica, Josie en John informeren de integrators nu dat de `featureA` en `featureBee` branches op de server klaar zijn voor integratie in de hoofdlijn. Nadat zij die branches in de hoofdlijn gentegreerd hebben, zal een fetch de nieuwe merge commits ophalen, waardoor de commit historie er uit ziet zoals Figuur 5-14. +Jessica, Josie en John informeren de integrators nu dat de `featureA` en `featureBee` branches op de server klaar zijn voor integratie in de hoofdlijn. Nadat zij die branches in de hoofdlijn ge�ntegreerd hebben, zal een fetch de nieuwe merge commits ophalen, waardoor de commit historie er uit ziet zoals Figuur 5-14. Insert 18333fig0514.png @@ -398,7 +398,7 @@ Eerst zal je waarschijnlijk de hoofdrepository klonen, een topic branch maken vo $ (work) $ git commit -Je kunt eventueel besluiten `rebase -i` te gebruiken om je werk in n enkele commit samen te persen (squash), of het werk in de commits te herschikken om de patch eenvoudiger te kunnen laten reviewen door de beheerders - zie Hoofdstuk 6 voor meer informatie over het interactief rebasen. +Je kunt eventueel besluiten `rebase -i` te gebruiken om je werk in één enkele commit samen te persen (squash), of het werk in de commits te herschikken om de patch eenvoudiger te kunnen laten reviewen door de beheerders - zie Hoofdstuk 6 voor meer informatie over het interactief rebasen. Als je werk op de branch af is, en je klaar bent om het over te dragen aan de beheerders, ga je naar de originele project pagina en klik op de "Fork" knop. Hiermee maak je een eigen overschrijfbare fork van het project. Je moet de URL van deze nieuwe repository URL toevoegen als een tweede remote, in dit geval `myfork` genaamd: @@ -439,10 +439,10 @@ Bij een project waarvan je niet de beheerder bent, is het over het algemeen eenv $ (email maintainer) $ git fetch origin -Nu zijn al je onderwerpen opgeslagen in een silo - vergelijkbaar met een patch reeks (queue) - die je kunt herschrijven, rebasen en wijzigen zonder dat de onderwerpen elkaar benvloeden of van elkaar afhankelijk zijn zoals in Figuur 5-16. +Nu zijn al je onderwerpen opgeslagen in een silo - vergelijkbaar met een patch reeks (queue) - die je kunt herschrijven, rebasen en wijzigen zonder dat de onderwerpen elkaar be�nvloeden of van elkaar afhankelijk zijn zoals in Figuur 5-16. Insert 18333fig0516.png -Figuur 5-16. Initile commit historie met werk van featureB. +Figuur 5-16. Initiële commit historie met werk van featureB. Stel dat de project beheerder een verzameling andere patches binnengehaald heeft en jouw eerste branch geprobeerd heeft, maar dat die niet meer netjes merged. In dat geval kun je proberen die branch te rebasen op de punt van `origin/master`, de conflicten op te lossen voor de beheerder, en dan je wijzigingen opnieuw aanbieden: @@ -465,7 +465,7 @@ Laten we eens kijken naar nog een mogelijk scenario: de beheerder heeft je werk $ git commit $ git push myfork featureBv2 -De `--squash` optie pakt al het werk op de gemergde branch en perst dat samen in n non-merge commit bovenop de branch waar je op zit. De `--no-commit` optie vertelt Git dat hij niet automatisch een commit moet doen. Dit stelt je in staat om alle wijzigingen van een andere branch te introduceren en dan meer wijzigingen te doen, alvorens de nieuwe commit te doen. +De `--squash` optie pakt al het werk op de gemergde branch en perst dat samen in één non-merge commit bovenop de branch waar je op zit. De `--no-commit` optie vertelt Git dat hij niet automatisch een commit moet doen. Dit stelt je in staat om alle wijzigingen van een andere branch te introduceren en dan meer wijzigingen te doen, alvorens de nieuwe commit te doen. Nu kun je de beheerder een bericht sturen dat je de gevraagde wijzigingen gemaakt hebt en dat ze die wijzigingen kunnen vinden in je `featureBv2` branch (zie Figuur 5-18). @@ -484,7 +484,7 @@ De werkwijze is vergelijkbaar met het vorige geval - je maakt topic branches voo $ (work) $ git commit -Nu heb je twee commits die je wil sturen naar de maillijst. Je gebruikt `git format-patch` om de mbox-geformatteerde bestanden te genereren die je kunt mailen naar de lijst. Dit vormt iedere commit om naar een e-mail bericht met de eerste regel van het commit bericht als de onderwerp regel, en de rest van het bericht plus de patch die door de commit wordt gentroduceerd als de inhoud. Het prettige hieraan is dat met het toepassen van een patch uit een mail die gegenereerd is met `format-patch` alle commit informatie blijft behouden. In de volgende paragraaf zal je hiervan meer zien, als je deze commits gaat toepassen: +Nu heb je twee commits die je wil sturen naar de maillijst. Je gebruikt `git format-patch` om de mbox-geformatteerde bestanden te genereren die je kunt mailen naar de lijst. Dit vormt iedere commit om naar een e-mail bericht met de eerste regel van het commit bericht als de onderwerp regel, en de rest van het bericht plus de patch die door de commit wordt ge�ntroduceerd als de inhoud. Het prettige hieraan is dat met het toepassen van een patch uit een mail die gegenereerd is met `format-patch` alle commit informatie blijft behouden. In de volgende paragraaf zal je hiervan meer zien, als je deze commits gaat toepassen: $ git format-patch -M origin/master 0001-add-limit-to-log-function.patch @@ -583,7 +583,7 @@ Dan spuuwt Git een bergje log-informatie uit voor elke patch die je stuurt, wat ### Samenvatting ### -In dit hoofdstuk is een aantal veel voorkomende werkwijzen behandeld, die je kunt gebruiken om te kunnen werken in een aantal zeer verschillende typen Git projecten die je misschien zult tegenkomen, en een aantal nieuwe gereedschappen gentroduceerd die je helpen om dit proces te beheren. Wat hierna volgt zal je laten zien hoe je aan de andere kant van de tafel werkt: een Git project beheren. Je zult leren hoe een welwillende dictator of integratie manager te zijn. +In dit hoofdstuk is een aantal veel voorkomende werkwijzen behandeld, die je kunt gebruiken om te kunnen werken in een aantal zeer verschillende typen Git projecten die je misschien zult tegenkomen, en een aantal nieuwe gereedschappen geïntroduceerd die je helpen om dit proces te beheren. Wat hierna volgt zal je laten zien hoe je aan de andere kant van de tafel werkt: een Git project beheren. Je zult leren hoe een welwillende dictator of integratie manager te zijn. ## Het beheren van een project ## @@ -612,7 +612,7 @@ Als je de patch ontvangen hebt van iemand die het gegenereerd heeft met de `git $ git apply /tmp/patch-ruby-client.patch -Dit wijzigt de bestanden in je werk directory. Het is vrijwel gelijk aan het uitvoeren van een `patch -p1` commando om de patch toe te passen, alhoewel het meer paranode is en minder "fuzzy matches" accepteert dan patch. Het handelt ook bestandstoevoegingen af, -verwijderingen, en hernoemingen als ze beschreven staan in het `git diff` formaat, wat `patch` niet doet. Als laatste volgt `git apply` een "pas alles toe of laat alles weg" model waarbij alles of niets wordt toegepast. Dit in tegenstelling tot `patch` die gedeeltelijke patches kan toepassen, waardoor je werk directory in een vreemde status achterblijft. Over het algemeen is `git apply` meer paranode dan `patch`. Het zal geen commit voor je aanmaken; na het uitvoeren moet je de gentroduceerde wijzigingen handmatig stagen en committen. +Dit wijzigt de bestanden in je werk directory. Het is vrijwel gelijk aan het uitvoeren van een `patch -p1` commando om de patch toe te passen, alhoewel het meer paranoïde is en minder "fuzzy matches" accepteert dan patch. Het handelt ook bestandstoevoegingen af, -verwijderingen, en hernoemingen als ze beschreven staan in het `git diff` formaat, wat `patch` niet doet. Als laatste volgt `git apply` een "pas alles toe of laat alles weg" model waarbij alles of niets wordt toegepast. Dit in tegenstelling tot `patch` die gedeeltelijke patches kan toepassen, waardoor je werk directory in een vreemde status achterblijft. Over het algemeen is `git apply` meer paranoïde dan `patch`. Het zal geen commit voor je aanmaken; na het uitvoeren moet je de geïntroduceerde wijzigingen handmatig stagen en committen. Je kunt ook git apply gebruiken om te zien of een patch netjes kan worden toepast voordat je het echt doet; je kunt `git apply --check` uitvoeren met de patch: @@ -626,7 +626,7 @@ Als er geen uitvoer is, dan zou de patch netjes moeten passen. Dit commando reto Als de bijdrager een Git gebruiker is en zo vriendelijk is geweest om het `format-patch` commando te gebruiken om de patch te genereren, dan is je werk eenvoudiger omdat de patch de auteur informatie en een commit bericht voor je bevat. Als het enigzins kan, probeer dan je bijdragers aan te moedigen om `format-patch` te gebruiken in plaats van `diff` om patches te genereren voor je. Je zou alleen `git apply` willen hoeven te gebruiken voor oude patches en dat soort dingen. -Om een patch gegenereerd met `format-patch` toe te passen, gebruik je `git am`. Technisch is `git am` gemaakt om een mbox bestand te lezen, dat een eenvoudig gewone platte tekstformaat is om n of meer e-mail berichten in een tekstbestand op te slaan. Het ziet er ongeveer zo uit: +Om een patch gegenereerd met `format-patch` toe te passen, gebruik je `git am`. Technisch is `git am` gemaakt om een mbox bestand te lezen, dat een eenvoudig gewone platte tekstformaat is om één of meer e-mail berichten in een tekstbestand op te slaan. Het ziet er ongeveer zo uit: From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith @@ -635,9 +635,9 @@ Om een patch gegenereerd met `format-patch` toe te passen, gebruik je `git am`. Limit log functionality to the first 20 -Dit is het begin van de uitvoer van het format-patch commando dat je gezien hebt in de vorige paragraaf. Dit is ook een geldig mbox e-mail formaat. Als iemand jou de patch correct gemaild heeft door gebruik te maken van git send-email en je downloadt dat in een mbox formaat, dan kan je het git am naar dat mbox bestand verwijzen, en het zal beginnen met alle patches die het tegenkomt toe te passen. Als je een mail client gebruikt die meerdere e-mails kan opslaan in mbox formaat, dan kun je hele reeksen patches in een bestand opslaan en dan git am gebruiken om ze n voor n toe te passen. +Dit is het begin van de uitvoer van het format-patch commando dat je gezien hebt in de vorige paragraaf. Dit is ook een geldig mbox e-mail formaat. Als iemand jou de patch correct gemaild heeft door gebruik te maken van git send-email en je downloadt dat in een mbox formaat, dan kan je het git am naar dat mbox bestand verwijzen, en het zal beginnen met alle patches die het tegenkomt toe te passen. Als je een mail client gebruikt die meerdere e-mails kan opslaan in mbox formaat, dan kun je hele reeksen patches in een bestand opslaan en dan git am gebruiken om ze één voor één toe te passen. -Maar, als iemand een patch bestand heeft gepload die gegenereerd is met `format-patch` naar een ticket systeem of zoiets, kun je het bestand lokaal opslaan en dan dat opgeslagen bestand aan `git am` doorgeven om het toe te passen: +Maar, als iemand een patch bestand heeft ge�pload die gegenereerd is met `format-patch` naar een ticket systeem of zoiets, kun je het bestand lokaal opslaan en dan dat opgeslagen bestand aan `git am` doorgeven om het toe te passen: $ git am 0001-limit-log-function.patch Applying: add limit to log function @@ -723,7 +723,7 @@ Als je maar af en toe met een persoon werkt, maar toch op deze manier van hen wi * branch HEAD -> FETCH_HEAD Merge made by recursive. -### Bepalen wat gentroduceerd wordt ### +### Bepalen wat geïntroduceerd wordt ### Je hebt een topic branch dat bijgedragen werk bevat. Nu kan je bepalen wat je er mee wilt doen. Deze paragraaf bekijkt een paar commando's nogmaals om te laten zien hoe je ze kunt gebruiken om precies te reviewen wat je zult introduceren als je dit merged in je hoofd branch. @@ -742,7 +742,7 @@ Het is vaak handig om een review te krijgen van alle commits die in deze branch updated the gemspec to hopefully work better -Om te zien welke wijzigingen door iedere commit worden gentroduceert, onthoud dan dat je de `-p` optie kunt meegeven aan `git log` en dan zal het de diff weergeven die bij iedere commit wordt gentroduceerd. +Om te zien welke wijzigingen door iedere commit worden geïntroduceerd, onthoud dan dat je de `-p` optie kunt meegeven aan `git log` en dan zal het de diff weergeven die bij iedere commit wordt geïntroduceerd. Om een volledige diff te zien van wat zou gebeuren als je deze topic branch merged met een andere branch, zul je misschien een vreemde truc moeten toepassen om de juiste resultaten te krijgen. Je zult misschien denken om dit uit te voeren: @@ -764,11 +764,11 @@ Maar, dat is niet handig, dus levert Git een andere verkorte manier om hetzelfde $ git diff master...contrib -Dit commando laat alleen het werk zien dat je huidige topic branch heeft gentroduceerd sinds de gezamenlijke voorouder met master. Dat is een erg handige syntax om te onthouden. +Dit commando laat alleen het werk zien dat je huidige topic branch heeft ge�ntroduceerd sinds de gezamenlijke voorouder met master. Dat is een erg handige syntax om te onthouden. ### Bijgedragen werk integreren ### -Als al het werk in je onderwerp branch klaar is om te worden gentegreerd in een hogere branch, dan is de vraag hoe het te doen. En daarnaast, welke werkwijze wil je gebruiken om je project te beheren? Je hebt een aantal keuzes, dus ik zal er een paar behandelen. +Als al het werk in je onderwerp branch klaar is om te worden geïntegreerd in een hogere branch, dan is de vraag hoe het te doen. En daarbij, welke werkwijze wil je gebruiken om je project te beheren? Je hebt een aantal keuzes, dus ik zal er een paar behandelen. #### Merge werkwijzen #### @@ -782,7 +782,7 @@ Figuur 5-20. Na het mergen van een topic branch. Dat is waarschijnlijk de eenvoudigste werkwijze, maar het wordt problematisch als je werkt met grotere repositories of projecten. -Als je meer ontwikkelaars hebt of een groter project, dan zul je waarschijnlijk minstens een twee-fasen merge cyclus willen toepassen. In dat geval heb je twee langlopende branches, `master` en `develop`, waarbij je bepaalt dat `master` alleen vernieuwd wordt als een zeer stabiele release is gemaakt en alle nieuwe code gentegreerd is in de `develop` branch. Je pushed beide branches op regelmatige basis naar de publieke repository. Iedere keer als je een nieuw topic branch hebt om te mergen (Figuur 5-21), merge je het in `develop` (Figuur 5-22). En als je een tag gemaakt heb van een release, doe je een fast-forward van `master` naar waar de nu stabiele `develop` branch is (Figuur 5-23). +Als je meer ontwikkelaars hebt of een groter project, dan zul je waarschijnlijk minstens een twee-fasen merge cyclus willen toepassen. In dat geval heb je twee langlopende branches, `master` en `develop`, waarbij je bepaalt dat `master` alleen vernieuwd wordt als een zeer stabiele release is gemaakt en alle nieuwe code geïntegreerd is in de `develop` branch. Je pushed beide branches op regelmatige basis naar de publieke repository. Iedere keer als je een nieuw topic branch hebt om te mergen (Figuur 5-21), merge je het in `develop` (Figuur 5-22). En als je een tag gemaakt heb van een release, doe je een fast-forward van `master` naar waar de nu stabiele `develop` branch is (Figuur 5-23). Insert 18333fig0521.png Figuur 5-21. Voor een merge van een topic branch. @@ -798,7 +798,7 @@ Je kunt dit concept ook verder doorvoeren, waarbij je een integratie branch hebt #### Werkwijzen met grote merges #### -Het Git project heeft vier langlopende branches: `master`, `next`, en `pu` (proposed updates, voorgestelde vernieuwingen) voor nieuw spul, en `maint` voor onderhoudswerk. Als nieuw werk wordt gentroduceerd door bijdragers, wordt het samengeraapt in topic branches in de repository van de beheerder op een manier die lijkt op wat ik omschreven heb (zie Figuur 5-24). Hier worden de topics gevalueerd om te bepalen of ze veilig zijn en klaar voor verdere verwerking of dat ze nog wat werk nodig hebben. Als ze veilig zijn, worden ze in `next` gemerged, en wordt die branch gepushed zodat iedereen de gentegreerde topics kan uitproberen. +Het Git project heeft vier langlopende branches: `master`, `next`, en `pu` (proposed updates, voorgestelde vernieuwingen) voor nieuw spul, en `maint` voor onderhoudswerk. Als nieuw werk wordt geïntroduceerd door bijdragers, wordt het samengeraapt in topic branches in de repository van de beheerder op een manier die lijkt op wat ik omschreven heb (zie Figuur 5-24). Hier worden de topics geëvalueerd om te bepalen of ze veilig zijn en klaar voor verdere verwerking of dat ze nog wat werk nodig hebben. Als ze veilig zijn, worden ze in `next` gemerged, en wordt die branch gepushed zodat iedereen de geïntegreerde topics kan uitproberen. Insert 18333fig0524.png Figuur 5-24. Een complexe serie van parallel bijgedragen topic branches beheren. @@ -814,7 +814,7 @@ Als een onderwerp branch uiteindelijk is gemerged in `master`, dan wordt het ver Andere beheerders geven de voorkeur aan rebasen of bijgedragen werk te cherry picken naar hun master branch in plaats van ze erin te mergen, om een vrijwel lineaire historie te behouden. Als je werk in een topic branch hebt en hebt besloten dat je het wil integreren, dan ga je naar die branch en voert het rebase commando uit om de wijzigingen op je huidige master branch te baseren (of `develop`, enzovoorts). Als dat goed werkt, dan kun je de `master` branch fast-forwarden, en eindig je met een lineaire project historie. -De andere manier om gentroduceerd werk van de ene naar de andere branch te verplaatsen is om het te cherry picken. Een cherry-pick in Git is een soort rebase voor een enkele commit. Het pakt de patch die was gentroduceerd in een commit en probeert die weer toe te passen op de branch waar je nu op zit. Dit is handig als je een aantal commits op een topic branch hebt en je er slechts n van wilt integreren, of als je alleen n commit op een topic branch hebt en er de voorkeur aan geeft om het te cherry-picken in plaats van rebase uit te voeren. Bijvoorbeeld, stel dat je een project hebt dat eruit ziet als Figuur 5-26. +De andere manier om geïntroduceerd werk van de ene naar de andere branch te verplaatsen is om het te cherry picken. Een cherry-pick in Git is een soort rebase voor een enkele commit. Het pakt de patch die was geïntroduceerd in een commit en probeert die weer toe te passen op de branch waar je nu op zit. Dit is handig als je een aantal commits op een topic branch hebt en je er slechts één van wilt integreren, of als je alleen één commit op een topic branch hebt en er de voorkeur aan geeft om het te cherry-picken in plaats van rebase uit te voeren. Bijvoorbeeld, stel dat je een project hebt dat eruit ziet als Figuur 5-26. Insert 18333fig0526.png Figuur 5-26. Voorbeeld historie voor een cherry pick. @@ -826,7 +826,7 @@ Als je commit `e43a6` in je master branch wilt pullen, dan kun je dit uitvoeren [master]: created a0a41a9: "More friendly message when locking the index fails." 3 files changed, 17 insertions(+), 3 deletions(-) -Dit pulled dezelfde wijziging zoals gentroduceerd in `e43a6`, maar je krijgt een nieuwe SHA-1 waarde, omdat de gegevens op een andere manier toegepast zijn. Nu ziet je historie eruit als Figuur 5-27. +Dit pulled dezelfde wijziging zoals geïntroduceerd in `e43a6`, maar je krijgt een nieuwe SHA-1 waarde, omdat de gegevens op een andere manier toegepast zijn. Nu ziet je historie eruit als Figuur 5-27. Insert 18333fig0527.png Figuur 5-27. Historie na het cherry-picken van een commit op een topic branch. @@ -860,11 +860,11 @@ Nu dat je de inhoud van je sleutel in Git hebt, kun je een tag aanmaken die dire $ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92 -Als je `git push --tags` uitvoert, zal de `maintainer-pgp-pub` tag met iedereen gedeeld worden. Als iemand een tag wil verifiren, dan kunnen ze jouw PGP sleutel direct importeren door de blob direct uit de database te halen en het in GPG te importeren: +Als je `git push --tags` uitvoert, zal de `maintainer-pgp-pub` tag met iedereen gedeeld worden. Als iemand een tag wil verifiëren, dan kunnen ze jouw PGP sleutel direct importeren door de blob direct uit de database te halen en het in GPG te importeren: $ git show maintainer-pgp-pub | gpg --import -Ze kunnen die sleutel gebruiken om al je gesigneerde tags te verifiren. Als je instructies in het tag bericht zet, dan zal `git show ` je eindgebruikers meer specifieke instructies geven over tag verificatie. +Ze kunnen die sleutel gebruiken om al je gesigneerde tags te verifiëren. Als je instructies in het tag bericht zet, dan zal `git show ` je eindgebruikers meer specifieke instructies geven over tag verificatie. ### Een bouw nummer genereren ### @@ -875,7 +875,7 @@ Omdat Git geen monotone oplopende nummers heeft zoals 'v123' of iets gelijkwaard Op deze manier kun je een snapshot of "build" exporteren en het vernoemen naar iets dat begrijpelijk is voor mensen. Sterker nog: als je Git, gekloond van het Git repository, vanaf broncode bouwt geeft `git --version` je iets dat er zo uitziet. Als je een commit omschrijft die je direct getagged hebt, dan krijg je de tag naam. -Het `git describe` commando geeft beschreven tags de voorkeur (tags gecreerd met de `-a` of `-s` vlag), dus release tags moeten op deze manier aangemaakt 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 ook gebruiken als het doel van een checkout of show commando, alhoewel het afhankelijk is van de verkorte SHA-1 waarde aan het einde, dus het zou niet eeuwig 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, oudere `git describe` commando's werden daardoor ongeldig. +Het `git describe` commando geeft beschreven tags de voorkeur (tags gemaakt met de `-a` of `-s` vlag), dus release tags moeten op deze manier aangemaakt 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 ook gebruiken als het doel van een checkout of show commando, alhoewel het afhankelijk is van de verkorte SHA-1 waarde aan het einde, dus het zou niet eeuwig 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, oudere `git describe` commando's werden daardoor ongeldig. ### Een release voorbereiden ### @@ -914,4 +914,4 @@ Je krijgt een opgeschoonde samenvatting van alle commits sinds v1.0.1, gegroepee ## Samenvatting ## -Je zou je nu redelijk op je gemak moeten voelen om aan een project bij te dragen met Git, maar ook om je eigen project te beheren of de bijdragen van andere gebruikers te integreren. Gefeliciteerd met het worden van een effectieve Git ontwikkelaar! In het volgende hoofdstuk zul je nog krachtigere tools en trucs leren voor het omgaan met complexe situaties, die je een echte Git meester zullen maken. +Je zou je nu redelijk op je gemak moeten voelen om aan een project bij te dragen met Git, maar ook om je eigen project te beheren of de bijdragen van andere gebruikers te integreren. Gefeliciteerd, je bent nu een effectieve Git ontwikkelaar! In het volgende hoofdstuk zul je nog krachtigere tools en trucs leren voor het omgaan met complexe situaties, die je een echte Git meester zullen maken. From b5bb8388ee856dbf34c4e276cd3d3d82ecd2a932 Mon Sep 17 00:00:00 2001 From: Matt Deacalion Stevens Date: Thu, 30 Jan 2014 02:00:00 +0000 Subject: [PATCH 142/690] Update command line output in Chapter 4.2 The command line output in the examples is from an older version of Git (1.7.*) and is slightly inconsistent with the latest version. --- en/04-git-server/01-chapter4.markdown | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/en/04-git-server/01-chapter4.markdown b/en/04-git-server/01-chapter4.markdown index c0e35ec3f..7a57171f6 100644 --- a/en/04-git-server/01-chapter4.markdown +++ b/en/04-git-server/01-chapter4.markdown @@ -117,7 +117,8 @@ In order to initially set up any Git server, you have to export an existing repo 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/ + Cloning into bare repository 'my_project.git'... + done. 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. From de84431607fe66fe3cb42ff30b2dd01d61e4f495 Mon Sep 17 00:00:00 2001 From: Matt Deacalion Stevens Date: Thu, 30 Jan 2014 02:00:00 +0000 Subject: [PATCH 143/690] Update command line output in Chapter 4.5 The command line output in the examples is from an older version of Git (1.7.*) and is slightly inconsistent with the latest version. --- en/04-git-server/01-chapter4.markdown | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/en/04-git-server/01-chapter4.markdown b/en/04-git-server/01-chapter4.markdown index 7a57171f6..52651cff7 100644 --- a/en/04-git-server/01-chapter4.markdown +++ b/en/04-git-server/01-chapter4.markdown @@ -288,6 +288,13 @@ What does this `post-update` hook do? It looks basically like this: $ cat .git/hooks/post-update #!/bin/sh + # + # An example hook script to prepare a packed repository for use over + # dumb transports. + # + # To enable this hook, rename this file to "post-update". + # + 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. From 4a0e143e25dbd0ec108080431b0dee00d440e8c0 Mon Sep 17 00:00:00 2001 From: Matt Deacalion Stevens Date: Thu, 30 Jan 2014 02:00:00 +0000 Subject: [PATCH 144/690] Update command line output in Chapter 4.7 The command line output in the examples is from an older version of Git (1.7.*) and Gitosis. Both being slightly inconsistent with the latest versions. --- en/04-git-server/01-chapter4.markdown | 32 +++++++++++++-------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/en/04-git-server/01-chapter4.markdown b/en/04-git-server/01-chapter4.markdown index 52651cff7..9f5c9a0ed 100644 --- a/en/04-git-server/01-chapter4.markdown +++ b/en/04-git-server/01-chapter4.markdown @@ -410,7 +410,7 @@ You’re ready to roll. If you’re set up correctly, you can try to SSH into yo $ ssh git@gitserver PTY allocation request failed on channel 0 - fatal: unrecognized command 'gitosis-serve schacon@quaternion' + ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment. 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: @@ -434,28 +434,28 @@ If you look at the `gitosis.conf` file, it should only specify information about [gitosis] [group gitosis-admin] - writable = gitosis-admin members = scott + writable = gitosis-admin 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 + writable = iphone_project 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 + [master 8962da8] add iphone_project and mobile group + 1 file changed, 4 insertions(+) + $ git push origin master 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 + Compressing objects: 100% (3/3), done. + Writing objects: 100% (3/3), 272 bytes | 0 bytes/s, done. + Total 3 (delta 0), reused 0 (delta 0) + To git@gitserver: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: @@ -464,7 +464,7 @@ You can make your first push to the new `iphone_project` project by adding your $ 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. + Writing objects: 100% (3/3), 230 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To git@gitserver:iphone_project.git * [new branch] master -> master @@ -480,20 +480,20 @@ You want to work on this project with your friends, so you’ll have to re-add t 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 + writable = iphone_project 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 + writable = iphone_project [group mobile_ro] - readonly = iphone_project members = john + readonly = iphone_project 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: @@ -501,12 +501,12 @@ Now John can clone the project and get updates, but Gitosis won’t allow him to members = scott josie jessica [group mobile] - writable = iphone_project members = @mobile_committers + writable = iphone_project [group mobile_2] - writable = another_iphone_project members = @mobile_committers john + writable = another_iphone_project 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. From 4946e881565e33eba1c9e1bf1a4fffd6f10f4420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Kalicz?= Date: Sat, 1 Feb 2014 23:26:05 +0100 Subject: [PATCH 145/690] Tiny spelling correction --- hu/01-introduction/01-chapter1.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hu/01-introduction/01-chapter1.markdown b/hu/01-introduction/01-chapter1.markdown index 8bb5f20d7..c3cef723a 100644 --- a/hu/01-introduction/01-chapter1.markdown +++ b/hu/01-introduction/01-chapter1.markdown @@ -32,7 +32,7 @@ Ugyanakkor ez az összeállításnak van néhány komoly hátránya. A legnyílv ### Elosztott verziókövető rendszerek ### -Ekkor jöttek az Elosztott Verziókövető Rendszerek (EVR). Az EVR-ekben, mint a Git, a Mercurical, a Bazaar vagy a Dracs, a kliensek nem csak a legutolsó állapotot kérik le, hanem a teljes repositorit. Ekéépen ha a szerver megáll, amin eddig folyt az együttműködés, bármelyik kliens repositoriból vissza állítható a teljes adatbázis. Minden adat lekrés tényleg teljes mentésnek felel meg (Lásd 1-3 ábra). +Ekkor jöttek az Elosztott Verziókövető Rendszerek (EVR). Az EVR-ekben, mint a Git, a Mercurical, a Bazaar vagy a Dracs, a kliensek nem csak a legutolsó állapotot kérik le, hanem a teljes repositorit. Ekéépen ha a szerver megáll, amin eddig folyt az együttműködés, bármelyik kliens repositoriból vissza állítható a teljes adatbázis. Minden adat lekérés tényleg teljes mentésnek felel meg (Lásd 1-3 ábra). Insert 18333fig0103.png 1-3 ábra. Elosztott verziókövetés sematikus ábrája. From 4f40e142fe95a76406fc3297693fdee0bdd1237a Mon Sep 17 00:00:00 2001 From: Yue Lin Ho Date: Sun, 2 Feb 2014 16:57:35 +0800 Subject: [PATCH 146/690] [zh-tw] Synchronize with En version --- zh-tw/01-introduction/01-chapter1.markdown | 24 +- zh-tw/02-git-basics/01-chapter2.markdown | 383 ++++++++++-------- zh-tw/06-git-tools/01-chapter6.markdown | 28 +- zh-tw/07-customizing-git/01-chapter7.markdown | 115 ++++-- .../01-chapter8.markdown | 24 +- zh-tw/09-git-internals/01-chapter9.markdown | 60 +-- 6 files changed, 365 insertions(+), 269 deletions(-) diff --git a/zh-tw/01-introduction/01-chapter1.markdown b/zh-tw/01-introduction/01-chapter1.markdown index 93abf46a6..bbd0e2701 100644 --- a/zh-tw/01-introduction/01-chapter1.markdown +++ b/zh-tw/01-introduction/01-chapter1.markdown @@ -1,14 +1,11 @@ # 開始 # - 本章介紹Git的相關知識。 先從講解一些版本控制工具的背景知識開始,然後試著在讀者的系統將Git跑起來,最後則是設定它。 在本章結束後,讀者應瞭解為什麼Git如 此流行、為什麼讀者應該利用它、以及完成使用它的準備工作。 ## 關於版本控制 ## - 什麼是版本控制? 以及為什麼讀者會在意它? 版本控制是一個能夠記錄一個或一組檔案在某一段時間的變更,使得讀者以後能取回特定版本的系統。 在本書的範例中,讀者會學到如何對軟體的原始碼做版本控制。 即使實際上讀者幾乎可以針對電腦上任意型態的檔案做版本控制。 - 若讀者是繪圖或網頁設計師且想要記錄每一版影像或版面配置(這也通常是讀者想要做的),採用版本控制系統(VCS)做這件事是非常明智的。 它允許讀者將檔案復原到原本的狀態、將整個專案復原到先前的狀態、比對某一段時間的修改、查看最後是誰在哪個時間點做了錯誤的修改導致問題發生,等。 使用版本控制系統一般也意謂著若讀者做了一些傻事或者遺失檔案,讀者能很容易地回復到原先的狀態。 更進一步,僅需付出很小的代價即可得到這些優點。 ### 本地端版本控制 ### @@ -17,17 +14,16 @@ 為了解決這問題,程式設計師在很久以前開發了本地端的版本控制系統,具備簡單的資料庫,用來記載檔案的所有變更記錄(參考圖1-1)。 -Insert 18333fig0101.png +Insert 18333fig0101.png 圖1-1. 本地端版本控制流程圖。 這種版本控制工具中最流行的是rcs,目前仍存在於許多電腦。 即使是流行的Mac OS X作業系統,都會在讀者安裝開發工具時安裝rcs命令。 此工具基本上以特殊的格式記錄修補集合(patch set,即檔案從一個版本變更到另一個版本所需資訊),並儲存於磁碟上。 它就可以藉由套用各修補集合産生各時間點的檔案內容。 ### 集中式版本控制系統 ### - 接下來人們遇到的主要問題是需要在多種其它系統上的開發協同作業。 為了解決此問題,集中式版本控制系統(Centralized Version Control Systems,簡稱CVCSs)被發展出來。 此系統,如:CVS、Subversion及Perforce皆具備單一伺服器,記錄所有版本的檔案,且有多個客戶端從伺服器從伺服器取出檔案。 在多年後,這已經是版本控制系統的標準(參考圖1-2)。 -Insert 18333fig0102.png +Insert 18333fig0102.png 圖1-2. 集中式版本控制系統 這樣的配置提供了很多優點,特別是相較於本地端的版本控制系統來說。 例如:每個人皆能得知其它人對此專案做了些什麼修改有一定程度的瞭解。 管理員可調整存取權限,限制各使用者能做的事。 而且維護集中式版本控制系統也比維護散落在各使用者端的資料庫來的容易。 @@ -38,7 +34,7 @@ Insert 18333fig0102.png 這就是分散式版本控制系統(Distributed Version Control Systems, 簡稱DVCSs)被引入的原因。 在分散式版本控制系統,諸如:Git、Mercurial、Bazaar、Darcs。 客戶端不只是取出最後一版的檔案,而是完整複製整個儲存庫。 即使是整個系統賴以運作的電腦損毀,皆可將任何一個客戶端先前複製的資料還原到伺服器。 每一次的取出動作實際上就是完整備份整個儲存庫。(參考圖1-3) -Insert 18333fig0103.png +Insert 18333fig0103.png 圖1-3. 分散式版本控制系統 更進一步來說,許多這類型的系統皆能同時與數個遠端的機器同時運作。 因此讀者能同時與許多不同群組的人們協同開發同一個專案。 這允許讀者設定多種集中式系統做不到的工作流程,如:階層式模式。 @@ -65,12 +61,12 @@ Insert 18333fig0103.png Git與其它版本控制系統(包含Subversion以及與它相關的)的差別是如何處理資料的方式。 一般來說,大部份其它系統記錄資訊是一連串檔案更動的內容。 如圖1-4所示。 這些系統(CVS、Subversion、Perforce、Bazaar等等)儲存一組基本的檔案以及對應這些檔案隨時間遞增的更動資料。 -Insert 18333fig0104.png +Insert 18333fig0104.png 圖1-4. 其它系統傾向儲存每個檔案更動的資料。 Git並不以此種方式儲存資料。 而是將其視為小型檔案系統的一組快照(Snapshot)。 每一次讀者提交更新時、或者儲存目前專案的狀態到Git時。 基本上它為當時的資料做一組快照並記錄參考到該快照的參考點。 為了講求效率,只要檔案沒有變更,Git不會再度儲存該檔案,而是記錄到前一次的相同檔案的連結。 Git的工作方式如圖1-5所示。 -Insert 18333fig0105.png +Insert 18333fig0105.png 圖1-5. Git儲存每次專案更新時的快照。 這是Git與所有其它版本控制系統最重要的區別。 它完全顛覆傳統版本控制的作法。 這使用Git更像一個上層具備更強大工具的小型檔案系統,而不只是版本控制系統。 我們將會在第三章介紹分支時,提到採用此種作法的優點。 @@ -105,7 +101,7 @@ Git用來計算查核碼的機制稱為SHA-1雜湊法。 它由40個十六進制 這帶領我們到Git專案的三個主要區域:Git目錄、工作目錄(working directory)以及暫存區域(staging area)。 -Insert 18333fig0106.png +Insert 18333fig0106.png 圖1-6. 工作目錄、暫存區域及git目錄。 Git目錄是Git用來儲存讀者的專案的元數據及物件資料庫。 這是Git最重要的部份,而且它是當讀者從其它電腦複製儲存庫時會複製過來的。 @@ -141,7 +137,7 @@ Git目錄是Git用來儲存讀者的專案的元數據及物件資料庫。 這 當讀者安裝所有必要的程式庫,讀者可到Git的網站取得最新版本: http://git-scm.com/download - + 接著,編譯及安裝: $ tar -zxf git-1.6.0.5.tar.gz @@ -152,7 +148,7 @@ Git目錄是Git用來儲存讀者的專案的元數據及物件資料庫。 這 在這些工作完成後,讀者也可以使用Git取得Git的更新版: $ git clone git://git.kernel.org/pub/scm/git/git.git - + ### 在Linux系統安裝 ### 若讀者想使用二進位安裝程式安裝Git到Linux,一般來說讀者可經由發行套件提供的套件管理工具完成此工作。 若讀者使用Fedora,可使用`yum`: @@ -169,7 +165,7 @@ Git目錄是Git用來儲存讀者的專案的元數據及物件資料庫。 這 http://code.google.com/p/git-osx-installer -Insert 18333fig0107.png +Insert 18333fig0107.png 圖1-7. Git OS X 安裝程式。 藉由MacPorts安裝Git是另一種主要的方法。 若讀者已安裝MacPorts,使用下列命令安裝Git @@ -214,7 +210,7 @@ Git附帶名為`git config`的工具,允許讀者取得及設定組態參數 現在讀者的識別資料已設定完畢,讀者可設定預設的文書編輯器,當Git需要讀者輸入訊息時會叫用它。 預設情況下,Git會使用系統預設的編輯器,一般來說是Vi或Vim。 若讀者想指定不同的編輯器,例如:Emacs。可執行下列指令: $ git config --global core.editor emacs - + ### 指定合併工具 ### 另外一個對讀者來說有用的選項是設定解決合併失敗時,讀者慣用的合併工具。 假設讀者想使用vimdiff: diff --git a/zh-tw/02-git-basics/01-chapter2.markdown b/zh-tw/02-git-basics/01-chapter2.markdown index 5bf05a15c..d05734c1c 100644 --- a/zh-tw/02-git-basics/01-chapter2.markdown +++ b/zh-tw/02-git-basics/01-chapter2.markdown @@ -46,7 +46,7 @@ Git提供很多種協定給讀者使用。 上一個範例採用 `git://` 協定 只要讀者編輯任何已被追蹤的檔案。 Git將它們視為被更動的,因為讀者將它們改成與最後一次提交不同。 讀者暫存這些已更動檔案並提供所有被暫存的更新, 並重複此週期。 此生命週期如圖2-1所示。 -Insert 18333fig0201.png +Insert 18333fig0201.png 圖2-1. 檔案狀態的生命週期。 ### 檢視檔案的狀態 ### @@ -54,8 +54,8 @@ Insert 18333fig0201.png 主要給讀者用來檢視檔案的狀態是 git status 命令。 若讀者在複製完複本後馬上執行此命令,會看到如下的文字: $ git status - # On branch master - nothing to commit (working directory clean) + On branch master + nothing to commit, working directory clean 這意謂著讀者有一份乾淨的工作目錄(換句話說,沒有未被追蹤或已被修改的檔案)。 Git未看到任何未被追蹤的檔案,否則會將它們列出。 最後,這個命令告訴讀者目前在哪一個分支。 到目前為止,一直都是master,這是預設的。 目前讀者不用考慮它。 下一個章節會詳細介紹分支。 @@ -63,11 +63,12 @@ Insert 18333fig0201.png $ vim README $ git status - # On branch master - # Untracked files: - # (use "git add ..." to include in what will be committed) - # - # README + 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) 讀者可看到新增的`README`尚未被追蹤,因為它被列在輸出訊息的 Untracked files 下方。 除非讀者明確指定要將該檔案加入提交的快照,Git不會主動將它加入。 這樣就不會突然地將一些二進位格式的檔案或其它讀者並不想加入的檔案含入。 讀者的確是要新增 `README` 檔案,因此讓我們開始追蹤該檔案。 @@ -81,12 +82,12 @@ Insert 18333fig0201.png 若讀者再度檢查目前狀態,可看到`README`檔案已被列入追蹤並且已被暫存: $ git status - # On branch master - # Changes to be committed: - # (use "git reset HEAD ..." to unstage) - # - # new file: README - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + new file: README + 因為它被放在Changes to be commited文字下方,讀者可得知它已被暫存起來。 若讀者此時提交更新,剛才執行`git add`加進來的檔案就會被記錄在歷史的快照。 讀者可能可回想一下先前執行`git init`後也有執行過`git add`,開始追蹤目錄內的檔案。 `git add`命令可接受檔名或者目錄名。 若是目錄名,會遞迴將整個目錄下所有檔案及子目錄都加進來。 @@ -95,58 +96,60 @@ Insert 18333fig0201.png 讓我們修改已被追蹤的檔案。 若讀者修改先前已被追蹤的檔案,名為`benchmarks.rb`,並檢查目前儲存庫的狀態。 讀者會看到類似以下文字: $ 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 - # + 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) + (use "git checkout -- ..." to discard changes in working directory) + + modified: benchmarks.rb + `benchmarks.rb`檔案出現在 “Changes not staged for commit” 下方,代表著這個檔案已被追蹤,而且位於工作目錄的該檔案已被修改,但尚未暫存。 要暫存該檔案,可執行`git add`命令(這是一個多重用途的指令)。現在,讀者使用 `git add` 將`benchmarks.rb`檔案暫存起來,並再度執行`git status`: $ 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 - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + new file: README + modified: benchmarks.rb + 這兩個檔案目前都被暫存起來,而且會進入下一次的提交。 假設讀者記得仍需要對`benchmarks.rb`做一點修改後才要提交,可再度開啟並編輯該檔案。 然而,當我們再度執行`git status`: - $ vim benchmarks.rb + $ 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 - # + 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) + (use "git checkout -- ..." to discard changes in working directory) + + modified: benchmarks.rb + 到底發生了什麼事? 現在`benchmarks.rb`同時被列在已被暫存及未被暫存。 這怎麼可能? 這表示Git的確在讀者執行`git add`命令後,將檔案暫存起來。 若讀者現在提交更新,最近一次執行`git add`命令時暫存的`benchmarks.rb`會被提交。 若讀者在`git add`後修改檔案,需要再度執行`git add`將最新版的檔案暫存起來: $ 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 - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + new file: README + modified: benchmarks.rb + ### 忽略某些檔案 ### @@ -167,7 +170,6 @@ Insert 18333fig0201.png Glob pattern就像是shell使用的簡化版正規運算式。 星號(`*`)匹配零個或多個字元;`[abc]`匹配中括弧內的任一字元(此例為`a`、`b`、`c`);問號(`?`)匹配單一個字元;中括孤內的字以連字符連接(如:`[0-9]`),用來匹配任何符合該範圍的字(此例為0到9)。 - 以下是另一個`.gitignore`的範例檔案: # 註解,會被忽略。 @@ -181,6 +183,10 @@ Glob pattern就像是shell使用的簡化版正規運算式。 星號(`*`) build/ # 忽略doc/notes.txt但不包含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. ### 檢視已暫存及尚未暫存的更動 ### @@ -189,17 +195,18 @@ Glob pattern就像是shell使用的簡化版正規運算式。 星號(`*`) 假設讀者編輯並暫存`README`,接者修改`benchmarks.rb`檔案,卻未暫存。 若讀者檢視目前的狀況,會看到類似下方文字: $ 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 - # + 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) + (use "git checkout -- ..." to discard changes in working directory) + + modified: benchmarks.rb + 想瞭解尚未暫存的修改,執行`git diff`,不用帶任何參數: @@ -244,20 +251,22 @@ Glob pattern就像是shell使用的簡化版正規運算式。 星號(`*`) $ 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 - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + modified: benchmarks.rb + + 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 + 現在讀者可使用`git diff`檢視哪些部份尚未被暫存: - $ git diff + $ git diff diff --git a/benchmarks.rb b/benchmarks.rb index e445e28..86b2f7c 100644 --- a/benchmarks.rb @@ -265,7 +274,7 @@ Glob pattern就像是shell使用的簡化版正規運算式。 星號(`*`) @@ -127,3 +127,4 @@ end main() - ##pp Grit::GitRuby.cache_client.stats + ##pp Grit::GitRuby.cache_client.stats +# test line 以及使用`git diff --cached`檢視目前已暫存的變更: @@ -282,7 +291,7 @@ Glob pattern就像是shell使用的簡化版正規運算式。 星號(`*`) + run_code(x, 'commits 1') do + git.commits.size + end - + + + run_code(x, 'commits 2') do log = git.commits('master', 15) log.size @@ -302,10 +311,9 @@ Glob pattern就像是shell使用的簡化版正規運算式。 星號(`*`) # 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 + # modified: benchmarks.rb + # ~ ~ ~ @@ -316,8 +324,8 @@ Glob pattern就像是shell使用的簡化版正規運算式。 星號(`*`) 另一種方式則是在commit命令後方以`-m`參數指定提交訊息,如下: $ git commit -m "Story 182: Fix benchmarks for speed" - [master]: created 463dc4f: "Fix benchmarks for speed" - 2 files changed, 3 insertions(+), 0 deletions(-) + [master 463dc4f] Fix benchmarks for speed + 2 files changed, 3 insertions(+) create mode 100644 README 現在讀者已建立第一個提交! 讀者可從輸出的訊息看到此提交、放到哪個分支(`master`)、SHA-1查核碼(`463dc4f`)、有多少檔案被更動,以及統計此提交有多少列被新增及移除。 @@ -329,15 +337,17 @@ Glob pattern就像是shell使用的簡化版正規運算式。 星號(`*`) 雖然優秀好用的暫存區域能很有技巧且精確的提交讀者想記錄的資訊,有時候暫存區域也比讀者實際需要的工作流程繁瑣。 若讀者想跳過暫存區域,Git提供了簡易的使用方式。 在`git commit`命令後方加上`-a`參數,Git自動將所有已被追蹤且被修改的檔案送到暫存區域並開始提交程序,讓讀者略過`git add`的步驟: $ git status - # On branch master - # - # Changes not staged for commit: - # - # modified: benchmarks.rb - # + 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) + + modified: benchmarks.rb + + no changes added to commit (use "git add" and/or "git commit -a") $ git commit -a -m 'added new benchmarks' [master 83e38c7] added new benchmarks - 1 files changed, 5 insertions(+), 0 deletions(-) + 1 files changed, 5 insertions(+) 留意本次的提交之前,讀者並不需要執行`git add`將`benchmarks.rb`檔案加入。 @@ -349,26 +359,26 @@ Glob pattern就像是shell使用的簡化版正規運算式。 星號(`*`) $ 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 - # + On branch master + Changes not staged for commit: + (use "git add/rm ..." to update what will be committed) + (use "git checkout -- ..." to discard changes in working directory) + + deleted: grit.gemspec + + no changes added to commit (use "git add" and/or "git commit -a") 接著,若執行`git rm`,則會將暫存區域內的該檔案移除: $ 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 - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + deleted: grit.gemspec + 下一次提交時,該檔案將會消失而且不再被追蹤。 若已更動過該檔案且將它記錄到暫存區域。 必須使用`-f`參數才能將它強制移除。 這是為了避免已被記錄的快照意外被移除且再也無法使用Git復原。 @@ -398,14 +408,12 @@ Git並不像其它檔案控制系統一樣,明確地追蹤檔案的移動。 $ 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 - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + renamed: README.txt -> README + 不過,這就相當於執行下列命令: @@ -450,7 +458,7 @@ Git會在背後判斷檔案是否被更名,因此不管是用上述方法還 最常用的選項之一為 `-p`,用來顯示每個更新之間差別的內容。 另外還可以加上 `-2` 參數,限制為只輸出最後兩個更新。 - $ git log –p -2 + $ git log -p -2 commit ca82a6dff817ec66f44342007202690a93763949 Author: Scott Chacon Date: Mon Mar 17 21:52:11 2008 -0700 @@ -461,11 +469,13 @@ Git會在背後判斷檔案是否被更名,因此不管是用上述方法還 index a874b73..8f94139 100644 --- a/Rakefile +++ b/Rakefile - @@ -5,7 +5,7 @@ require 'rake/gempackagetask' + @@ -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 @@ -489,9 +499,30 @@ Git會在背後判斷檔案是否被更名,因此不管是用上述方法還 \ No newline at end of file 這個選項除了顯示相同的資訊外,還另外附上每個更新的差異。 這對於重新檢視或者快速的瀏覽協同工作伙伴新增的更新非常有幫助。 + +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. + 另外也可以使用`git log`提供的一系統摘要選項。 例如:若想檢視每個更新的簡略統計資訊,可使用 `--stat` 選項: - $ git log --stat + $ git log --stat commit ca82a6dff817ec66f44342007202690a93763949 Author: Scott Chacon Date: Mon Mar 17 21:52:11 2008 -0700 @@ -499,7 +530,7 @@ Git會在背後判斷檔案是否被更名,因此不管是用上述方法還 changed the version number Rakefile | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) + 1 file changed, 1 insertion(+), 1 deletion(-) commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 Author: Scott Chacon @@ -508,7 +539,7 @@ Git會在背後判斷檔案是否被更名,因此不管是用上述方法還 removed unnecessary test code lib/simplegit.rb | 5 ----- - 1 files changed, 0 insertions(+), 5 deletions(-) + 1 file changed, 5 deletions(-) commit a11bef06a3f659402fe7563abf99ad00de2209e6 Author: Scott Chacon @@ -519,7 +550,7 @@ Git會在背後判斷檔案是否被更名,因此不管是用上述方法還 README | 6 ++++++ Rakefile | 23 +++++++++++++++++++++++ lib/simplegit.rb | 25 +++++++++++++++++++++++++ - 3 files changed, 54 insertions(+), 0 deletions(-) + 3 files changed, 54 insertions(+) 如以上所示,`--stat`選項在每個更新項目的下方列出被更動的檔案、有多少檔案被更動,以及有多行列被加入或移出該檔案。 也會在最後印出摘要的訊息。 其它實用的選項是 `--pretty`。 這個選項改變原本預設輸出的格式。 有數個內建的選項供讀者選用。 其中 `oneline` 選項將每一個更新印到單獨一行,對於檢視很多更新時很有用。 更進一步,`short`、`full`、`fuller` 選項輸出的格式大致相同,但會少一些或者多一些資訊。 @@ -538,6 +569,11 @@ Git會在背後判斷檔案是否被更名,因此不管是用上述方法還 表格2-1列出一些 `format` 支援的選項。 + + 選項 選項的說明 %H 該更新的SHA1雜湊值 %h 該更新的簡短SHA1雜湊值 @@ -562,17 +598,22 @@ Git會在背後判斷檔案是否被更名,因此不管是用上述方法還 $ 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 這些只是一些簡單的 `git log` 的選項,還有許多其它的。 表格2-2列出目前我們涵蓋的及一些可能有用的格式選項,以及它們如何更動 `log` 命令的輸出格式。 + + 選項 選項的說明 -p 顯示每個更新與上一個的差異。 --stat 顯示每個更新更動的檔案的統計及摘要資訊。 @@ -600,6 +641,11 @@ Git會在背後判斷檔案是否被更名,因此不管是用上述方法還 在表格2-3,我們列出這些選項以及少數其它常見選項以供參考。 + + 選項 選項的說明文字 -(n) 僅顯示最後 n 個更新 --since, --after 列出特定日期後的更新。 @@ -624,7 +670,7 @@ Git 原始碼的更新歷史接近二萬筆更新,本命令顯示符合條件 若讀者較偏向使用圖形界面檢視歷史,或與會想看一下隨著 Git 發佈的,名為 `gitk` 的 Tcl/Tk 程式。 Gitk 基本上就是 `git log` 的圖形界面版本,而且幾乎接受所有 `git log` 支援的過濾用選項。 若在專案所在目錄下執行 gitk 命令,將會看到如圖2-2的畫面。 -Insert 18333fig0202.png +Insert 18333fig0202.png 圖2-2。 gitk檢視歷史程式。 在上圖中可看到視窗的上半部顯示相當棒的更新歷史圖。 視窗下半部則顯示當時被點選的更新引入的變更。 @@ -647,7 +693,7 @@ Insert 18333fig0202.png $ git commit -m 'initial commit' $ git add forgotten_file - $ git commit --amend + $ git commit --amend 這些命令的僅僅會提交一個更新,第二個被提交的更新會取代第一個。 @@ -657,31 +703,32 @@ Insert 18333fig0202.png $ git add . $ git status - # On branch master - # Changes to be committed: - # (use "git reset HEAD ..." to unstage) - # - # modified: README.txt - # modified: benchmarks.rb - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + modified: README.txt + modified: benchmarks.rb + 在 “Changes to be commited” 文字下方,註明著使用 “`git reset HEAD ...`,將 file 移出暫存區”。 因此,讓我們依循該建議將 `benchmarks.rb` 檔案移出暫存區: - $ git reset HEAD benchmarks.rb - benchmarks.rb: locally modified + $ git reset HEAD benchmarks.rb + Unstaged changes after reset: + M benchmarks.rb $ 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 - # + 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 + 這個命令看起來有點奇怪,不過它的確可行。 `benchmarks.rb` 檔案被移出暫存區了。 @@ -689,23 +736,23 @@ Insert 18333fig0202.png 若讀者發現其者並不需要保留 `benchmarks.rb` 檔案被更動部份,應該如何做才能很容易的復原為最後一次提交的狀態(或者最被複製儲存庫時、或放到工作目錄時的版本)? 很幸運的,`git status` 同樣也告訴讀者如何做。 在最近一次檢視狀態時,暫存區看起來應如下所示: - # 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 - # + 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 + 在這訊息中已很明確的說明如何拋棄所做的修改(至少需升級為 Git 1.6.1或更新版本。 若讀者使用的是舊版,強烈建議升級,以取得更好用的功能。) 讓我們依據命令執行: $ git checkout -- benchmarks.rb $ git status - # On branch master - # Changes to be committed: - # (use "git reset HEAD ..." to unstage) - # - # modified: README.txt - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + modified: README.txt + 在上述文字可看到該變更已被復原。 讀者應該瞭解這是危險的命令,任何對該檔案做的修改將不復存在,就好像複製別的檔案將它覆蓋。 除非很清楚真的不需要該檔案,絕不要使用此檔案。 若需要將這些修改排除,我們在下一章節會介紹備份及分支。 一般來說會比此方法來的好。 @@ -721,20 +768,21 @@ Insert 18333fig0202.png 欲瞭解目前已加進來的遠端儲存庫,可執行 `git remote` 命令。 它會列出當初加入遠端儲存庫時指定的名稱。 若目前所在儲存庫是從其它儲存庫複製過來的,至少應該看到 *origin*,也就是 Git 複製儲存庫時預設名字: $ 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. + Cloning into 'ticgit'... + remote: Reusing existing pack: 1857, done. + remote: Total 1857 (delta 0), reused 0 (delta 0) + Receiving objects: 100% (1857/1857), 374.35 KiB | 193.00 KiB/s, done. + Resolving deltas: 100% (772/772), done. + Checking connectivity... done. $ cd ticgit - $ git remote + $ git remote origin 也可以再加上 `-v` 參數,將會在名稱後方顯示其URL: $ git remote -v - origin git://github.com/schacon/ticgit.git + origin git://github.com/schacon/ticgit.git (fetch) + origin git://github.com/schacon/ticgit.git (push) 若有一個以上遠端儲存庫,此命令會全部列出。 例如:我的 Grit 儲存庫包含以下遠端儲存庫。 @@ -898,6 +946,7 @@ Git使用兩大類的標籤:輕量級(lightweight)和含附註(annotated)。 Date: Mon Feb 9 14:45:11 2009 -0800 my version 1.4 + commit 15027957951b64cf874c3557a0f3547bd83b3ff6 Merge: 4a447f7... a6b4c97... Author: Scott Chacon @@ -1008,7 +1057,7 @@ Git使用兩大類的標籤:輕量級(lightweight)和含附註(annotated)。 你可以看到標籤已經補上: - $ git tag + $ git tag v0.1 v1.2 v1.3 @@ -1057,7 +1106,6 @@ Git使用兩大類的標籤:輕量級(lightweight)和含附註(annotated)。 現在,當其他使用者clone或pull你的儲存庫時,他們也同時會取得所有你的標籤。 - ## 提示和技巧 ## 在結束Git基礎這個章節前,我們將介紹有一些將會使你的Git使用經驗更簡單、方便和親切的提示和技巧。或許很多人從未運用過這些技巧,我們也不會假設你在本書的後續章節會使用它們。但你也許會想知道如何使用它們。 @@ -1066,7 +1114,7 @@ Git使用兩大類的標籤:輕量級(lightweight)和含附註(annotated)。 如果你用的是 Bash shell,你可以啟動Git本身寫好的自動補齊腳本。下載Git原始碼,切到`contrib/completion`目錄;可以看到檔案名為`git-completion.bash`。將它複製到你的家目錄,並加入以下指令到你的`.bashrc`檔案裡: - source ~/.git-completion.bash + source ~/git-completion.bash 如果你想為所有使用者都自動設置Bash shell的補齊功能,在Mac系統上將這個腳本複製到`/opt/local/etc/bash_completion.d`目錄,若你使用Linux系統複製到 `/etc/bash_completion.d/`目錄。這兩個目錄中的脚本,都會在 Bash 啟動時自動載入。 @@ -1086,7 +1134,6 @@ Git使用兩大類的標籤:輕量級(lightweight)和含附註(annotated)。 這是個好用的小技巧,或許可以省下許多輸入和查文件的時間 - ### Git 命令別名 ### 如果僅輸入命令的部份字元,Git並不會幫你推論出你想要下的完整命令。如果你想偷懶,不想輸入Git命令的所有字元,你可以輕易地利用`git config`設定別名(alias)。你也許會想要設定以下這幾個範例: @@ -1112,7 +1159,7 @@ Git使用兩大類的標籤:輕量級(lightweight)和含附註(annotated)。 $ git config --global alias.last 'log -1 HEAD' 如此一來,將可更簡單地看到最新的提交訊息: - + $ git last commit 66938dae3329c7aebe598c2246a8e6af90d04646 Author: Josh Goebel @@ -1128,4 +1175,4 @@ Git使用兩大類的標籤:輕量級(lightweight)和含附註(annotated)。 ## 總結 ## -至此,讀者已具備所有Git的本地端操作,包括:創建和副本儲存庫、建立修改、暫存和提交這些修改,以及檢視在儲存庫中所有修改歷史。接下來,我們將觸及Git的殺手級特性,也就是他的分支模型。 \ No newline at end of file +至此,讀者已具備所有Git的本地端操作,包括:創建和副本儲存庫、建立修改、暫存和提交這些修改,以及檢視在儲存庫中所有修改歷史。接下來,我們將觸及Git的殺手級特性,也就是他的分支模型。 diff --git a/zh-tw/06-git-tools/01-chapter6.markdown b/zh-tw/06-git-tools/01-chapter6.markdown index c5e1f5f26..392cc7b5b 100644 --- a/zh-tw/06-git-tools/01-chapter6.markdown +++ b/zh-tw/06-git-tools/01-chapter6.markdown @@ -79,7 +79,7 @@ Git 可以為你的 SHA-1 值生成出簡短且唯一的縮寫。如果你傳遞 在你工作的同時,Git 在後臺的工作之一就是保存一份引用日誌(reflog)——一份記錄最近幾個月你的 HEAD 和分支引用的日誌。 -你可以使用 `git reflog` 來查看引用日誌: +你可以使用 `git reflog` 來查看引用日誌: $ git reflog 734713b... HEAD@{0}: commit: fixed refs handling, added gc auto, updated @@ -100,12 +100,12 @@ Git 可以為你的 SHA-1 值生成出簡短且唯一的縮寫。如果你傳遞 它就會顯示昨天分支的頂端在哪。這項技術只對還在你引用日誌裡的資料有用,所以不能用來查看比幾個月前還早的提交。 -想要看類似於 `git log` 輸出格式的引用日誌資訊,你可以執行 `git log -g`: +想要看類似於 `git log` 輸出格式的引用日誌資訊,你可以執行 `git log -g`: $ 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 @@ Git 可以為你的 SHA-1 值生成出簡短且唯一的縮寫。如果你傳遞 $ 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 @@ -189,7 +189,7 @@ Git 可以為你的 SHA-1 值生成出簡短且唯一的縮寫。如果你傳遞 最常用的指明範圍的方法是雙點的語法。這種語法主要是讓 Git 區分出可從一個分支中獲得而不能從另一個分支中獲得的提交。例如,假設你有類似於圖 6-1 的提交歷史。 -Insert 18333fig0601.png +Insert 18333fig0601.png Figure 6-1. 範圍選擇的提交歷史實例 你想要查看你的試驗分支(experiment)上哪些沒有被提交到主分支,那麼你就可以使用 `master..experiment` 來讓 Git 顯示這些提交的日誌——這句話的意思是「所有可從 experiment 分支中獲得而不能從 master 分支中獲得的提交」。為了使例子簡單明瞭,我使用了圖示中提交物件的字母,來代替它們在實際的日誌輸出裏的顯示順序: @@ -263,7 +263,7 @@ Git 提供了很多腳本來輔助某些命令列任務。這裡,你將看到 *** Commands *** 1: status 2: update 3: revert 4: add untracked 5: patch 6: diff 7: quit 8: help - What now> + What now> 你會看到這個命令以一個完全不同的視圖顯示了你的暫存區——主要是你通過 `git status` 得到的那些資訊但是稍微簡潔但資訊更加豐富一些。它在左側列出了你暫存的變更,在右側列出了未被暫存的變更。 @@ -291,7 +291,7 @@ Git 提供了很多腳本來輔助某些命令列任務。這裡,你將看到 每個檔旁邊的 `*` 表示選中的檔將被暫存。如果你在 update>> 提示後直接敲入 Enter,Git會替你把所有選中的內容暫存: - Update>> + Update>> updated 2 paths *** Commands *** @@ -373,7 +373,7 @@ Git 提供了很多腳本來輔助某些命令列任務。這裡,你將看到 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,?]? 此處你有很多選擇。輸入 `?` 可以顯示清單: @@ -737,7 +737,7 @@ Git 也提供了一些工具來幫助你 debug 專案中遇到的問題。由於 如果你在追查程式碼中的 bug,想要知道這是什麼時候、為什麼被引進來的,檔案標注會是你的最佳工具。它會顯示檔案中對每一行進行修改的最近一次提交。因此,如果你發現自己程式碼中的一個 method 有 bug,你可以用 `git blame` 來標注該檔案,查看那個 method 的每一行分別是由誰在哪一天修改的。下面這個例子使用了 `-L` 選項來限制輸出範圍在第12至22行: - $ 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 @@ -745,7 +745,7 @@ Git 也提供了一些工具來幫助你 debug 專案中遇到的問題。由於 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 @@ -754,8 +754,8 @@ Git 也提供了一些工具來幫助你 debug 專案中遇到的問題。由於 另一件很酷的事情是,Git 並不會明確地記錄對檔案所做的重命名(rename)動作。它會記錄快照,然後根據實際狀況嘗試找出隱藏在背後的重命名動作。這其中有一個很有意思的特性,就是你可以讓它找出所有的程式碼移動。如果你在 `git blame` 後加上 `-C`,Git 會分析你所標注的檔案,然後嘗試找出其中代碼片段的原始出處,如果它是從其他地方拷貝過來的話。最近,我在對 `GITServerHandler.m` 這個檔案做程式碼重構(code refactoring),將它分解為多個檔案,其中一個是 `GITPackUpload.m`。通過對 `GITPackUpload.m` 執行帶 `-C` 參數的 blame 命令,我可以看到程式碼片段的原始出處: - $ 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 @@ -852,7 +852,7 @@ Git 通過子模組處理這個問題。子模組允許你將一個 Git 倉庫 首先你注意到有一個 `.gitmodules` 文件。這是一個設定檔,保存了專案 URL 和你拉取到的本地子目錄 - $ cat .gitmodules + $ cat .gitmodules [submodule "rack"] path = rack url = git://github.com/chneukirchen/rack.git diff --git a/zh-tw/07-customizing-git/01-chapter7.markdown b/zh-tw/07-customizing-git/01-chapter7.markdown index 31eadc0c5..8be51aab4 100644 --- a/zh-tw/07-customizing-git/01-chapter7.markdown +++ b/zh-tw/07-customizing-git/01-chapter7.markdown @@ -129,7 +129,7 @@ Git 會按照你的需要,自動為大部分的輸出加上顏色。你能明 除此之外,以上每個選項都有子選項,可以被用來覆蓋其父設置,以達到為輸出的各個部分著色的目的。例如,要讓 diff 輸出的改變資訊 (meta information) 以粗體、藍色前景和黑色背景的形式顯示,你可以執行: - $ 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。 @@ -157,13 +157,13 @@ diff 包裝腳本首先確定傳遞過來7個參數,隨後把其中2個傳遞 由於你僅僅需要 `old-file` 和 `new-file` 參數,用 diff 包裝腳本來傳遞它們吧。 - $ 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 現在來設定使用你自訂的比較和合併工具吧。這需要許多自訂設置:`merge.tool` 通知 Git 使用哪個合併工具;`mergetool.*.cmd` 規定命令如何執行;`mergetool.trustExitCode` 會通知 Git 該程式的退出碼(exit code)是否指示合併操作成功;`diff.external` 通知 Git 用什麼命令做比較。因此,你可以執行以下4條配置命令: @@ -185,12 +185,12 @@ diff 包裝腳本首先確定傳遞過來7個參數,隨後把其中2個傳遞 external = extDiff 設置完畢後,如果你像這樣執行 diff 命令: - + $ git diff 32d1776b1^ 32d1776b1 不同於在命令列得到 diff 命令的輸出,Git 觸發了剛剛設置的 P4Merge,它看起來像圖7-1這樣: -Insert 18333fig0701.png +Insert 18333fig0701.png Figure 7-1. P4Merge. 當你設法合併兩個分支,結果卻有衝突時,執行 `git mergetool`,Git 會啟用 P4Merge 讓你通過圖形介面來解決衝突。 @@ -198,7 +198,7 @@ Figure 7-1. P4Merge. 設置包裝腳本的好處是你能簡單地改變 diff 和 merge 工具,例如把 `extDiff` 和 `extMerge` 改成 KDiff3,要做的僅僅是編輯 `extMerge` 指令檔: $ cat /usr/local/bin/extMerge - #!/bin/sh + #!/bin/sh /Applications/kdiff3.app/Contents/MacOS/kdiff3 $* 現在 Git 會使用 KDiff3 來做比較、合併和解決衝突。 @@ -260,8 +260,7 @@ Git 伺服器端的配置選項並不多,但仍有一些有趣的選項值得 #### receive.fsckObjects #### -Git 預設情況下不會在推送期間檢查所有物件的一致性。Git 雖然會檢查確認每個物件仍然符合它的 SHA-1 checksum, -所指向的物件也都是有效的,但是預設 Git 不會在每次推送時都做這種檢查。對於 Git 來說,倉庫或推送的檔越大,這個操作代價就相對越高,每次推送會消耗更多時間。如果想讓 Git 在每次推送時都檢查物件一致性,可以設定 `receive.fsckObjects` 為 true 來強迫它這麼做: +Git 預設情況下不會在推送期間檢查所有物件的一致性。Git 雖然會檢查確認每個物件仍然符合它的 SHA-1 checksum,所指向的物件也都是有效的,但是預設 Git 不會在每次推送時都做這種檢查。對於 Git 來說,倉庫或推送的檔越大,這個操作代價就相對越高,每次推送會消耗更多時間。如果想讓 Git 在每次推送時都檢查物件一致性,可以設定 `receive.fsckObjects` 為 true 來強迫它這麼做: $ git config --system receive.fsckObjects true @@ -312,9 +311,11 @@ To tell Git to treat all `pbxproj` files as binary data, add the following line 在 Git 1.6 及以上版本中,你能利用 Git 屬性來有效地比較二進位檔案。可以設置 Git 把二進位資料轉換成文本格式,然後用一般 diff 來做比較。 +##### MS Word files ##### + 這個特性很酷,而且鮮為人知,因此我會結合實例來講解。首先,你將使用這項技術來解決最令人頭疼的問題之一:對 Word 文檔進行版本控制。每個人都知道 Word 是最可怕的編輯器,奇怪的是,每個人都在使用它。如果想對 Word 文件進行版本控制,你可以把檔案加入到 Git 倉庫中,每次修改後提交即可。但這樣做有什麼好處?如果你像平常一樣執行 `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 @@ -336,15 +337,67 @@ To tell Git to treat all `pbxproj` files as binary data, add the following line 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 成功且簡潔地顯示出我增加的文字 ”(See Chapter 3)”。雖然有些瑕疵 -- 在末尾顯示了一些隨機的內容 -- 但確實可以比較了。如果你能找到或自己寫個 Word 到純文字的轉換器的話,效果可能會更好。不過因為 `strings` 可以在大部分 Mac 和 Linux 系統上運行,所以在初次嘗試對各種二進位格式檔進行類似的處理,它是個不錯的選擇。 + +##### OpenDocument Text files ##### + +The same approach that we used for MS Word files (`*.doc`) can be used for OpenDocument Text files (`*.odt`) created by OpenOffice.org. + +Add the following line to your `.gitattributes` file: + + *.odt diff=odt + +Now set up the `odt` diff filter in `.git/config`: + + [diff "odt"] + binary = true + textconv = /usr/local/bin/odt-to-txt -Git 成功且簡潔地顯示出我增加的文字 ”Let’s see if this works”。雖然有些瑕疵 -- 在末尾顯示了一些隨機的內容 -- 但確實可以比較了。如果你能找到或自己寫個 Word 到純文字的轉換器的話,效果可能會更好。不過因為 `strings` 可以在大部分 Mac 和 Linux 系統上運行,所以在初次嘗試對各種二進位格式檔進行類似的處理,它是個不錯的選擇。 +OpenDocument files are actually zip’ped directories containing multiple files (the content in an XML format, stylesheets, images, etc.). We’ll need to write a script to extract the content and return it as plain text. Create a file `/usr/local/bin/odt-to-txt` (you are free to put it into a different directory) with the following content: + + #! /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"; + +And make it executable + + chmod +x /usr/local/bin/odt-to-txt + +Now `git diff` will be able to tell you what changed in `.odt` files. + + +##### Image files ##### 你還能用這個方法解決另一個有趣的問題:比較影像檔。方法之一是對 JPEG 檔執行一個篩檢程式,把 EXIF 資訊捉取出來 — EXIF 資訊是記錄在大部分圖像格式裏面的 metadata。如果你下載並安裝了 `exiftool` 程式,可以用它把圖檔的 metadata 轉換成文本,於是至少 diff 可以用文字呈現的方式向你展示發生了哪些修改: @@ -360,7 +413,7 @@ Git 成功且簡潔地顯示出我增加的文字 ”Let’s see if this works @@ -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 @@ -385,19 +438,19 @@ Git 成功且簡潔地顯示出我增加的文字 ”Let’s see if this works 下次 check out 這個檔案的時候,Git 注入了 blob 的 SHA 值: - $ rm text.txt - $ git checkout -- text.txt - $ cat test.txt + $ rm test.txt + $ git checkout -- test.txt + $ cat test.txt $Id: 42812b7653c7b88933f8a9d6cad0ca16714b9bb3 $ 然而,這個結果的用處有限。如果你在 CVS 或 Subversion 中用過關鍵字替換,你可以包含一個日期值 -- 而這個 SHA 值沒什麼幫助,因為它相當地隨機,也無法區分某個 SHA 跟另一個 SHA 比起來是比較新或是比較舊。 因此,你可以撰寫自己的篩檢程式,在提交或 checkout 文件時替換關鍵字。有兩種篩檢程式,”clean” 和 ”smudge”。在 `.gitattributes` 檔中,你能對特定的路徑設置一個篩檢程式,然後設置處理檔案的腳本,這些腳本會在檔案 check out 前(”smudge”,見圖 7-2)和提交前(”clean”,見圖7-3)被執行。這些篩檢程式能夠做各種有趣的事。 -Insert 18333fig0702.png +Insert 18333fig0702.png Figure 7-2. “smudge” filter 在 checkout 時執行 -Insert 18333fig0703.png +Insert 18333fig0703.png Figure 7-3. “clean” filter 在檔案被 staged 的時候執行 這裡舉一個簡單的例子:在提交前,用 indent(縮進)程式過濾所有C原始程式碼。在 `.gitattributes` 檔中設置 ”indent” 篩檢程式過濾 `*.c` 文件: @@ -679,7 +732,7 @@ A simple way to get the commit message from a commit when you have the SHA-1 val 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 @@ -687,7 +740,7 @@ A simple way to get the commit message from a commit when you have the SHA-1 val exit 1 end end - end + end end check_directory_perms @@ -702,7 +755,7 @@ A simple way to get the commit message from a commit when you have the SHA-1 val 檢查的邏輯是看看是否有任何的提交在舊版本(revision)裡能找到、但在新版本裡卻找不到。如果沒有,那這是一次純 fast-forward 的推送;如果有,那我們拒絕此次推送: - # 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 @@ -722,9 +775,9 @@ A simple way to get the commit message from a commit when you have the SHA-1 val 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 + [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 @@ -733,8 +786,8 @@ A simple way to get the commit message from a commit when you have the SHA-1 val 這裡有幾個有趣的資訊。首先,我們可以看到掛鉤執行的起點: - Enforcing Policies... - (refs/heads/master) (fb8c72) (c56860) + Enforcing Policies... + (refs/heads/master) (8338c5) (c5b616) 注意這是你在 update 腳本一開頭的地方印出到標準輸出的東西。所有從腳本印出到 stdout 的東西都會發送到用戶端,這點很重要。 @@ -860,7 +913,7 @@ A simple way to get the commit message from a commit when you have the SHA-1 val 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/zh-tw/08-git-and-other-scms/01-chapter8.markdown b/zh-tw/08-git-and-other-scms/01-chapter8.markdown index f781e3201..32bcd7acb 100644 --- a/zh-tw/08-git-and-other-scms/01-chapter8.markdown +++ b/zh-tw/08-git-and-other-scms/01-chapter8.markdown @@ -29,14 +29,14 @@ Git 中所有 Subversion 橋接命令的基礎是 `git svn` 。所有的命令 然後,允許所有用戶修改 revprop —— 簡單的做法是添加一個總是以 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`,參數加目標倉庫,再加來源倉庫,就可以把該專案同步到本地了: - $ svnsync init file:///tmp/test-svn http://progit-example.googlecode.com/svn/ + $ svnsync init file:///tmp/test-svn http://progit-example.googlecode.com/svn/ 這將建立進行同步所需的屬性(property)。可以通過執行以下命令來 clone 程式碼: @@ -282,7 +282,7 @@ Git 通過搜尋提交歷史中 Subversion 分支的頭部(tip)來決定 dcommit ------------------------------------------------------------------------ r85 | schacon | 2009-05-02 16:00:09 -0700 (Sat, 02 May 2009) | 2 lines - + updated the changelog 關於 `git svn log` ,有兩點需要注意。首先,它可以離線工作,不像 `svn log 命令`,需要向 Subversion 伺服器索取資料。其次,它僅僅顯示已經提交到 Subversion 伺服器上的 commit。在本地尚未 dcommit 的 Git 資料不會出現在這裡;其他人向 Subversion 伺服器新提交的資料也不會顯示。等於說是顯示了最近已知 Subversion 伺服器上的狀態。 @@ -291,19 +291,19 @@ Git 通過搜尋提交歷史中 Subversion 分支的頭部(tip)來決定 dcommit 類似 `git svn log` 命令模擬了 `svn log` 命令的離線操作,`svn annotate` 的等效命令是 `git svn blame [檔案名]`。其輸出如下: - $ 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 同樣,它不顯示本地的 Git 提交以及 Subversion 上後來更新的內容。 @@ -370,7 +370,7 @@ Git 通過搜尋提交歷史中 Subversion 分支的頭部(tip)來決定 dcommit 為 `git svn` 提供該檔可以讓它更精確的映射作者資料。你還可以在 `clone` 或者 `init` 後面添加 `--no-metadata` 來阻止 `git svn` 包含那些 Subversion 的附加資訊。這樣 `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 現在 `my_project` 目錄下導入的 Subversion 應該比原來整潔多了。原來的 commit 看上去是這樣: @@ -383,7 +383,6 @@ Git 通過搜尋提交歷史中 Subversion 分支的頭部(tip)來決定 dcommit git-svn-id: https://my-project.googlecode.com/svn/trunk@94 4c93b258-373f-11de- be05-5f7a86268029 - 現在是這樣: commit 03a8785f44c8ea5cdb0e8834b7c8e6c469be2ff2 @@ -411,6 +410,7 @@ Git 通過搜尋提交歷史中 Subversion 分支的頭部(tip)來決定 dcommit 現在所有的舊分支都變成真正的 Git 分支,所有的舊標籤也變成真正的 Git 標籤。最後一項工作就是把新建的 Git 伺服器添加為遠端伺服器並且向它推送。為了讓所有的分支和標籤都得到上傳,我們使用這條命令: $ git push origin --all + $ git push origin --tags 所有的分支和標籤現在都應該整齊乾淨的躺在新的 Git 伺服器裡了。 @@ -510,7 +510,7 @@ Git 通過搜尋提交歷史中 Subversion 分支的頭部(tip)來決定 dcommit 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 @@ -605,7 +605,7 @@ Git 通過搜尋提交歷史中 Subversion 分支的頭部(tip)來決定 dcommit 搞定了。現在執行該腳本,你將得到如下內容: - $ ruby import.rb /opt/import_from + $ ruby import.rb /opt/import_from commit refs/heads/master mark :1 committer Scott Chacon 1230883200 -0700 diff --git a/zh-tw/09-git-internals/01-chapter9.markdown b/zh-tw/09-git-internals/01-chapter9.markdown index f10253059..1da300664 100644 --- a/zh-tw/09-git-internals/01-chapter9.markdown +++ b/zh-tw/09-git-internals/01-chapter9.markdown @@ -16,7 +16,7 @@ 當你在一個新目錄或已有目錄內執行 `git init` 時,Git 會創建一個 `.git` 目錄,幾乎所有 Git 儲存和操作的內容都位於該目錄下。如果你要備份或複製一個倉庫,基本上將這一目錄拷貝至其他地方就可以了。本章基本上都討論該目錄下的內容。該目錄結構如下: - $ ls + $ ls HEAD branches/ config @@ -54,7 +54,7 @@ Git 初始化了 `objects 目錄`,同時在該目錄下創建了 `pack` 和 `i 參數 `-w` 指示 `hash-object` 命令儲存 (資料) 物件,若不指定這個參數該命令僅僅回傳鍵值。`--stdin` 指定從標準輸入裝置 (stdin) 來讀取內容,若不指定這個參數,`hash-object` 就需要指定一個要儲存的檔案路徑。該命令輸出長度為 40 個字元的校驗和(checksum hash)。這是個 SHA-1 雜湊值──其值為要儲存的資料加上你馬上會瞭解到的一種頭資訊(header)的校驗和。現在可以查看到 Git 已經儲存了資料: - $ find .git/objects -type f + $ find .git/objects -type f .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 可以在 `objects` 目錄下看到一個檔。這便是 Git 儲存資料內容的方式──為每份內容生成一個檔,取得該內容與頭資訊的 SHA-1 校驗和,創建以該校驗和前兩個字元為名稱的子目錄,並以 (校驗和) 剩下 38 個字元為檔命名 (保存至子目錄下)。 @@ -67,32 +67,32 @@ Git 初始化了 `objects 目錄`,同時在該目錄下創建了 `pack` 和 `i 可以往 Git 中添加更多內容並取回了。也可以直接添加檔案。比方說可以對一個檔進行簡單的版本控制。首先,創建一個新檔,並把檔案內容儲存到資料庫中: $ echo 'version 1' > test.txt - $ git hash-object -w test.txt + $ git hash-object -w test.txt 83baae61804e65cc73a7201a7252750c76066a30 接著往該檔中寫入一些新內容並再次保存: $ echo 'version 2' > test.txt - $ git hash-object -w test.txt + $ git hash-object -w test.txt 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a 資料庫中已經將檔案的兩個新版本連同一開始的內容保存下來了: - $ find .git/objects -type f + $ find .git/objects -type f .git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a .git/objects/83/baae61804e65cc73a7201a7252750c76066a30 .git/objects/d6/70460b4b4aece5915caf5c68d12f560a9fe3e4 再將檔案修復到第一個版本: - $ 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 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > test.txt - $ cat test.txt + $ git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a > test.txt + $ cat test.txt version 2 需要記住的是幾個版本的檔 SHA-1 值可能與實際的值不同,其次,儲存的並不是檔案名而僅僅是檔案內容。這種物件類型稱為 blob 。通過傳遞 SHA-1 值給 `cat-file -t` 命令可以讓 Git 返回任何物件的類型: @@ -116,7 +116,7 @@ Git 初始化了 `objects 目錄`,同時在該目錄下創建了 `pack` 和 `i 從概念上來講,Git 保存的資料如圖 9-1 所示。 -Insert 18333fig0901.png +Insert 18333fig0901.png Figure 9-1. Git 物件模型的簡化版 你可以自己創建 tree 。通常 Git 根據你的暫存區域或 index 來創建並寫入一個 tree 。因此要創建一個 tree 物件的話首先要通過將一些檔暫存從而創建一個 index 。可以使用 plumbing 命令 `update-index` 為一個單獨檔 ── test.txt 檔的第一個版本 ── 創建一個 index。通過該命令人工地將 test.txt 檔的首個版本加入到了一個新的暫存區域中。由於該檔原先並不在暫存區域中 (甚至就連暫存區域也還沒被創建出來呢),必須傳入 `--add` 參數;由於要添加的檔並不在目前的目錄下而是在資料庫中,必須傳入 `--cacheinfo` 參數。同時指定檔案模式,SHA-1 值和檔案名: @@ -141,8 +141,8 @@ Figure 9-1. Git 物件模型的簡化版 再根據 test.txt 的第二個版本以及一個新檔創建一個新 tree 物件: $ echo 'new file' > new.txt - $ git update-index test.txt - $ git update-index --add new.txt + $ git update-index test.txt + $ git update-index --add new.txt 這時暫存區域中包含了 test.txt 的新版本及一個新檔 new.txt 。創建 (寫) 該 tree 物件 (將暫存區域或 index 狀態寫入到一個 tree 物件),然後瞧瞧它的樣子: @@ -164,7 +164,7 @@ Figure 9-1. Git 物件模型的簡化版 如果從剛寫入的新 tree 物件創建一個工作目錄,將得到位於工作目錄頂級的兩個檔和一個名為 `bak` 的子目錄,該子目錄包含了 test.txt 檔的第一個版本。可以將 Git 用來包含這些內容的資料想像成如圖 9-2 所示的樣子。 -Insert 18333fig0902.png +Insert 18333fig0902.png Figure 9-2. 當前 Git 資料的內容結構 ### Commit 物件 ### @@ -241,7 +241,7 @@ commit 物件格式很簡單:指明了該時間點專案快照的頂層樹物 如果你按照以上描述進行了操作,可以得到如圖 9-3 所示的物件圖。 -Insert 18333fig0903.png +Insert 18333fig0903.png Figure 9-3. Git 目錄下的所有物件 ### 物件儲存 ### @@ -326,7 +326,7 @@ Git 用 zlib 對資料內容進行壓縮,在 Ruby 中可以用 zlib 程式庫 現在,你的 Git 資料庫應該看起來像圖 9-4 一樣。 -Insert 18333fig0904.png +Insert 18333fig0904.png Figure 9-4. 包含分支引用的 Git 目錄物件 每當你執行 `git branch (分支名稱)` 這樣的命令,Git 基本上就是執行 `update-ref` 命令,把你現在所在分支中最後一次提交的 SHA-1 值,添加到你要創建的分支的引用。 @@ -335,12 +335,12 @@ Figure 9-4. 包含分支引用的 Git 目錄物件 現在的問題是,當你執行 `git branch (分支名稱)` 這條命令的時候,Git 怎麼知道最後一次提交的 SHA-1 值呢?答案就是 HEAD 檔。HEAD 檔是一個指向你當前所在分支的引用識別字。這樣的引用識別字——它看起來並不像一個普通的引用——其實並不包含 SHA-1 值,而是一個指向另外一個引用的指標。如果你看一下這個檔,通常你將會看到這樣的內容: - $ cat .git/HEAD + $ cat .git/HEAD ref: refs/heads/master 如果你執行 `git checkout test`,Git 就會更新這個檔,看起來像這樣: - $ cat .git/HEAD + $ cat .git/HEAD ref: refs/heads/test 當你再執行 `git commit` 命令,它就創建了一個 commit 物件,把這個 commit 物件的父級設置為 HEAD 指向的引用的 SHA-1 值。 @@ -353,7 +353,7 @@ Figure 9-4. 包含分支引用的 Git 目錄物件 你也可以設置 HEAD 的值: $ git symbolic-ref HEAD refs/heads/test - $ cat .git/HEAD + $ cat .git/HEAD ref: refs/heads/test 但是你不能設置成 refs 以外的形式: @@ -375,7 +375,7 @@ Figure 9-4. 包含分支引用的 Git 目錄物件 這是所創建物件的 SHA-1 值: - $ cat .git/refs/tags/v1.1 + $ cat .git/refs/tags/v1.1 9585191f37f7b0fb9444f35a9bf50de191beadc2 現在你可以執行 `cat-file` 命令檢查這個 SHA-1 值: @@ -409,7 +409,7 @@ Git 原始程式碼裡的公開金鑰. Linux kernel 也有一個不是指向 com 然後查看 `refs/remotes/origin/master` 這個檔,你就會發現 `origin` remote 中的 `master` 分支就是你最後一次和伺服器的通信。 - $ cat .git/refs/remotes/origin/master + $ cat .git/refs/remotes/origin/master ca82a6dff817ec66f44342007202690a93763949 Remote references 和分支(`refs/heads` references)的主要區別在於他們是不能被 check out 的。Git 把他們當作是標記了這些分支在伺服器上最後狀態的一種書簽。 @@ -433,8 +433,8 @@ Remote references 和分支(`refs/heads` references)的主要區別在於他們 Git 用 zlib 壓縮檔案內容,因此這些檔並沒有佔用太多空間,所有檔加起來總共僅用了 925 位元組。接下去你將添加一些大檔以演示 Git 的一個很有意思的功能。將你之前用到過的 Grit 庫中的 repo.rb 檔加進去 ── 這個原始程式碼檔大小約為 12K: - $ curl http://github.com/mojombo/grit/raw/master/lib/grit/repo.rb > repo.rb - $ git add 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 3 files changed, 459 insertions(+), 2 deletions(-) @@ -451,8 +451,8 @@ Git 用 zlib 壓縮檔案內容,因此這些檔並沒有佔用太多空間, 然後可以用 `git cat-file` 命令查看這個物件有多大: - $ git cat-file -s 9bc1dc421dcd51b4ac296e3e5b6e2a99cf44391e - 12898 + $ du -b .git/objects/9b/c1dc421dcd51b4ac296e3e5b6e2a99cf44391e + 4102 .git/objects/9b/c1dc421dcd51b4ac296e3e5b6e2a99cf44391e 稍微修改一下些檔,看會發生些什麼: @@ -470,8 +470,8 @@ Git 用 zlib 壓縮檔案內容,因此這些檔並沒有佔用太多空間, blob 物件與之前的已經不同了。這說明雖然只是往一個 400 行的檔最後加入了一行內容,Git 卻用一個全新的物件來保存新的檔案內容: - $ git cat-file -s 05408d195263d853f09dca71d55116663690c27c - 12908 + $ du -b .git/objects/05/408d195263d853f09dca71d55116663690c27c + 4109 .git/objects/05/408d195263d853f09dca71d55116663690c27c 你的磁片上有了兩個幾乎完全相同的 12K 的物件。如果 Git 只完整保存其中一個,並保存另一個物件的差異內容,豈不更好? @@ -784,8 +784,8 @@ Git 會不定時地自動執行稱為「auto gc」的命令。大部分情況下 這時如果執行 `git gc`, `refs` 下的所有檔都會消失。Git 會將這些檔挪到 `.git/packed-refs` 檔中去以提高效率,該檔是這個樣子的: - $ 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 @@ -858,7 +858,7 @@ Git 會不定時地自動執行稱為「auto gc」的命令。大部分情況下 酷!這樣有了一個跟原來 `master` 一樣的 `recover-branch` 分支,最新的兩個 commit 又找回來了。 接著,假設引起 commit 丟失的原因並沒有記錄在 reflog 中 ── 可以通過刪除 `recover-branch` 和 reflog 來類比這種情況。這樣最新的兩個 commit 不會被任何東西引用到: - $ git branch –D recover-branch + $ git branch -D recover-branch $ rm -Rf .git/logs/ 因為 reflog 資料是保存在 `.git/logs/` 目錄下的,這樣就沒有 reflog 了。現在要怎樣恢復 commit 呢?辦法之一是使用 `git fsck` 工具,該工具會檢查倉庫的資料完整性。如果指定 `--full` 選項,該命令顯示所有未被其他物件引用 (指向) 的所有物件: @@ -890,7 +890,7 @@ Git 有許多過人之處,不過有一個功能有時卻會帶來問題:`git 喔,你並不想往專案中加進一個這麼大的 tar 包。最後還是去掉它: - $ git rm git.tbz2 + $ git rm git.tbz2 rm 'git.tbz2' $ git commit -m 'oops - removed large tarball' [master da3f30d] oops - removed large tarball From 7db428809dc29eae70eaa6b67ddc692189de2523 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 2 Feb 2014 20:17:44 -0600 Subject: [PATCH 147/690] Reviewing "Private Small Team" --- it/05-distributed-git/01-chapter5.markdown | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 19cb4562c..0f12e0670 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -107,12 +107,12 @@ Se tutti i tuoi messaggi di commit fossero così, per te e gli altri sviluppator Nei esempi che seguono e nella maggior parte di questo libro, per brevità, non formatterò i messaggi accuratamente come descritto: userò invece l'opzione `-m` di `git commit`. Fa' come dico, non come faccio. -### Piccoli team privati ### +### Piccoli gruppi privati ### -La configurazione più semplice e facile da incontrare è il progetto privato con uno o due sviluppatori. Con privato, intendo codice a sorgente chiuso - non accessibile dal resto del mondo. Tu e gli altri sviluppatori avete tutti accesso per il push verso il repository. +La configurazione più semplice che è più facile che incontrerai è quella del progetto privato con uno o due sviluppatori. Con privato intendo codice a sorgente chiuso: non accessibile al resto del mondo. Tu e gli altri sviluppatori avete accesso in scrittura al repository. -In questo ambiente, puoi utilizzare un workflow simile a quello che magari stai già usando con Subversion od un altro sistema centralizzato. Hai ancora i vantaggi (ad esempio) di poter eseguire commit da offline e la creazione di rami (ed unione degli stessi) molto più semplici, ma il workflow può restare simile; la differenza principale è che, nel momento del commit, l'unione avviene nel tuo repository piuttosto che in quello sul server. -Vediamo come potrebbe essere la situazione quando due sviluppatori iniziano a lavorare insieme con un repository condiviso. Il primo sviluppatore, John, clona in repository, fa dei cambiamenti ed esegue il commit localmente. (Sostituisco il messaggio di protocollo con `...` in questi esempi per brevità.) +Con questa configurazione, puoi utilizzare un workflow simile a quello che magari stai già usando con Subversion o un altro sistema centralizzato. Hai comunque i vantaggi (ad esempio) di poter eseguire commit da offline e la creazione di rami (ed unione degli stessi) molto più semplici, ma il workflow può restare simile; la differenza principale è che, nel momento del commit, l'unione avviene nel tuo repository piuttosto che in quello sul server. +Vediamo come potrebbe essere la situazione quando due sviluppatori iniziano a lavorare insieme con un repository condiviso. Il primo sviluppatore, John, clona in repository, fa dei cambiamenti ed esegue il commit localmente. (In questi esempi sostituirò, per brevità, il messaggio del protocollo con `...`) # Computer di John $ git clone john@githost:simplegit.git @@ -124,7 +124,7 @@ Vediamo come potrebbe essere la situazione quando due sviluppatori iniziano a la [master 738ee87] rimosso valore di default non valido 1 files changed, 1 insertions(+), 1 deletions(-) -Il secondo sviluppatore, Jessica, fa la stessa cosa - clona il repository ed esegue dei cambiamenti: +Il secondo sviluppatore, Jessica, fa la stessa cosa - clona il repository e committa le modifiche: # Computer di Jessica $ git clone jessica@githost:simplegit.git @@ -136,7 +136,7 @@ Il secondo sviluppatore, Jessica, fa la stessa cosa - clona il repository ed ese [master fbff5bc] aggiunto il processo di reset 1 files changed, 1 insertions(+), 0 deletions(-) -Ora, Jessica esegue un push del suo lavoro nel server: +Ora, Jessica invia il suo lavoro al server con una push: # Computer di Jessica $ git push origin master @@ -144,7 +144,7 @@ Ora, Jessica esegue un push del suo lavoro nel server: To jessica@githost:simplegit.git 1edee6b..fbff5bc master -> master -Anche John cerca di eseguire un push: +Anche John cerca di eseguire una push: # Computer di John $ git push origin master @@ -152,7 +152,7 @@ Anche John cerca di eseguire un push: ! [rejected] master -> master (non-fast forward) error: failed to push some refs to 'john@githost:simplegit.git' -A John non è consentito eseguire un push perché Jessica ha fatto lo stesso nel frattempo. Questo è particolarmente importante se sei abituato a Subversion, perché avrai notato che i due sviluppatori non hanno modificato lo stesso file. Anche se Subversion automaticamente esegue questa unione nel server se differenti file sono stati modificati, in Git devi unire i cambiamenti localmente. John deve recuperare i cambiamenti di Jessica ed unirli ai suoi prima di poter eseguire il push: +A John non è permesso fare un push perché nel frattempo lo ha già fatto Jessica. Questo è particolarmente importante se sei abituato a Subversion, perché vedrai che i due sviluppatori non hanno modificato lo stesso file. Sebbene Subversion unisca automaticamente sul server queste commit se i file modificati sono diversi, in Git sei tu che devi farlo localmente. John deve quindi scaricare le modifiche di Jessica e unirle alle sue prima di poter fare una push: $ git fetch origin ... @@ -164,29 +164,29 @@ A questo punto, il repository locale di John somiglia a quello di figura 5-4. 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: +John sa quali sono le modifiche di Jessica, ma deve unirle alle sue prima poter fare una push: $ git merge origin/master Merge made by recursive. TODO | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) -L'unione fila liscia - ora la cronologia dei commit di John sarà come quella di Figura 5-5. +L'unione fila liscia e ora la cronologia delle commit di John sarà come quella di Figura 5-5. 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: +John ora può testare il suo codice per essere sicuro che continui a funzionare correttamente e può quindi eseguire la push del tutto sul server: $ git push origin master ... To john@githost:simplegit.git fbff5bc..72bbc59 master -> master -Infine, la cronologia dei commit di John somiglierà a quella di figura 5-6. +La cronologia dei commit di John somiglierà quindi a quella di figura 5-6. Insert 18333fig0506.png -Figura 5-6. La cronologia di John dopo avere eseguito il push verso il server. +Figura 5-6. La cronologia di John dopo avere eseguito la 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. From 6302a8995f4875763023b006a8af766c24e04bc2 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 2 Feb 2014 20:20:30 -0600 Subject: [PATCH 148/690] Reviewing "Private Small Team" --- it/05-distributed-git/01-chapter5.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 0f12e0670..a678c5d34 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -188,7 +188,7 @@ La cronologia dei commit di John somiglierà quindi a quella di figura 5-6. Insert 18333fig0506.png Figura 5-6. La cronologia di John dopo avere eseguito la 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. +Jessica nel frattempo sta lavorando a un altro ramo. Ha creato un branch chiamato `problema54` e ha eseguito tre commit su quel branch. Poiché non ha ancora recuperato le modifiche di John la sua cronologia è quella della Figura 5-7. Insert 18333fig0507.png Figura 5-7. La cronologia iniziale di Jessica. From e342ad89628b185f1ef1e3396b0c03cde36cd87e Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 2 Feb 2014 20:27:59 -0600 Subject: [PATCH 149/690] Reviewing "Private Small Team" --- it/05-distributed-git/01-chapter5.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index a678c5d34..7ba146e47 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -193,7 +193,7 @@ Jessica nel frattempo sta lavorando a un altro ramo. Ha creato un branch chiamat Insert 18333fig0507.png Figura 5-7. La cronologia iniziale di Jessica. -Jessica vuole sincronizzarsi con John, così recupera: +Jessica vuole sincronizzarsi con John, quindi esegue: # Computer di Jessica $ git fetch origin @@ -201,12 +201,12 @@ Jessica vuole sincronizzarsi con John, così recupera: From jessica@githost:simplegit fbff5bc..72bbc59 master -> origin/master -Questo recupera il lavoro che John ha eseguito nel frattempo. La cronologia di Jessica ora è quella di Figura 5-8. +Con cui recupera il lavoro che nel frattempo John ha eseguito. La cronologia di Jessica ora è quella di Figura 5-8. 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: +Jessica pensa che il suo ramo sia pronto, però vuole sapere con cosa deve unire il suo lavoro prima di eseguire la push. Esegue quindi `git log` per scoprirlo: $ git log --no-merges origin/master ^problema54 commit 738ee872852dfaa9d6634e0dea7a324040193016 From f53c5b716b14aacda42385a91d2b61f8241c5472 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 2 Feb 2014 21:01:37 -0600 Subject: [PATCH 150/690] Reviewing "Private Small Team" --- it/05-distributed-git/01-chapter5.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 7ba146e47..3cb60305b 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -215,13 +215,13 @@ Jessica pensa che il suo ramo sia pronto, però vuole sapere con cosa deve unire rimosso valore di default non valido -Ora, Jessica può unire il suo lavoro al ramo master, unire il lavoro di John (`origin/master`) nel suo ramo `master`, e poi eseguire il push verso il server di nuovo. Per prima cosa, torna nel suo ramo master per integrare il suo lavoro: +Ora, Jessica può unire il lavoro del suo branch nel suo master, quindi le modifiche di John (`origin/master`) nel suo branch `master`, e ritrasmettere il tutto al server con una push. Per prima cosa torna al suo branch master per integrare il lavoro svolto nell'altro branch: $ git checkout master Switched to branch "master" Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded. -Può unire sia `origin/master` che `problema54` per primo - sono entrambi a monte, per cui l'ordine non conta. Il risultato finale sarà lo stesso a prescindere dall'ordine scelto; solo la cronologia sarà leggermente differente. Lei sceglie di unire `problema54` per primo: +Può decidere di unire prima `origin/master` o `problema54`: entrambi sono flussi principali, per cui non conta l'ordine. Il risultato finale sarà lo stesso a prescindere dall'ordine scelto, ma la cronologia sarà leggermente differente. Lei sceglie di fare il merge prima di `problema54`: $ git merge problema54 Updating fbff5bc..4af4298 @@ -230,7 +230,7 @@ Può unire sia `origin/master` che `problema54` per primo - sono entrambi a mont lib/simplegit.rb | 6 +++++- 2 files changed, 6 insertions(+), 1 deletions(-) -Non ci sono problemi; come puoi vederem è stato tutto semplice. Ora Jessica unisce il lavoro di John (`origin/master`): +Non ci sono stati problemi: come puoi vedere tutto è stato molto semplice. Quindi Jessica unisce il lavoro di John (`origin/master`): $ git merge origin/master Auto-merging lib/simplegit.rb From c1c856b3e9df1306fd3b9fd361d2229d91b4bbd9 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 2 Feb 2014 21:08:07 -0600 Subject: [PATCH 151/690] Reviewing "Private Small Team" --- it/05-distributed-git/01-chapter5.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 3cb60305b..ad62b3e65 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -243,14 +243,14 @@ Tutto viene unito correttamente, e la cronologia di Jessica è come quella di Fi 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): +Ora `origin/master` è raggiungibile dal ramo `master` di Jessica, cosicché lei sia capace di eseguire delle push con successo (supponendo che John non abbia fatto altre push nel frattempo): $ git push origin master ... To jessica@githost:simplegit.git 72bbc59..8059c15 master -> master -Ogni sviluppatore ha eseguito alcuni commit ed unito il proprio lavoro con quello di altri con successo; vedi Figura 5-10. +Ogni sviluppatore ha eseguito alcune commit ed unito con successo il proprio lavoro con quello degli altri; vedi Figura 5-10. Insert 18333fig0510.png Figura 5-10. La cronologia di Jessica dopo aver eseguito il push dei cambiamenti verso il server. From 81a2a1fde1c99681a8f6cae7691f74076e7d45c2 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 2 Feb 2014 21:19:06 -0600 Subject: [PATCH 152/690] Reviewed "Private Small Team" --- it/05-distributed-git/01-chapter5.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index ad62b3e65..3524f807a 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -255,10 +255,10 @@ Ogni sviluppatore ha eseguito alcune commit ed unito con successo il proprio lav Insert 18333fig0510.png Figura 5-10. La cronologia di Jessica dopo aver eseguito il push dei cambiamenti verso il server. -Questo è uno dei workflow più semplici. Lavori per un pò, generalmente in un ramo, ed unisci il tutto al ramo master questo è pronto ad essere integrato. Quando vuoi condividere il tuo lavoro, uniscilo al tuo ramo master, poi recupera ed unisci `origin/master` se è cambiato, ed infine esegui il push verso il ramo `master` nel server. La sequenza è simile a quella di Figura 5-11. +Questo è uno dei workflow più semplici. Lavori per un po', generalmente in un branch, ed unisci il tutto al branch master quando è pronto per essere integrato. Quando vuoi condividere questo lavoro lo unisci al tuo branch master e poi scarichi ed unisci `origin/master`, se è cambiato, e infine esegui la push verso il branch `master` nel server. La sequenza è simile a quella in Figura 5-11. Insert 18333fig0511.png -Figura 5-11. La sequenza generale di eventi per un semplice workflow con Git a più sviluppatori. +Figura 5-11. La sequenza generale di eventi per un workflow semplice con Git a più sviluppatori. ### Team privato con manager ### From 23c4b8e03610d461f93328b915a5f4c69fc243a2 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 2 Feb 2014 21:41:21 -0600 Subject: [PATCH 153/690] Reviewing "Private Managed Team" --- it/05-distributed-git/01-chapter5.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 3524f807a..e7b7bac44 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -262,9 +262,9 @@ Figura 5-11. La sequenza generale di eventi per un workflow semplice con Git a p ### Team privato con manager ### -In questo prossimo scenario, scoprirai ai ruoli di un contributore in un gruppo privato più grande. Imparerai come lavorare in un ambiente dove piccoli gruppi collaborano a delle funzionalità e poi queste contribuzioni sono integrate da un altro componente. +In questo scenario, scoprirai i ruoli di contributore in un gruppo privato più grande. Imparerai come lavorare in un ambiente dove gruppi piccoli collaborano a delle funzionalità e poi queste contribuzioni sono integrate da un altra persona. -Supponiamo che John e Jessica stiano lavorando insieme su una funzionalità, mentre Jessica e Josie si stanno concentrando su una seconda. In questo caso, l'azienda sta usando un workflow con manager d'integrazione dove il lavoro di ogni gruppo è integrato solo da certi ingegneri, ed il ramo `master` del repository principale può essere aggiornato solo dai suddetti ingegneri. In questo scenario, tutto il lavoro è eseguito sui rami suddivisi per team, ed unito dagli integratori in seguito. +Supponiamo che John e Jessica stiano lavorando insieme a una funzionalità, mentre Jessica e Josie si stiano concentrando a una seconda. In questo caso l'azienda sta usando un workflow con manager d'integrazione dove il lavoro di ogni gruppo è integrato solo da alcuni ingegneri, ed il branch `master` del repository principale può essere aggiornato solo da questi. In questo scenario, tutto il lavoro è eseguito sui rami suddivisi per team, e unito successivamente dagli integratori. Seguiamo il workflow di Jessica mentre lavora sulle due funzionalità, collaborando parallelamente con due diversi sviluppatori in questo ambiente. Assumendo che lei abbia già clonato il suo repository, decide di lavorare su `funzionalitaA` per prima. Crea un nuovo ramo per la funzionalità ed esegue del lavoro su di esso. From 8a76f5e5a71994639fa4bcdb8ab54fad50dee2a9 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 2 Feb 2014 21:50:30 -0600 Subject: [PATCH 154/690] Reviewing "Private Managed Team" --- it/05-distributed-git/01-chapter5.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index e7b7bac44..4ce2ad9da 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -266,7 +266,7 @@ In questo scenario, scoprirai i ruoli di contributore in un gruppo privato più Supponiamo che John e Jessica stiano lavorando insieme a una funzionalità, mentre Jessica e Josie si stiano concentrando a una seconda. In questo caso l'azienda sta usando un workflow con manager d'integrazione dove il lavoro di ogni gruppo è integrato solo da alcuni ingegneri, ed il branch `master` del repository principale può essere aggiornato solo da questi. In questo scenario, tutto il lavoro è eseguito sui rami suddivisi per team, e unito successivamente dagli integratori. -Seguiamo il workflow di Jessica mentre lavora sulle due funzionalità, collaborando parallelamente con due diversi sviluppatori in questo ambiente. Assumendo che lei abbia già clonato il suo repository, decide di lavorare su `funzionalitaA` per prima. Crea un nuovo ramo per la funzionalità ed esegue del lavoro su di esso. +Seguiamo il workflow di Jessica mentre lavora sulle due funzionalità, collaborando parallelamente con due diversi sviluppatori in questo ambiente. Assumendo che lei abbia già clonato il suo repository, decide di lavorare prima alla `funzionalitaA`. Crea un nuovo branch per la funzionalità e ci lavora. # Computer di Jessica $ git checkout -b featureA @@ -276,7 +276,7 @@ Seguiamo il workflow di Jessica mentre lavora sulle due funzionalità, collabora [featureA 3300904] aggiunto il limite alla funzione di log 1 files changed, 1 insertions(+), 1 deletions(-) -A questo punto, lei ha bisogno di condividere il suo lavoro con John, così lei esegue il push del ramo `funzionalitaA` sul server. Jessica non ha accesso per il push al ramo `master` - solo gli integratori ce l'hanno - perciò deve eseguire il push verso un altro ramo per poter collaborare con John: +A questo punto lei deve condividere il suo lavoro con John, così fa la push sul server del branch `funzionalitaA`. Poiché Jessica non ha permessi per fare la push sul ramo `master` (solo gli integratori ce l'hanno) deve perciò eseguire la push su un altro branch per poter collaborare con John: $ git push origin funzionalitaA ... From deb848b17345c681069856165bc53d6796a1d02f Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 2 Feb 2014 22:47:45 -0600 Subject: [PATCH 155/690] Reviewing "Private Managed Team" --- it/05-distributed-git/01-chapter5.markdown | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 4ce2ad9da..fbf85893c 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -283,14 +283,14 @@ A questo punto lei deve condividere il suo lavoro con John, così fa la push sul To jessica@githost:simplegit.git * [new branch] featureA -> featureA -Jessica manda una e-mail a John dicendogli che ha eseguito il push del suo lavoro in un ramo chiamato `funzioanlitaA` e lui può dargli un'occhiata. Mentre aspetta una risposta da John, Jessica decide di iniziare a lavorare su `funzionalitaB` con Josie. Per iniziare, crea un nuovo ramo basandosi sul ramo `master` del server: +Jessica manda una e-mail a John dicendogli che fatto la push del suo lavoro su un branch chiamato `funzioanlitaA` chiedendogli se lui può dargli un'occhiata. Mentre aspetta una risposta da John, Jessica decide di iniziare a lavorare su `funzionalitaB` con Josie. Per iniziare, crea un nuovo branch basandosi sul branch `master` del server: # Computer di Jessica $ git fetch origin $ git checkout -b featureB origin/master Switched to a new branch "featureB" -Ora, Jessica esegue un paio di commit sul ramo `funzionalitaB`: +Quindi Jessica esegue un paio di commit sul branch `funzionalitaB`: $ vim lib/simplegit.rb $ git commit -am 'resa la funzione ls-tree ricorsiva' @@ -304,10 +304,9 @@ Ora, Jessica esegue un paio di commit sul ramo `funzionalitaB`: Il repository di Jessica è come quello di Figura 5-12. Insert 18333fig0512.png -Figura 5.12. La cronologia iniziale dei commit di Jessica -Figure 5-12. Jessica’s initial commit history. +Figura 5.12. La cronologia iniziale delle commit di Jessica -Lei è pronta ad eseguire un push del proprio lavoro, ma riceve una e-mail da Josie la quale dice che una parte del lavoro era già stato messo nel server nel ramo chiamato `funzionalitaBee`. Jessica innanzitutto deve unire questi cambiamenti ai suoi prima di poter eseguire il push verso il server. Può recuperare il lavoro di Josie usando `git fetch`: +Quando è pronta a eseguire una push del proprio lavoro riceve una e-mail da Josie che le dice che una parte del lavoro era già stato caricato sul server nel branch chiamato `funzionalitaBee`. Jessica deve unire prima le modifiche al server alle sue per poter fare la push verso il server. Può recuperare il lavoro di Josie usando `git fetch`: $ git fetch origin ... @@ -322,7 +321,7 @@ Jessica ora può unire il suo lavoro a quello di Josie con `git merge`: lib/simplegit.rb | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) -C'è un problema - deve eseguire il push del suo ramo `funzionalitaB` verso il ramo `funzionalitaBee` nel server. Può farlo specificando il ramo locale seguito dal simbolo dei due punti (:) seguito a sua volta dal nome del ramo remoto destinazione del comando `git push`: +C'è un piccolo problema: deve fare la push del suo branch `funzionalitaB` sul branch `funzionalitaBee` del server. Può farlo specificando il branch locale seguito da due punti (:) seguito a sua volta dal nome del branch remoto di destinazione al comando `git push`: $ git push origin funzionalitaB:funzionalitaBee ... From 9e6e9422ded5e9ea3c1a94445f5e797488d7fe55 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 2 Feb 2014 22:53:03 -0600 Subject: [PATCH 156/690] Reviewing "Private Managed Team" --- it/05-distributed-git/01-chapter5.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index fbf85893c..f3342b8d4 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -328,25 +328,25 @@ C'è un piccolo problema: deve fare la push del suo branch `funzionalitaB` sul b To jessica@githost:simplegit.git fba9af8..cd685d1 featureB -> featureBee -Questo è chiamato _refSpec_. Vedi il capitolo 9 per una discussione più dettagliata sui refspec di Git ed altre cose che puoi fare con loro. +Questo è detto _refSpec_. Vedi il capitolo 9 per una discussione più dettagliata sui refspec di Git e cosa ci puoi fare. -Ora John manda una mail a Jessica dicendo che ha eseguito il push di alcuni cambiamenti sul ramo `funzionalitaA` e le chiede di controllarli. Lei esegue `git fetch` per recuperare questi cambiamenti: +John manda una mail a Jessica dicendole che ha fatto la push di alcune modifiche sul branch `funzionalitaA` e le chiede di controllarle. Lei esegue `git fetch` per scaricarle: $ git fetch origin ... From jessica@githost:simplegit 3300904..aad881d featureA -> origin/featureA -Ora, lei può vedere cos'è stato cambiato con `git log`: +E può vederle con `git log`: $ git log origin/funzionalitaA ^funzionalitaA commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6 Author: John Smith Date: Fri May 29 19:57:33 2009 -0700 - cambianto l'output del log da 30 a 25 + cambiato l'output del log da 25 a 30 -Finalmente, unisce il lavoro di John al suo sul ramo `funzionalitaA`: +Infine unisce il lavoro di John al suo nel branch `funzionalitaA`: $ git checkout funzionalitaA Switched to branch "funzionalitaA" From 5d789600a8aa6dffee5a67410caf3c38b8c4727b Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 2 Feb 2014 23:05:46 -0600 Subject: [PATCH 157/690] Reviewed "Private Managed Team" --- it/05-distributed-git/01-chapter5.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index f3342b8d4..5775605be 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -356,7 +356,7 @@ Infine unisce il lavoro di John al suo nel branch `funzionalitaA`: lib/simplegit.rb | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) -Jessica vuole aggiustare qualcosa, così esegue un altro commit ed un push verso il server: +Jessica vuole aggiustare qualcosa e fa un'altro commit ed una push verso il server: $ git commit -am 'leggero aggiustamento' [featureA ed774b3] leggero aggiustamento @@ -366,17 +366,17 @@ Jessica vuole aggiustare qualcosa, così esegue un altro commit ed un push verso To jessica@githost:simplegit.git 3300904..ed774b3 featureA -> featureA -Ora la cronologia dei commit di Jessica sarà come quella di Figura 5-13. +La cronologia delle commit di Jessica ora sarà come quella della Figura 5-13. Insert 18333fig0513.png -Figura 5-13. La cronologia di Jessica dopo aver eseguito il commit sul ramo. +Figura 5-13. La cronologia di Jessica dopo aver eseguito la commit sul branch. -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. +Jessica, Josie e John informano gli integratori che i rami `funzionalitaA` e `funzionalitaB` che sono sul server sono pronti per l'integrazione nel `master`. Dopo l'integrazione di questi branch nel `master`, una fetch scaricherà tutte queste nuove commit, rendendo la cronologia delle commit come quella della Figura 5.14. Insert 18333fig0514.png Figura 5.14. La cronologia di Jessica dopo aver unito entrambi i rami. -Molti gruppi migrano verso Git per la sua capacità di avere più team a lavorarare in parallelo, unendo le differenti linee di lavoro alla fine del processo. L'abilità di piccoli sotto gruppi di una squadra di collaborare tramite rami remoti senza necessariamente dover coinvolgere o ostacolare l'intero team è un grande beneficio di Git. La sequenza per il workflow che hai appena visto è rappresentata dalla Figura 5-15. +Molti gruppi migrano a Git per la sua capacità di avere gruppi che lavorino in parallelo, unendo le differenti righe di lavoro alla fine del processo. La possibilità che piccoli sottogruppi del team possano collaborare con branch remoti senza dover necessariamente coinvolgere o ostacolare l'intero team è un grande beneficio di Git. La sequenza del workflow che hai appena visto è rappresentata nella Figura 5-15. Insert 18333fig0515.png Figura 5-15. Sequenza base di questo workflow con team separati. From 6ca9042c139e16af7422bb24d5eb5373d69b6378 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Sun, 2 Feb 2014 23:10:47 -0600 Subject: [PATCH 158/690] Reviewing "Public Small Project" --- it/05-distributed-git/01-chapter5.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 5775605be..a21356ba6 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -383,7 +383,7 @@ Figura 5-15. Sequenza base di questo workflow con team separati. ### Piccolo progetto pubblico ### -Contribuire ad un progetto pubblico è leggermente differente. Dato che non hai il permesso di aggiornare direttamente i rami del progetto, devi far avere il tuo lavoro ai mantenitori in qualche altro modo. Questo esempio descrive la contribuzione via fork su host Git che lo supportano in maniera semplice. I siti repo.or.cz e GitHub lo supportano, e molti altri mantenitori di progetti si aspettano questo tipo di contribuzione. La prossima sezione si occupa di progetti che preferiscono accettare patch via e-mail +Contribuire ad un progetto pubblico è leggermente differente. Poiché non hai il permesso di aggiornare direttamente i rami del progetto, devi far avere il tuo lavoro ai mantenitori in qualche altro modo. Questo primo esempio descrive come contribuire con i fork su host Git che lo supportano in maniera semplice. I siti di repo.or.cz e GitHub lo supportano, e molti mantenitori di progetti si aspettano questo tipo di contribuzione. La sezione successiva tratta i progetti che preferiscono ricevere le patch per e-mail Innanzitutto, probabilemnte dovrai clonare il repository principale, creare un ramo per le modifiche che hai in programma di fare, e fare li il tuo lavoro. La sequenza è grosso modo questa: From f26f3cc0297ee4939da9fcdc3b62ac0891e3febb Mon Sep 17 00:00:00 2001 From: harupong Date: Mon, 3 Feb 2014 14:39:17 +0900 Subject: [PATCH 159/690] [ja] Apply #573 (bdef6f7) to ja tree --- 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 1690e53b3..e674e1d5f 100644 --- a/ja/03-git-branching/01-chapter3.markdown +++ b/ja/03-git-branching/01-chapter3.markdown @@ -458,7 +458,7 @@ Insert 18333fig0326.png Branch sf set up to track remote branch refs/remotes/origin/serverfix. Switched to a new branch "sf" -これで、ローカルブランチ sf が自動的に `origin/serverfix` を追跡するようになりました。 +これで、ローカルブランチ `sf` が自動的に `origin/serverfix` を追跡するようになりました。 ### リモートブランチの削除 ### From 617eb401bf743add90c82f392e2ba655b4b6a3ba Mon Sep 17 00:00:00 2001 From: Cor Date: Mon, 3 Feb 2014 10:36:54 +0100 Subject: [PATCH 160/690] [nl] Retranslate, remove Babelfishes and use diacritical characters. --- nl/07-customizing-git/01-chapter7.markdown | 419 ++++++++++++--------- 1 file changed, 241 insertions(+), 178 deletions(-) diff --git a/nl/07-customizing-git/01-chapter7.markdown b/nl/07-customizing-git/01-chapter7.markdown index 0d7a9c7a4..22fbee5e2 100644 --- a/nl/07-customizing-git/01-chapter7.markdown +++ b/nl/07-customizing-git/01-chapter7.markdown @@ -1,25 +1,25 @@ # Git op maat maken # -Tot zover heb ik de fundamentele werking van Git behandeld, en hoe het te gebruiken, en ik heb een aantal tools geïntroduceerd die Git levert om je het makkelijk en efficiënt te laten gebruiken. In dit hoofdstuk zal ik wat operaties doorlopen die je kunt gebruiken om Git op een persoonlijker manier te laten werken door een aantal belangrijke configuratie-instellingen te introduceren en het hakensysteem. Met deze gereedschappen is het makkelijk om Git precies te laten werken op de manier zoals jij, je bedrijf, of je groep het graag wil. +Tot zover heb ik de fundamentele werking van Git behandeld en hoe het te gebruiken, en ik heb een aantal tools geïntroduceerd die Git levert om je het makkelijk en efficiënt te laten gebruiken. In dit hoofdstuk zal ik wat operaties doorlopen die je kunt gebruiken om Git op een maat gemaakte manier te laten werken door een aantal belangrijke configuratie-instellingen te introduceren en het inhaak-systeem (hooks). Met deze gereedschappen is het makkelijk om Git precies te laten werken op de manier zoals jij, je bedrijf, of je groep het nodig hebben. ## Git configuratie ## -Zoals je kort in Hoofdstuk 1 gezien hebt, kun je Git configuratie instellingen specificeren met het `git config` commando. Een van de eerste dingen die je deed wat je naam en e-mail adres instellen: +Zoals je kort in Hoofdstuk 1 gezien hebt, kun je Git configuratie instellingen specificeren met het `git config` commando. Een van de eerste dingen die je deed was je naam en e-mail adres instellen: $ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com -Nu zul je een paar van de meer interessante opties leren, die je op deze manier kunt instellen om je Git op maat te maken. +Hierna zal je een paar van de meer interessante opties leren, die je op vergelijkbare manier kunt instellen om je Git op maat te maken. -Je zag wat eenvoudige Git configuratie details in het eerste hoofdstuk, maar ik zal ze hier nog eens snel laten zien. Git gebruikt een aantal configuratie bestanden om het niet-standaard gedrag dat je wil te bepalen. De eerste plaats waar Git kijkt voor deze waarden is in een `/etc/gitconfig` bestand, wat de waarden bevat voor alle gebruikers op het systeem en al hun repositories. Als je de optie `--system` aan `git config` meegeeft, leest en schrijft het specifiek naar dit bestand. +Je zag al wat eenvoudige Git configuratie details in het eerste hoofdstuk, en die zal ik hier snel nog eens laten zien. Git gebruikt een aantal configuratie bestanden om het niet-standaard gedrag dat je wilt te bepalen. De eerste plek waar Git kijkt voor deze waarden is in een `/etc/gitconfig` bestand, deze bevat de waarden voor alle gebruikers op het systeem en al hun repositories. Als je de optie `--system` aan `git config` meegeeft, leest en schrijft Git naar dit bestand. -De volgende plaats waar Git kijkt is het `~/.gitconfig` bestand, wat specifiek is voor iedere gebruiker. Je kunt er voor zorgen dat Git naar dit bestand leest en schrijft door de `--global` optie mee te geven. +De volgende plaats waar Git kijkt is het `~/.gitconfig` bestand, wat specifiek is voor elke gebruiker. Je kunt er voor zorgen dat Git naar dit bestand leest en schrijft door de `--global` optie mee te geven. -Als laatste kijkt Git naar configuratie waarden in het config bestand in de Git map (`.git/config`) of welk repository dat je op dat moment gebruikt. Deze waarden zijn specifiek voor dat ene repository. Ieder niveau overschrijft de waarden in het vorige niveau, dus waarden in `.git/config` gaan boven die in `/etc/gitconfig`, bijvoorbeeld. Je kunt die waarden ook instellen door het bestand handmatig aan te passen en de correcte syntax in te voegen, maar het is over het algemeen makkelijk m het `git config` commando uit te voeren. +Als laatste kijkt Git naar configuratie waarden in het config bestand in de Git directory (`.git/config`) van de repository dat op dat moment gebruikt wordt. Deze waarden zijn specifiek voor die ene repository. Ieder niveau overschrijft de waarden in het vorig, dus waarden in `.git/config` gaan voor op die in `/etc/gitconfig` bijvoorbeeld. Je kunt die waarden ook instellen door het bestand handmatig aan te passen en de correcte syntax te gebruiken, maar het is gewoon eenvoudiger het `git config` commando uit te voeren. ### Basis client configuratie ### -De configuratie opties die herkent worden door Git vallen binnen twee categorieën: de client kant en de server kant. De meerderheid van de opties zijn voor de client kant – de configuratie van je persoonlijke voorkeuren. Alhoewel er massa's opties beschikbaar zijn, zal ik alleen een paar behandelen die ofwel veelgebruikt zijn of je werkwijze significant kunnen beïnvloeden. Veel opties zijn alleen bruikbaar in randgevallen waar ik hier niet naar kijk. Als je een lijst van alle opties wil zien, die jou versie van Git herkent kun je dit uitvoeren +De configuratie opties die herkend worden door Git vallen in twee categorieën: de cliënt kant en de server kant. De meerderheid van de opties zijn voor de cliënt kant: de configuratie van je persoonlijke voorkeuren. Alhoewel er massa's opties beschikbaar zijn, zal ik er maar een paar behandelen die ofwel veelgebruikt zijn ofwel je werkwijze significant kunnen beïnvloeden. Veel opties zijn alleen van toepassing in randgevallen, die ik nu niet zal behandelen. Als je een lijst van alle opties wilt zien, die door jouw versie van Git worden herkend kan je dit uitvoeren $ git config --help @@ -27,15 +27,15 @@ De gebruikershandleiding voor `git config` toont alle beschikbare opties in groo #### core.editor #### -Standaard zal Git de standaard tekst editor gebruiken, die je hebt ingesteld of anders terugvallen op de Vi editor om je commit en tag boodschappen te maken of te wijzigen. Om die instelling naar iets anders om te zetten, kun je de `core.editor` instelling gebruiken: +Standaard zal Git de tekst editor gebruiken die je zelf ingesteld als standaard en anders valt Git terug op de Vi editor om je commit en tag boodschappen te maken of te wijzigen. Om die instelling naar iets anders om te zetten, kun je de `core.editor` instelling gebruiken: $ git config --global core.editor emacs -Zonder dat het uitmaakt wat je als je standaard shell editor waarde ingesteld hebt, zal Git Emacs starten om boodschappen aan te passen. +Nu maakt het niet uit wat je als je standaard shell editor waarde ingesteld hebt, en zal Git Emacs starten om boodschappen aan te passen. #### commit.template #### -Als je dit als een pad instelt dat naar een bestand op je systeem wijst, zal Git dat bestand als de standaard boodschap gebruiken als je commit. Bijvoorbeeld, stel dat je een sjabloon bestand aanmaakt als `$HOME/.gitmessage.txt` die er zo uitziet: +Als je hier het een pad instelt dat naar een bestand op je systeem wijst, zal Git dat bestand als de standaard boodschap gebruiken bij elke commit. Bijvoorbeeld, stel dat je een sjabloon bestand aanmaakt als `$HOME/.gitmessage.txt` die er zo uitziet: onderwerp regel @@ -43,12 +43,12 @@ Als je dit als een pad instelt dat naar een bestand op je systeem wijst, zal Git [ticket: X] -Om Git te vertellen dat het dit moet gebruiken als standaard boodschap dat in je editor moet verschijnen als je `git commit` uitvoert, stel je de `commit.template` configuratie waarde in: +Om Git te vertellen dat het dit moet gebruiken als standaard boodschap dat in de editor moet verschijnen als je `git commit` uitvoert, stel je de `commit.template` configuratie waarde in: $ git config --global commit.template $HOME/.gitmessage.txt $ git commit -Daarna zal je editor zoiets als dit openen als je standaard commit boodschap als je commit: +Daarna zal je editor zoiets als dit openen als je standaard commit boodschap bij een commit: onderwerp regel @@ -67,29 +67,29 @@ Daarna zal je editor zoiets als dit openen als je standaard commit boodschap als ~ ".git/COMMIT_EDITMSG" 14L, 297C -Als je een beleid hebt voor commit boodschappen, dan vergroot het plaatsen van een sjabloon voor dat beleid op je systeem en het configureren ervan voor Git om het als standaard te gebruiken de kans dat dat beleid met regelmaat gevolgd wordt. +Als je een beleid hebt voor commit boodschappen, dan vergroot het plaatsen van een sjabloon op je systeem en het configureren ervan als standaard te gebruiken binnen Git de kans dat het beleid ook daadwerkelijk wordt gevolgd. #### core.pager #### -De instelling voor 'core.pager' bepaald welke pagineer applicatie gebruikt wordt door Git om de uitvoer van `log` en `diff` weer te geven. Je kunt het instellen als `more` of als je favoriete pagineerder (standaard is het `less`), of je kunt het uit zetten door het als een lege tekst in te stellen: +De instelling voor 'core.pager' bepaalt welke pagineer tool gebruikt wordt door Git om de uitvoer van bijvoorbeeld `log` en `diff` weer te geven. Je kunt het instellen als `more` of als je favoriete pagineer tool (standaard is het `less`), of je kunt het uitzetten door het als een lege tekst in te stellen: $ git config --global core.pager '' -Als je dat uitvoert, zal Git de gehele uitvoer van alle commando's pagineren, hoe lang het ook is. +Als je dat uitvoert zal Git de gehele tekst van alle commando's ononderbroken tonen, ongeacht de lengte van die uitvoer. #### user.signingkey #### -Als je gebruik maakt van ondertekende tags (zoals besproken in Hoofdstuk 2), dan maakt het instellen van je GPG signeer sleutel als configuratie instelling het leven eenvoudiger. Stel je sleutel ID zo in: +Als je gebruik maakt van ondertekende tags (zoals besproken in Hoofdstuk 2), dan maakt het instellen van een GPG signeersleutel als configuratie instelling je leven een stuk eenvoudiger. Stel je sleutel ID zo in: $ git config --global user.signingkey -Nu kun je je tags signeren zonder steeds je sleutel op te hoeven geven bij het `git tag` commando: +Nu kun je tags signeren zonder steeds je sleutel op te hoeven geven bij het `git tag` commando: $ git tag -s #### core.excludesfile #### -Je kunt patronen in het `.gitignore` bestand van je project zetten zodat Git ze niet ziet als ongevolgde bestanden of ze niet zal proberen te stagen als je `git add` op ze uitvoert, zoals besproken in Hoofdstuk 2. Maar als je wilt dat een ander bestand buiten je project die waarden of extra waarden bevat, kun je Git vertellen met de `core.excludesfile` vertellen waar dat bestand is. Stel het eenvoudigweg in als een pad naar een bestand dat een inhoud heeft dat vergelijkbaar is met wat een `.gitignore` bestand zou hebben. +Je kunt patronen in het `.gitignore` bestand van je project zetten zodat Git ze niet ziet als untracked bestanden en niet zal proberen ze te stagen als je `git add` op ze uitvoert, zoals besproken in Hoofdstuk 2. Maar als je wilt dat een ander bestand buiten je project die waarden of additionele waarden bevat, kan je Git vertellen met de `core.excludesfile` waarde waar dat bestand is. Stel het eenvoudigweg in als een pad naar een bestand met een inhoud dat vergelijkbaar is met wat een `.gitignore` bestand zou hebben. #### help.autocorrect #### @@ -105,67 +105,67 @@ Als je `het.autocorrect` op 1 instelt, zal Git automatisch het commando uitvoere ### Kleuren in Git ### -Git kan zijn uitvoer in je terminal kleuren, wat je kan helpen om de uitvoer snel en eenvoudig visueel te begrijpen. Een aantal opties kan je helpen om de kleuren naar je voorkeur in te stellen. +Git kan zijn uitvoer op de terminal in kleur tonen, wat kan helpen om de uitvoer snel en eenvoudig visueel te interpreteren. Een aantal opties kan helpen om de kleuren naar jouw voorkeur in te stellen. #### color.ui #### -Git zal automatisch het meeste van zijn uitvoer kleuren als je het vraagt. Je kunt erg specifiek zijn in wat je gekleurd wil en hoe; maar om alle standaard kleuren in de terminal aan te zetten, stel dan `color.ui` in op true: +Git zal automatisch het meeste van zijn uitvoer in kleur tonen als je het vraagt. Je kunt erg specifiek zijn in wat je gekleurd wilt hebben en hoe. Maar om alle standaard kleuren in de terminal aan te zetten, stel dan `color.ui` in op true: $ git config --global color.ui true -Als deze waarde ingesteld is, zal Git zijn uitvoer kleuren zodra deze naar een terminal gaat. Andere mogelijke opties zijn false, wat de uitvoer nooit kleurt, en always, wat de kleuren altijd weergeeft, zelfs als je Git commando's omleidt naar een bestand of naar een ander commando doorsluist. Deze instelling is toegevoegd in Git 1.5; als je een oudere versie hebt, zul je alle kleuren instellingen individueel in moeten stellen. +Als deze waarde ingesteld is, zal Git zijn uitvoer in kleur tonen zodra deze naar een terminal gaat. Andere mogelijke opties zijn false wat de uitvoer nooit kleurt, en always, wat de kleuren altijd weergeeft zelfs als je Git commando's uitvoert naar een bestand of deze naar een ander commando doorsluist (piping). -Je zult zelden `color.ui = always` willen. In de meeste scenario's, als je kleuren in je omgeleide uitvoer wil, kun je een `--color` vlag aan het Git commando meegeven om het te forceren kleuren te gebruiken. De `color.ui = true` instelling is vrijwel altijd hetgene je wil gebruiken. +Je zult zelden `color.ui = always` willen. In de meeste scenario's, als je kleuren in je omgeleide uitvoer wil, kan je een `--color` vlag aan het Git commando meegeven om het te forceren kleuren te gebruiken. De `color.ui = true` instelling is degene die je vrijwel altijd wilt gebruiken. #### `color.*` #### -Als je meer specifiek wil zijn welke commando's gekleurd moeten zijn en hoe, of je hebt een oudere versie, dan voorziet Git in woord specifieke kleuren instellingen. Ieder van deze kan worden ingesteld op `true`, `false` of `always`: +Als je meer specifiek wil zijn welke commando's gekleurd moeten zijn en hoe, dan voorziet Git in woordspecifieke kleuren instellingen. Elk van deze kan worden ingesteld op `true`, `false` of `always`: color.branch color.diff color.interactive color.status -Daarnaast heeft ieder van deze ook sub-instellingen die je kunt gebruiken om specifieke kleuren in te stellen voor delen van de uitvoer, als je iedere kleur wilt overschrijven. Bijvoorbeeld, om de meta informatie in je diff uitvoer in blauwe voorgrond, zwarte achtergrond en vetgedrukt in te stellen, kun je dit uitvoeren +Daarnaast heeft elk van deze ook sub-instellingen die je kunt gebruiken om specifieke kleuren in te stellen voor delen van de uitvoer, als je iedere kleur wilt overschrijven. Bijvoorbeeld, om de meta-informatie in je diff uitvoer in blauwe voorgrond, zwarte achtergrond en vetgedrukt in te stellen, kun je dit uitvoeren $ git config --global color.diff.meta “blue black bold” -Je kunt de kleur instellen op ieder van de volgende waarden: normal, black, red, green, yellow, blue, magenta, cyan, of white. Als je een attribuut wil hebben, zoals vetgedrukt in het vorige voorbeeld, kun je kiezen uit bold, dim, ul, blink en reverse. +Je kunt de kleur instellen op een van de volgende waarden: ’normal’, ’black’, ’red’, ’green’, ’yellow’, ’blue’, ’magenta’, ’cyan’, of ’white’. Als je een attribuut wil hebben, zoals vetgedrukt in het vorige voorbeeld, kun je kiezen uit ’bold’, ’dim’, ’ul’, ’blink’ en ’reverse’. -Zie de manpage van `git config` voor alle sub-instellingen die je kunt instellen, als je dat wil. +Zie de manpage van `git config` voor alle sub-instellingen die je kunt instellen, als je dat wilt. ### Externe merge en diff tools ### -Alhoewel Git een interne implementatie van diff heeft, die je tot nog toe gebruikte, kun je in plaats daarvan een extern tool instellen. Je kunt ook een grafisch samenvoeg conflict-oplossings tool instellen, in plaats van handmatig de conflicten op te moeten lossen. Ik zal nu demonstreren hoe je het Perforce Visuele Samenvoeg Tool (P4Merge) in moet stellen, om je diff en samenvoeg oplossingen te doen, omdat het een fijn grafisch tool is en omdat het gratis is. +Alhoewel Git een interne implementatie van diff heeft, die heb je tot nu toe gebruikt, kan je in plaats daarvan een extern tool instellen. Je kunt ook een grafisch merge conflict-oplossings tool instellen, in plaats van handmatig de conflicten op te moeten lossen. Ik zal nu demonstreren hoe je het Perforce Visuele Merge Tool (P4Merge) in moet stellen, om je diff en merge oplossingen te doen, omdat het een fijn grafisch tool is en omdat het gratis is. -P4Merge werkt op alle grote platformen als je dit wil proberen, dus je zou het moeten kunnen doen. Ik zal in de voorbeelden paden gebruiken die op Mac en Linux systemen werken; voor Windows moet je `/usr/local/bin` veranderen in een pad naar een uitvoerbaar bestand in je omgeving. +P4Merge werkt op alle grote platformen als je dit wil proberen, dus je zou het moeten kunnen doen. Ik zal in de voorbeelden paden gebruiken die op Mac en Linux systemen werken; voor Windows moet je `/usr/local/bin` veranderen in een pad naar een uitvoerbaar bestand op jouw machine. Je kunt P4Merge hier downloaden: http://www.perforce.com/perforce/downloads/component.html -Om te beginnen zul je externe wrapper scripts instellen om je commando's uit te voeren. Ik zal het Mac pad gebruiken voor de applicatie; in andere systemen zal het moeten wijzen naar waar de `p4merge` binary geïnstalleerd is. Stel een samenvoeg wrapper script in, genaamd `extMerge`, die je applicatie met alle meegegeven argumenten aanroept: +Om te beginnen ga je externe wrapper scripts instellen om de commando's uit te voeren. Ik zal het Mac pad gebruiken voor de applicatie; in andere systemen zal het moeten wijzen naar waar de `p4merge` binary geïnstalleerd is. Stel een merge wrapper script in, genaamd `extMerge`, die jouw applicatie met alle meegegeven argumenten aanroept: $ cat /usr/local/bin/extMerge #!/bin/sh /Applications/p4merge.app/Contents/MacOS/p4merge $* -De diff wrapper controleert dat er zeker zeven argumenten meegegeven zijn, en geeft twee ervan aan je samenvoeg script. Standaard geeft Git de volgende argumenten aan het diff programma mee: +De diff wrapper controleert dat er precies zeven argumenten meegegeven zijn, en geeft twee ervan aan het merge script. Standaard geeft Git de volgende argumenten aan het diff programma mee: - path old-file old-hex old-mode new-file new-hex new-mode + pad oud-bestand oude-hex oude-modus nieuwe-bestand nieuwe-hex nieuwe-modus -Omdat je alleen de `oude-bestand` en `nieuwe-bestand` argumenten wil, zul je het wrapper script gebruiken om degenen door te geven die je wil. +Omdat je alleen de `oude-bestand` en `nieuwe-bestand` argumenten wilt, zul je het wrapper script gebruiken om de juiste parameters door te geven. $ cat /usr/local/bin/extDiff #!/bin/sh [ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5" -Je moet er ook zeker van zijn dat deze tools uitvoerbaar zijn: +Je moet er ook zeker van zijn dat deze scripts uitvoerbaar zijn: $ sudo chmod +x /usr/local/bin/extMerge $ sudo chmod +x /usr/local/bin/extDiff -Nu kun je je config bestand instellen dat het je eigengemaakte samenvoeg en diff tools gebruikt. Dit wordt gedaan met een aantal eigen instellingen: `merge.tool` om Git te vertellen welke strategie hij moet gebruiken, `mergetool.*.cmd` om te specificeren hoe het het commando moet uitvoeren, `mergetool.trustExitCode` om Git te vertellen of de exit code van dat programma een succesvolle samenvoeging betekent of niet, en `diff.external` om Git te vertellen welk commando het moet uitvoeren voor diffs. Dus, je kunt of vier configuratie commando's uitvoeren +Nu kun je het config bestand instellen om de zelfgemaakte merge en diff tools te gebruiken. Dit wordt gedaan met een aantal instellingen: `merge.tool` om Git te vertellen welke strategie hij moet gebruiken, `mergetool.*.cmd` om te specificeren hoe het commando moet worden uitgevoerd, `mergetool.trustExitCode` om Git te vertellen of de exit code van dat programma een succesvolle merge betekent of niet, en `diff.external` om Git te vertellen welk commando het moet uitvoeren voor diffs. Dus, je kunt de vier configuratie commando's uitvoeren $ git config --global merge.tool extMerge $ git config --global mergetool.extMerge.cmd \ @@ -183,26 +183,26 @@ of je kunt je `~/.gitconfig` bestand aanpassen en deze regels toevoegen: [diff] external = extDiff -Nadat dit alles ingesteld is, zul je als je diff commando's zoals deze uitvoert: +Nadat dit alles ingesteld is, kan je diff commando's zoals deze uitvoeren: $ git diff 32d1776b1^ 32d1776b1 -in plaat van de uitvoer van diff op de commando regel, een instantie van P4Merge gestart door Git krijgen, wat er uitziet zoals in Figuur 7-1. +in plaats van de uitvoer van diff op de commando regel, wordt een instantie van P4Merge gestart door Git, en dat ziet er ongeveer uit als in Figuur 7-1. Insert 18333fig0701.png Figuur 7-1. P4Merge. -Als je twee branches probeert samen te voegen en je krijgt conflicten, dan kun je het `git mergetool` commando uitvoeren; het start P4Merge op om je het conflict op te laten lossen met behulp van dat GUI tool. +Als je twee branches probeert te mergen en je krijgt vervolgens merge conflicten, kan je het `git mergetool` commando uitvoeren. P4Merge wordt dan opgestart om je het conflict op te laten lossen met behulp van dat GUI tool. -Het aardige van deze wrapper opstelling is dat je je diff en merge tools eenvoudig aan kunt passen. Bijvoorbeeld, om je `extDiff` en `extMerge` tools in te stellen dat ze in plaats daarvan het KDiff3 tool uitvoeren, is het enige dat je moet doen je `extMerge` bestand aanpassen: +Het aardige van deze wrapper opstelling is dat je de diff en merge tools eenvoudig aan kunt passen. Bijvoorbeeld, om je `extDiff` en `extMerge` tools in te stellen dat ze bijvoorbeeld het KDiff3 tool uitvoeren, is het enige dat je moet doen het `extMerge` bestand aanpassen: $ cat /usr/local/bin/extMerge #!/bin/sh /Applications/kdiff3.app/Contents/MacOS/kdiff3 $* -Nu zal Git het KDiff3 tool gebruiken voor het tonen van diff en het oplossen van samenvoeg conflicten. +Nu zal Git het KDiff3 tool gebruiken voor het tonen van diff en het oplossen van merge conflicten. -Git is al ingesteld om een aantal andere conflict-oplossings tools te gebruiken zonder dat je de cmd configuratie in hoeft te stellen. Je kunt je merge tool op kdiff3 instellen, of opendiff, tkdiff, meld, xxdiff, emerge, vimdiff of gvimdiff. Als je niet geïnteresseerd bent in het gebruik van KDiff3 als diff, maar het liever alleen wilt gebruiken voor conflict oplossing, en het kdiff3 commando zit in je pad, dan kun je dit uitvoeren +Git is al ingesteld om een aantal andere mergeconflict-oplossings tools te gebruiken zonder dat je de cmd configuratie op hoeft te zetten. Je kunt je merge tool op kdiff3 instellen, opendiff, tkdiff, meld, xxdiff, emerge, vimdiff of gvimdiff. Als je niet geïnteresseerd bent in het gebruik van KDiff3 als diff, maar het liever alleen wilt gebruiken voor conflict oplossing en het kdiff3 commando zit in je pad, dan kun je dit uitvoeren $ git config --global merge.tool kdiff3 @@ -210,40 +210,40 @@ Als je dit uitvoert in plaats van de `extMerge` en `extDiff` bestanden in te ste ### Opmaak en witruimten ### -Problemen met opmaak en witruimten zijn één van de veelvoorkomende frustrerende en subtiele problemen die veel ontwikkelaars tegenkomen bij het samenwerken, in het bijzonder over verschillende platformen. Het is heel eenvoudig voor patches en ander werk om subtiele witruimte veranderingen te introduceren, omdat editors ze stil introduceren of omdat Windows programmeurs harde returns aan het eind van de regels toevoegen die ze aanraken in gekruiste platformprojecten. Git heeft een aantal configuratie opties om met deze problemen te helpen. +Problemen met opmaak en witruimten zijn één van de veelvoorkomende frustrerende en subtiele problemen die veel ontwikkelaars tegenkomen bij het samenwerken, in het bijzonder over verschillende platformen. Het is heel eenvoudig voor patches en ander werk om subtiele witruimte veranderingen te introduceren, omdat editors ze stiekum introduceren of omdat Windows programmeurs carriage returns aan het eind van de regels toevoegen van bestanden die ze bewerken in gemengde platformprojecten. Git heeft een aantal configuratie opties om met deze problemen te helpen. #### core.autocrlf #### -Als je op Windows programmeert, of een ander systeem gebruikt maar samenwerkt met mensen die op Windows werken, zul je vroeg of laat waarschijnlijk tegen regeleinde problemen aanlopen. Dat komt omdat Windows zowel een harde return als ook een linefeed karakter gebruikt voor regeleindes in zijn bestanden, waar Mac en Linux systemen alleen het linefeed karakter gebruiken. Dit is een subtiel maar verschrikkelijk irritant feit van het werken met gekruiste platformen. +Als je op Windows programmeert, of een ander systeem gebruikt maar samenwerkt met mensen die op Windows werken, zal je op enig moment tegen regeleinde problemen aanlopen. Dat komt omdat Windows zowel een carriage-return als een linefeed karakter gebruikt voor regeleindes in zijn bestanden, terwijl Mac en Linux systemen alleen het linefeed karakter gebruiken. Dit is een subtiel maar verschrikkelijk irritant feit van het werken met gemengde platformen. -Git kan hiermee omgaan door CRLF regeleinden automatisch om te zetten naar LF zodra je commit, en vice versa op het moment dat je code uitchecked op je systeem. Je kunt deze functionaliteit aanzetten met de `core.autocrlf` instelling. Als je op een Windows machine zit, stel het dan in op `true` – dit veranderd LF regeleinden in CRLF zodra je code uitchecked: +Git kan hiermee omgaan door CRLF regeleinden automatisch om te zetten naar LF zodra je commit, en vice versa op het moment dat je code uitchecked op je systeem. Je kunt deze functionaliteit aanzetten met de `core.autocrlf` instelling. Als je op een Windows machine zit, stel het dan in op `true` – dit verandert LF regeleinden in CRLF zodra je code uitchecked: $ git config --global core.autocrlf true -Als je op een Linux of Mac systeem zit dat LF regeleinden gebruikt, dan wil je niet dat Git ze automatisch veranderd op het moment dat Git bestanden uitchecked; maar als een bestand met CRLF regeleinden onverhoopt toch geïntroduceerd wordt, dan wil je misschien dat Git dit repareert. Je kunt Git vertellen dat je wilt dat hij CRLF in LF veranderd tijdens het committen, maar niet de andere kant op door het instellen van `core.autocrlf` op input: +Als je op een Linux of Mac systeem werkt (dat LF regeleinden gebruikt) dan wil je niet dat Git ze automatisch verandert op het moment dat Git bestanden uitchecked. Maar als een bestand met CRLF regeleinden onverhoopt toch geïntroduceerd wordt, dan wil je waarschijnlijk dat Git dit repareert. Je kunt Git vertellen dat je wilt dat hij CRLF in LF veranderd tijdens het committen, maar niet de andere kant op door het instellen van `core.autocrlf` op input: $ git config --global core.autocrlf input -Deze instelling zal CRLF regeleinden in Windows checkouts gebruiken, en LF einden in Mac en Linux systemen en in het repository moeten laten. +Deze instelling zal CRLF regeleinden in Windows checkouts gebruiken, en LF regeleinden in Mac en Linux systemen en in de repository. -Als je een Windows programmeur bent, die een alleen-Windows project doet, dan kun je deze functionaliteit uitzetten, waarmee de harde returns in het repository opgeslagen worden door de configuratie waarde op `false` te zetten: +Als je een Windows programmeur bent die aan een project voor alleen Windows werkt dan kun je deze functionaliteit uitzetten, waardoor de carriage-returns in de repository worden opgeslagen door de configuratie waarde op `false` te zetten: $ git config --global core.autocrlf false #### core.whitespace #### -Git is vooraf ingesteld om een aantal witruimte problemen te detecteren en te repareren. Het kan op vier veelvoorkomende witruimte problemen letten – twee staan er standaard aan en kunnen uitgezet worden, en twee staan er standaard niet aan, maar kunnen aangezet worden. +Git is standaard ingesteld om een aantal witruimte problemen te detecteren en te repareren. Het kan op vier veelvoorkomende witruimte problemen letten – twee staan er standaard aan en kunnen uitgezet worden, en twee staan standaard uit, maar kunnen aangezet worden. -De twee die standaard aan staan zijn `trailing-space`, wat kijkt of er spaties aan het eind van een regel staan, en `space-before-tab`, wat kijkt of er spaties voor tabs staan aan het begin van een regel. +De twee die standaard aan staan zijn `trailing-space`, waarmee wordt gekeken of er spaties aan het eind van een regel staan, en `space-before-tab`, wat kijkt of er spaties voor tabs staan aan het begin van een regel. -De twee die standaard uit staan, maar aangezet kunnen worden, zijn `indent-with-non-tab`, wat kijkt naar regels die met acht of meer spaties beginnen in plaats van tabs, en `cr-at-eol`, wat Git verteld dat harde returns aan het eind van een regel OK zijn. +De twee die standaard uit staan maar aangezet kunnen worden, zijn `indent-with-non-tab` die kijkt naar regels die met acht of meer spaties beginnen in plaats van tabs, en `cr-at-eol`, wat Git vertelt dat carriage-returns aan het eind van een regel geaccepteerd mogen worden. -Je kunt Git vertellen welke van deze je aan wil zetten door `core.whitespace` naar de waardes in te stellen die je aan of uit wil, gescheiden door komma's. Je kunt waarden uitzetten door ze weg te laten uit de instelling tekst of door een `-` vooraf te laten gaan aan de waarde. Bijvoorbeeld, als je alles aan wil behalve `cr-ar-eol`, dan kun je dit doen: +Je kunt Git vertellen welke van deze je aan wilt zetten door `core.whitespace` de waardes te geven die je aan of uit wilt zetten, gescheiden door komma's. Je kunt waarden uitzetten door ze weg te laten uit de instelling tekst of door een `-` vooraf te laten gaan aan de waarde. Bijvoorbeeld, als je alles aan wil behalve `cr-ar-eol`, dan kan je dit doen: $ git config --global core.whitespace \ trailing-space,space-before-tab,indent-with-non-tab -Git zal deze problemen detecteren zodra je een `git diff` commando uitvoert en ze proberen te kleuren zodat je ze kunt repareren alvorens te committen. Het zal deze waarden ook gebruiken om je te helpen met patches toe te passen met `git apply`. Als je patches gaat toepassen, kun je Git vragen om je te waarschuwen als hij patches toepast waarin deze specifieke witruimte problemen zitten: +Git zal deze problemen detecteren zodra je een `git diff` commando uitvoert en ze proberen in te kleuren zodat je ze kunt repareren voordat je ze commit. Het zal deze waarden ook gebruiken om je te helpen met patches toe te passen met `git apply`. Als je patches gaat toepassen, kan je Git vragen om je te waarschuwen als hij patches toepast waarin deze specifieke witruimte-problemen zitten: $ git apply --whitespace=warn @@ -251,104 +251,168 @@ 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 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. +Deze opties zijn ook op het `git rebase` commando 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 om Git automatisch witruimte problemen te laten repareren zodra het de patches herschrijft. ### Server configuratie ### -Er zijn lang niet zoveel configuratie opties beschikbaar voor de server kant van Git, maar er zijn er een paar interessante bij waar je misschien notie van wil hebben. +Er zijn lang niet zoveel configuratie opties beschikbaar voor de server kant van Git, maar er zijn er een paar interessante bij waar je misschien op gewezen wilt worden. #### receive.fsckObjects #### -Standaard zal Git niet alle objecten die hij ontvangt gedurende een push op consistentie controleren. Alhoewel Git kan controleren of ieder object nog steeds bij zijn SHA-1 checksum past en naar geldige objecten wijst, doet hij dat niet standaard bij iedere push. Dit is een relatief dure operatie en kan veel tijd kosten voor iedere push, afhankelijk van de grootte van het repository of de push. Als je wil dat Git ieder object op consistentie controleert bij iedere push, dan kun je hem dwingen door `receive.fsckObjects` op true te zetten: +Standaard zal Git niet alle objecten die hij ontvangt bij een push op consistentie controleren. Alhoewel Git kan controleren of ieder object nog steeds bij zijn SHA-1 checksum past en naar geldige objecten wijst, doet hij dat niet standaard bij iedere push. Het is een relatief dure operatie en kan veel extra tijd kosten bij iedere push, afhankelijk van de grootte van het repository of de push. Als je wilt dat Git ieder object op consistentie controleert bij elke push, dan kun je dit afdwingen door `receive.fsckObjects` op true te zetten: $ git config --system receive.fsckObjects true -Nu zal Git de integriteit van je repository controleren voor iedere push geaccepteerd wordt, om er zeker van te zijn dat kapotte clients geen corrupte gegevens introduceren. +Nu zal Git de integriteit van je repository controleren voordat een push geaccepteerd wordt, om er zeker van te zijn dat defecte clients geen corrupte gegevens introduceren. #### receive.denyNonFastForwards #### -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. +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 dat moment wijst, dan wordt dat afgewezen. Dit is in het algemeen goed beleid, maar in het geval van de rebase kan je besluiten dat je weet waar je mee bezig bent en kan 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: $ git config --system receive.denyNonFastForwards true -Een andere manier waarop je dit kunt doen is het instellen van ontvangst haken op de server, wat we zo meteen gaan behandelen. Die aanpak staat je toe meer complexe dingen te doen, zoals het weigeren van niet fast-forwards aan een bepaalde set gebruikers. +Een andere manier waarop je dit kunt doen is het instellen van ontvangst haken op de server wat we zo meteen gaan behandelen. Die aanpak stelt je in staat meer complexe dingen te doen, zoals het weigeren van niet fast-forwards aan een bepaalde groep gebruikers. #### receive.denyDeletes #### -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: +Een van de manieren waarop een gebruiker het `denyNonFastForwards` beleid kan omzeilen is dat hij de branch verwijdert en het dan opnieuw terug pushed met een 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 -Dit weigert branch en tag verwijdering door middel van een push over de hele breedte – geen enkele gebruiker mag het meer. Om remote branches te verwijderen, moet je de ref bestanden handmatig verwijderen van de server. Er zijn ook interessantere manieren om dit te doen op een per gebruiker basis door middel van ACL's, zoals je zult leren aan het eind van dit hoofdstuk. +Dit zal systeembreed branch en tag verwijdering door middel van een push weigeren; geen enkele gebruiker mag het meer. Om remote branches te verwijderen, moet je de ref bestanden handmatig verwijderen van de server. Er zijn ook interessantere manieren om dit per gebruiker af te dwingen door middel van ACL's, zoals je zult leren aan het eind van dit hoofdstuk. ## Git attributen ## -Een aantal van deze instellingen kan ook gedaan worden voor een pad, zodat Git die instellingen alleen toepast om een submap of subset van bestanden. Deze pad-specifieke instellingen worden Git attributen genoemd en worden in een `.gitattribute` bestand in een van je mappen (normaliter in de hoofdmap van je project) of in het `.git/attributes` bestand als je niet wilt dat het attributes bestand gecommit wordt met je project. +Een aantal van deze instellingen kan ook gedaan worden voor een pad, zodat Git die instellingen alleen toepast voor een subdirectory of subset van bestanden. Deze pad-specifieke instellingen worden Git attributen genoemd en worden in een `.gitattribute` bestand in een van je directories (normaliter in de hoofddirectory van je project) of in het `.git/info/attributes` bestand als je niet wilt dat het attributes bestand gecommit wordt met je project. -Door attributes te gebruiken kun je dingen doen als het specificeren van aparte samenvoeg strategieën voor individuele bestanden of mappen in je project, Git vertellen hoe hij niet-tekst bestanden kan diff'en, of Git inhoud laten filteren voordat je het in- of uitchecked van Git. In deze sectie zul je iets leren over de attributen die je kun instellen op de paden in je Git project en een paar voorbeelden zien hoe je deze eigenschap in de praktijk gebruikt. +Door attributen te gebruiken kun je dingen doen als het specificeren van aparte merge strategieën voor individuele bestanden of directories in je project, Git vertellen hoe hij niet-tekst bestanden kan diff'en, of Git inhoud laten filteren voordat je het in- of uitchecked van Git. In deze paragraaf zal je iets leren over de attributen die je kun instellen op de paden in je Git project en een paar voorbeelden zien hoe je deze eigenschap in de praktijk gebruikt. ### Binaire bestanden ### -Een stoere truc waarvoor je Git attributen kunt gebruiken is het vertellen aan Git welke bestanden binair zijn (in die gevallen waarin hij het niet zelf kan uitvinden) en Git dan speciale instructies geven hoe die bestanden te behandelen. Bijvoorbeeld, sommige tekstbestanden worden gegenereerd en zijn niet te diff'en, of sommige binaire bestanden kunnen wel gediff'ed worden – je zult zien hoe je Git verteld welke soort het is. +Een leuke truc waarvoor je Git attributen kunt gebruiken is het vertellen aan Git welke bestanden binair zijn (in die gevallen waarin hij het niet zelf kan ontdekken) en Git dan speciale instructies geven hoe die bestanden te behandelen. Bijvoorbeeld, sommige tekstbestanden worden gegenereerd en zijn niet te diff'en, of sommige binaire bestanden kunnen wel gediff'ed worden – je zult zien hoe je Git vertelt welke soort het is. #### Binaire bestanden identificeren #### -Sommige bestanden zien eruit als tekstbestanden, maar moeten toch behandeld worden als binaire gegevens. Bijvoorbeeld, Xcode projecten op de Mac bevatten een bestand dat eindigt in `.pbxproj`, wat eigenlijk een JSON (platte tekst javascript gegevens formaat) gegevensset is, dat geschreven wordt naar de schijf door de IDE, waarin je bouw instellingen opgeslagen zijn enzovoorts. Alhoewel het technisch een tekstbestand is, omdat het volledig ASCII is, zul je het niet als zodanig willen behandelen omdat het eigenlijk een lichtgewicht gegevensbank is – je kunt de inhoud niet samenvoegen als twee mensen het gewijzigd hebben, en diffs zijn over het algemeen niet behulpzaam. Het bestand is bedoeld om geconsumeerd te worden door een machine. In essentie wil je het behandelen als een binair bestand. +Sommige bestanden zien eruit als tekstbestanden, maar moeten toch behandeld worden als binaire gegevens. Bijvoorbeeld, Xcode projecten op de Mac bevatten een bestand dat eindigt in `.pbxproj`, wat eigenlijk een JSON (javascript gegevens in platte tekst formaat) gegevensset is, dat geschreven wordt naar de schijf door de IDE en waarin je bouw instellingen enzovoorts opgeslagen zijn. Alhoewel het technisch gezien een tekstbestand is, omdat het volledig ASCII is, zul je het niet als zodanig willen behandelen omdat het eigenlijk een lichtgewicht gegevensbank is – je kunt de inhoud niet samenvoegen als twee mensen het gewijzigd hebben, en diffs zijn over het algemeen niet behulpzaam. Het bestand is bedoeld om gebruikt te worden door een machine. In essentie wil je het behandelen als een binair bestand. Om Git te vertellen dat hij alle `pbxproj` bestanden als binaire gegevens moet behandelen, voeg je de volgende regel toe aan je `.gitattributes` bestand: *.pbxproj -crlf -diff -Nu zal Git niet proberen om CRLF problemen te veranderen of te repareren; noch zal het proberen een diff te berekenen of te tonen voor de veranderingen in dit bestand als je git show of git diff uitvoert op je project. In de 1.6 serie van Git, kun je ook een macro gebruiken die meegeleverd wordt, en die `-crlf -diff` betekend: +Nu zal Git niet proberen om CRLF problemen te corrigeren of repareren; noch zal het proberen een diff te berekenen of te tonen voor de veranderingen in dit bestand als je `git show` of `git diff` uitvoert op je project. In de 1.6 serie van Git, kun je ook het ingebouwde macro `binary` gebruiken die `-crlf -diff` betekend: *.pbxproj binary #### Binaire bestanden diff'en #### -In de 1.6 serie van Git, kun je de functionaliteit van Git attributen gebruiken om binaire bestanden effectief te diff'en. Je doet dit door Git te vertellen hoe het binaire gegevens naar tekst formaat moet omzetten, die dan via de normale diff vergeleken kan worden. +In Git kan je de functionaliteit van Git attributen gebruiken om binaire bestanden uiteindelijk toch te diff'en. Je doet dit door Git te vertellen hoe het de binaire gegevens naar tekst formaat moet omzetten, die dan via de normale diff vergeleken kan worden. Maar de vraag is hoe je de *binaire* gegevens naar tekst omzet. De beste oplossing is om een tool t vinden die deze conversie van binair naar tekstformaat voor je doet. Helaas kunnen weinig binaire formaten als mens-leesbaar formaat gerepresenteerd worden (probeer maar eens de gegevens van een geluidsfragment om te zetten naar tekst). Als dit het geval is en je bent er niet in geslaagd om een tekst-representatie te krijgen van de inhoud van het bestand is het vaak relatief eenvoudig om een menselijk leesbare omschrijving van de inhoud, of metadata te verkrijgen. Metadata geeft je niet een volledige representatie van de inhoud van het bestand, maar het is in elk geval beter dan niets. + +We gaan beide beschreven varianten gebruiken om bruikbare diff's te krijgen voor vaakgebruikte binaire formaten. + +Even terzijde: Er zijn verscheidene binaire formaten met een tekstinhoud waar moeilijk een bruikbare converter voor te vinden is. In die gevallen kan je proberen een tekst uit het bestand extraheren met het `strings` programma. Sommige van deze bestanden zouden een UTF-16 encoding of andere "codepages" kunnen gebruiken en `strings` kan dan niets bruikbaars in die bestanden vinden. Resultaten in het verleden geven geen garantie voor de toekomst. Echter `strings` wordt geleverd bij de meeste Mac en Linux systemen, dus het zou een goede eerste kandidaat zijn om dit te proberen bij veel binaire formaten. + +#### MS Word bestanden #### + +Ten eerste zullen we de beschreven techniek gebruiken om een van de meest ergerlijke problemen in de menselijke geschiedenis op te lossen: Word documenten versioneren. Iedereen weet dat Word een van de ergste editors verkrijgbaar is, maar vreemd genoeg: iedereen gebruikt het. Als je Word documenten in versie beheer wilt krijgen, kan je ze in een Git repostiory gooien en om de zoveel tijd een commit uitvoeren, maar wat voor nut heeft dit? Als je `git diff` uitvoert, zou je iets als dit zien: -Omdat dit een erg stoer en weinig gebruikte eigenschap is, zal ik een paar voorbeelden laten zien. Eerst zul je deze techniek gebruiken om een van de meest irritante problemen van deze mensheid op te lossen: Word documenten versie beheren. Iedereen weet dat Word een van de meest erge editors is die er te vinden is; maar, vreemd genoeg, gebruikt iedereen het. Als je Word documenten wil beheren, kun je ze in een Git repository stoppen en eens in de zoveel tijd committen; maar waar is dat goed voor? Als je `git diff` op een normale manier uitvoert, zie je alleen zoiets als dit: $ git diff diff --git a/chapter1.doc b/chapter1.doc index 88839c4..4afcb7c 100644 Binary files a/chapter1.doc and b/chapter1.doc differ -Je kunt twee versies niet direct vergelijken, tenzij je ze uitchecked en ze handmatig doorloopt, toch? Het blijkt dat je dit redelijk goed kunt doen door Git attributen te gebruiken. Stop de volgende regel in je `.gitattributes` bestand: +Je kunt niet direct twee versies vergelijken tenzij je ze uitchecked en handmatig doorneemt, toch? Maar het blijkt dat je dit toch redelijk goed met Git attributen kunt doen. Zet de volgende regel in je `.gitattributes` bestand: *.doc diff=word -Dit verteld Git dat ieder bestand dat dit patroon past (.doc) het "word" filter zou moeten gebruiken als je een diff probeert te bekijken, die veranderingen bevat. Wat is het "word" filter? Je zult het moeten instellen. Hier zul je Git configureren om het `strings` programma te gebruiken om Word documenten in leesbare tekstbestanden om te vormen, die het dan fatsoenlijk kan diff'en: +Dit vertelt Git dat allel bestanden die in het patroon (.doc) passen het "word" filter moeten gebruiken als je een diff probeert te bekijken die wijzigingen bevat. Wat is dat "word" filter eigenlijk? Je moet het zelf opzetten. Hier ga je Git configureren om het `catdoc` programma te gebruiken, die specifiek geschreven is om tekst uit binaire MS Word documenten te extraheren (je kunt het krijgen op `http://www.wagner.pp.ru/~vitus/software/catdoc/`), om Word documenten in leesbare tekstbestanden te converteren, en die vervolgens juist diff'en: + + $ git config diff.word.textconv catdoc + +Dit commando voegt een sectie toe aan je `.git/config`, wat er ongeveer zo uitziet: - $ git config diff.word.textconv strings + [diff "word"] + textconv = catdoc -Nu weet Git dat als het een diff probeert te doen tussen twee snapshots, en een van de bestanden eindigt in `.doc`, dan zou het deze bestanden door het "word" filter moeten halen, wat is gedefinieerd als het `strings` programma. Dit maakt effectief twee tekst-gebaseerde versies van je Word bestanden, alvorens ze proberen te diff'en. +Nu weet Git dat wanneer het probeert een diff uit te voeren tussen twee snapshots, en bestandsname eindigen op `.doc` dat het deze bestanden door de "word" filter moet halen, die gedefinieerd is als het `catdoc` programma. Effectief maakt het twee gewone tekst-gebaseerde versies van je Word bestanden vooraleer te proberen ze met diff te vergelijken. -Hier is een voorbeeld. Ik heb Hoofdstuk 1 van dit boek in Git gestopt, wat tekst aan een paragraaf toegevoegd, en het document bewaard. Daarna heb ik `git diff` uitgevoerd om te zien wat er gewijzigd is: +Hier is een voorbeeld. Ik heb hoofdstuk 1 van dit boek in Git gezet, wat tekst in een paragraaf toegevoegd en daarna het document gesaved. Daarna voerde ik `git diff` uit om te zien wat er gewijzigd was: $ git diff diff --git a/chapter1.doc b/chapter1.doc 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 vertelt me succesvol en kort en bondig dat ik de tekst "(See Chapter 3)" heb toegevoegd, wat juist is. Werkt perfect! + +##### OpenDocument tekst bestanden ##### + +Dezelfde aanpak die we hebben gebruikt vooro MS Word bestanden (`*.doc`) kan worden gebruikt bij OpenDocument Tekst bestanden (`*.odt`) wat gemaakt is door OpenOffice.org. + +Voeg de volgende regel toe aan je `.gitattributes` bestand: + + *.odt diff=odt -Git verteld me succesvol en beknopt dat ik de tekst "Let's see if this works" heb toegevoegd, wat correct is. Het is niet perfect – het voegt een serie willekeurig spul aan het einde toe – maar het werkt wel. Als je een Word-naar-gewone-tekst omvormer kunt vinden of schrijven die goed genoeg werkt, dan zal die oplossing waarschijnlijk zeer effectief zijn. Maar, `strings` is op de meeste Mac en Linux machines beschikbaar, dus dit kan een goede eerste poging zijn om dit te gebruiken bij andere binaire formaten. +Zet nu het `odt` diff filter op in `.git/config`: -Een ander interessant probleem dat je hiermee kunt oplossen in het diff'en van beeldbestanden. Een manier om dit te doen is JPEG bestanden door een filter te halen dat hun EXIF informatie eruit peutert – metadata die wordt opgeslagen met de meeste beeldbestanden. Als je het `exiftool` programma download en installeert, kun je het gebruiken om je plaatjes naar tekst over de metadata om te zetten, zodat de diff op z'n minst een tekstuele representatie van eventuele wijzigingen laat zien: + [diff "odt"] + binary = true + textconv = /usr/local/bin/odt-to-txt + +OpenDocument bestanden zijn eigenlijk gezipte directories met daarin meerdere bestanden (de inhoud ervan in een XML formaat, stylesheets, plaatjes, etc.). Ze zullen een script moeten schrijven om de inhoud te extraheren en dit terug te geven als platte tekst. Maak een bestand `/usr/local/bin/odt-to-txt` (het staat je vrij om dit in een andere directory neer te zetten) met de volgende inhoud: + + #! /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"; + +En maak het uitvoerbaar + + chmod +x /usr/local/bin/odt-to-txt + +Nu zal `git diff` je kunnen vertellen wat er gewijzigd is in `.odt` bestanden. + + +##### Beeldbestanden ##### + +Een ander interessant probleem dat je hiermee kunt oplossen is het diff'en van beeldbestanden. Een manier om dit te doen is PNG bestanden door een filter te halen dat de EXIF informatie eruit peutert; dat is metadata die wordt opgeslagen bij de meeste beeldbestand formaten. Als je het `exiftool` programma download en installeert, kan je dit gebruiken om je plaatjes naar tekst over de metadata om te zetten, zodat de diff op z'n minst een tekstuele representatie van eventuele wijzigingen laat zien: $ echo '*.png diff=exif' >> .gitattributes $ git config diff.exif.textconv exiftool -Als je een plaatje in je project veranderd en `git diff` uitvoert, dan zie je zoiets als dit: +Als je een plaatje in je project verandert en `git diff` uitvoert, dan zie je zoiets als dit: diff --git a/image.png b/image.png index 88839c4..4afcb7c 100644 @@ -373,9 +437,9 @@ Je kunt eenvoudig zien dat zowel de bestandsgrootte als de beeld dimensies gewij ### Keyword expansie ### -Keyword expansie zoals in SVN of CVS wordt vaak gevraagd door ontwikkelaars, die gewend zijn aan die systemen. Het grote probleem in Git is dat je een bestand niet mag wijzigen met informatie over de commit, nadat je het gecommit hebt, omdat Git eerst de checksum van het bestand maakt. Maar, je kunt tekst in een bestand injecteren zodra het uitgechecked wordt en opnieuw verwijderen voordat het aan een commit toegevoegd wordt. Met Git attributen zijn er twee manieren om dit te doen. +Keyword expansie zoals in SVN of CVS gebruikt wordt, wordt vaak gevraagd door ontwikkelaars die gewend zijn aan die systemen. Het grote probleem in Git is dat je een bestand niet mag wijzigen met informatie over de commit nadat je het gecommit hebt, omdat Git eerst de checksum van het bestand maakt. Maar, je kunt tekst in een bestand injecteren zodra het uitgechecked wordt en dit weer verwijderen voordat het aan een commit toegevoegd wordt. Met Git attributen zijn er twee manieren om dit te doen. -Als eerste kun je de SHA-1 checksum van een blob automatisch in een `$Id$` veld in het bestand stoppen. Als je dit attribuut op een bestand of serie bestanden insteld, dan zal Git de volgende keer dat je die branch uitchecked dat veld vervangen met de SHA-1 van de blob. Het is belangrijk om op te merken dat het niet de SHA van de commit is, maar van de blob zelf: +Als eerste kun je de SHA-1 checksum van een blob automatisch in een `$Id$` veld in het bestand stoppen. Als je dit attribuut in een bestand of aantal bestanden zet, dan zal Git de volgende keer dat je die branch uitchecked dat veld vervangen met de SHA-1 van de blob. Het is belangrijk om op te merken dat het niet de SHA van de commit is, maar van de blob zelf: $ echo '*.txt ident' >> .gitattributes $ echo '$Id$' > test.txt @@ -387,9 +451,9 @@ De volgende keer dat je dit bestand uitchecked, injecteert Git de SHA van de blo $ cat test.txt $Id: 42812b7653c7b88933f8a9d6cad0ca16714b9bb3 $ -Maar, het resultaat is slechts beperkt bruikbaar. Als je sleutelwoord vervanging in CVS of Subversion gebruikt hebt, kun je een tijdstempel toevoegen – de SHA is niet zo bruikbaar, omdat het vrij willekeurig is en je kunt niet zeggen of een SHA ouder of nieuwer is dan een andere. +Maar, het resultaat heeft slechts een beperkt nut. Als je sleutelwoord vervanging (keyword substitution) in CVS of Subversion gebruikt hebt, kun je een datumstempel toevoegen – de SHA is niet zo bruikbaar, omdat het vrij willekeurig is en je kunt niet zeggen of de ene SHA ouder of nieuwer is dan de andere. -Het blijkt dat je je eigen filters voor het doen van vervanging bij commit/checkout kunt schrijven. Dit zijn de "clean" en "smudge" filters. In het `.gitattributes` bestand, kun je een filter op bepaalde paden instellen en dan scripts instellen die bestanden bewerkt vlak voordat ze gecommit worden ("clean", zie Figuur 7-2) en vlak voordat ze uitgechecked worden ("smudge", zie Figuur 7-3). De filters kunnen ingesteld worden zodat ze allerlei leuke dingen doen. +Je kunt echter je eigen filters voor het doen van vervanging bij commit/checkout schrijven. Dit zijn de "kuis" ("clean") en "besmeer" ("smudge") filters. In het `.gitattributes` bestand kan je een filter op bepaalde paden instellen en dan scripts instellen die bestanden bewerkt vlak voordat ze uitgechecked worden ("smudge", zie Figuur 7-2) en vlak voordat ze gecommit worden ("clean", zie Figuur 7-3). De filters kunnen ingesteld worden om allerlei leuke dingen doen. Insert 18333fig0702.png Figuur 7-2. Het “smudge” filter wordt bij checkout uitgevoerd. @@ -397,7 +461,7 @@ Figuur 7-2. Het “smudge” filter wordt bij checkout uitgevoerd. Insert 18333fig0703.png Figuur 7-3. Het “clean” filter wordt uitgevoerd zodra bestanden worden gestaged. -De originele commit boodschap voor deze functionaliteit geeft een eenvoudig voorbeeld hoe je al je C broncode door het `indent` programma kunt halen alvorens te committen. Je kunt het instellen door het filter attribuut in je `.gitattributes` bestand te veranderen zodat `*.c` bestanden door de "indent" filter gehaald worden: +De originele commit boodschap van deze functionaliteit geeft een eenvoudig voorbeeld hoe je al je C broncode door het `indent` programma kunt laten bewerken alvorens te committen. Je kunt het instellen door het filter attribuut in je `.gitattributes` bestand te zetten zodat `*.c` bestanden door de "indent" filter gehaald worden: *.c filter=indent @@ -406,26 +470,26 @@ Vervolgens vertel je Git wat het "indent" filter doet bij smudge en clean: $ git config --global filter.indent.clean indent $ git config --global filter.indent.smudge cat -In dit geval zal Git, als je bestanden commit die op `*.c` passen, ze door het indent programma halen alvorens ze te committen, en ze door het `cat` programma halen alvorens ze op de schijf uit te checken. Het `cat` programma is eigenlijk een no-op: het spuugt dezelfde gegevens uit als dat het inneemt. Deze combinatie zal effectief alle C broncode bestanden door `indent` filteren alvorens te committen. +In dit geval zal Git, als je bestanden commit die op `*.c` passen, ze door het indent programma halen alvorens ze te committen, en ze door het `cat` programma halen alvorens ze op de schijf uit te checken. Het `cat` programma is eigenlijk een no-op: het geeft de gegevens onveranderd door. Deze combinatie zal effectief alle C broncode bestanden door `indent` filteren alvorens te committen. -Een ander interessant voorbeeld is `$Date$` sleutelwoord expansie, in RCS stijl. Om dit goed te doen, moet je een klein script hebben dat een bestandsnaam pakt, de laatste commit datum voor dit project uitvogelt, en de datum in een bestand toevoegt. Hier volgt een klein Ruby script dat dat doet: +Een ander interessant voorbeeld is `$Date$` sleutelwoord expansie, in RCS stijl. Om dit goed te doen, moet je een klein script hebben dat een bestandsnaam pakt, de laatste commit datum voor dit project opzoekt, en de datum in een bestand toevoegt. Hier volgt een klein Ruby script dat dat doet: #! /usr/bin/env ruby data = STDIN.read last_date = `git log --pretty=format:"%ad" -1` puts data.gsub('$Date$', '$Date: ' + last_date.to_s + '$') -Het enige dat het script doet is de laatste commit datum uit het `git log` commando halen, het in iedere `$Date$` tekst stoppen die het in stdin ziet, en de resultaten afdrukken – het moet eenvoudig te doen zijn in welke taal je je ook thuisvoelt. Je kunt dit bestand `expand_date` noemen en het in je pad stoppen. Nu moet je een filter in Git instellen (noem het `dater`), en het vertellen je `expand_date` filter te gebruiken om de bestanden tijdens checkout te 'smudgen'. Je zult een Perl expressie gebruiken om dat op te ruimen tijdens een commit: +Het enige dat het script doet is de laatste commit datum uit het `git log` commando halen, het in iedere `$Date$` tekst stoppen die het in stdin ziet, en de resultaten afdrukken – het moet eenvoudig te copieren zijn in welke taal je het beste thuisbent. Je kunt dit bestand `expand_date` noemen en het in je pad stoppen. Nu moet je een filter in Git instellen (noem het `dater`), en het vertellen jouw `expand_date` filter te gebruiken om de bestanden tijdens checkout te 'besmeren'. Je zult een Perl expressie gebruiken om dat op te ruimen tijdens een commit: $ git config filter.dater.smudge expand_date $ git config filter.dater.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"' -Dit Perl stukje haalt alles weg dat het in en `$Date$` tekst ziet, om terug te komen vanwaar je gekomen bent. Nu je filter klaar is, kun je het testen door een bestand aan te maken met je `$Date$` sleutelwoord en dan een Git attribuut voor dat bestand in te stellen, die het nieuwe filter gebruikt. +Dit stukje Perl haalt alles weg dat het in en `$Date$` tekst ziet, om weer op het uitgangspunt uit te komen. Nu je filter klaar is, kun je het testen door een bestand aan te maken met het `$Date$` sleutelwoord en dan een Git attribuut voor dat bestand in te stellen, die het nieuwe filter gebruikt. $ echo '# $Date$' > date_test.txt $ echo 'date*.txt filter=dater' >> .gitattributes -Als je die veranderingen commit en het bestand opnieuw uitchecked, zul je zien dat het sleutelwoord vervangen is: +Als je die veranderingen commit en het bestand opnieuw uitchecked, zul je zien dat het sleutelwoord correct vervangen is: $ git add date_test.txt .gitattributes $ git commit -m "Testing date expansion in Git" @@ -434,7 +498,7 @@ Als je die veranderingen commit en het bestand opnieuw uitchecked, zul je zien d $ cat date_test.txt # $Date: Tue Apr 21 07:26:52 2009 -0700$ -Je kunt wel zien hoe krachtig deze techniek is voor gebruik in eigengemaakte toepassingen. Je moet wel voorzichtig zijn, om dat het `.gitattributes` bestand ook gecommit wordt en meegestuurd wordt met het project, maar het filter (in dit geval `dater`) niet; dus het zal niet overal werken. Als je deze filters ontwerpt, zouden ze in staat moeten zijn om netjes te falen en het project nog steeds goed te laten werken. +Je ziet hier hoe krachtig deze techniek is voor gebruik in eigengemaakte toepassingen. Je moet wel voorzichtig zijn, om dat het `.gitattributes` bestand ook gecommit wordt en meegestuurd wordt met het project, maar het filter (in dit geval `dater`) niet; dus het zal niet overal werken. Als je deze filters ontwerpt, zouden ze in staat moeten zijn om netjes te falen en het project nog steeds goed te laten werken. ### Je repository exporteren ### @@ -442,9 +506,9 @@ De Git attribute gegevens staan je ook toe om interessante dingen te doen als je #### export-ignore #### -Je kunt Git vertellen dat sommige bestanden of mappen niet geëxporteerd moeten worden als een archief gegenereerd wordt. Als er een submap of bestand is waarvan je niet wil dat het wordt meegenomen in je archief bestand, maar dat je wel in je project ingechecked wil hebben, dan kun je die bestanden bepalen met behulp van het `export-ignore` attribuut. +Je kunt Git vertellen dat sommige bestanden of directories niet geëxporteerd moeten worden als een archief gegenereerd wordt. Als er een subdirectory of bestand is waarvan je niet wil dat het wordt meegenomen in je archief bestand, maar dat je wel in je project ingechecked wil hebben, dan kun je die bestanden bepalen met behulp van het `export-ignore` attribuut. -Bijvoorbeeld, stel dat je wat testbestanden in een `test/` submap hebt, en dat het geen zin heeft om die in de tarball export van je project mee te nemen. Je kunt dan de volgende regel in je Git attributes bestand toevoegen: +Bijvoorbeeld, stel dat je wat testbestanden in een `test/` submap hebt, en dat het geen zin heeft om die in de tarball export van je project mee te nemen. Dan kan je de volgende regel in je Git attributes bestand toevoegen: test/ export-ignore @@ -452,101 +516,101 @@ Als je nu git archive uitvoert om een tarball van je project te maken, zal die m #### export-subst #### -Iets anders dat je kunt doen met je archieven is eenvoudige sleutelwoord vervanging. Git staat je toe om de tekst `$Format:$` in ieder bestand met ieder van de `--pretty=format` formaat afkortingen te zetten, waarvan je er al veel zag in Hoofdstuk 2. Bijvoorbeeld, als je een bestand genaamd `LAST_COMMIT` wilt meenemen in je project, en de laatste commit datum was hierin automatisch geïnjecteerd toen `git archive` bezig was, kun je het bestand als volgt instellen: +Iets anders dat je kunt doen met je archieven is eenvoudige sleutelwoord vervanging. Git staat je toe om de tekst `$Format:$` met een van de `--pretty=format` formaat afkortingen in één of meer bestanden te zetten,. Voorbeelden van die formaatafkortingen zag je al in Hoofdstuk 2. Bijvoorbeeld, als je een bestand genaamd `LAST_COMMIT` wilt meenemen in je project, waarin de laatste commit datum automatisch wordt geïnjecteerd als `git archive` loopt, kun je het bestand als volgt instellen: $ echo 'Last commit date: $Format:%cd$' > LAST_COMMIT $ echo "LAST_COMMIT export-subst" >> .gitattributes $ git add LAST_COMMIT .gitattributes $ git commit -am 'adding LAST_COMMIT file for archives' -Als je `git archive` uitvoert, zal de inhoud van dat bestand als mensen het archief bestand openen er zo uit zien: +Als je `git archive` uitvoert, zal de inhoud van dat bestand, als mensen het archief bestand openen, er zo uit zien: $ cat LAST_COMMIT Last commit date: $Format:Tue Apr 21 08:38:48 2009 -0700$ -### Samenvoeg strategieën ### +### Merge strategieën ### -Je kunt Git attributen ook gebruiken om Git te vertellen dat het verschillende samenvoeg strategieën moet gebruiken voor specifieke bestanden in je project. Een erg handige optie is Git te vertellen dat het niet moet proberen bepaalde bestanden samen te voegen als ze conflicten hebben, maar jouw versie moeten gebruiken in plaats van andermans versie. +Je kunt Git attributen ook gebruiken om Git te vertellen dat het verschillende merge strategieën moet gebruiken voor specifieke bestanden in je project. Een erg handige optie is Git te vertellen dat het niet moet proberen bepaalde bestanden te mergen als ze conflicten hebben, maar jouw versie moeten gebruiken in plaats van die van de ander. -Dit is handig als een branch in je project af is geweken of gespecialiseerd is, maar je in staat wil zijn om veranderingen daarvan terug samen te voegen, en je wilt bepaalde bestanden negeren. Stel dat je een gegevensbank instellingen bestand hebt dat database.xml heet en dat in twee branches verschillend is, en je wilt in je andere branch samenvoegen zonder het gegevensbank bestand te verprutsen. Je kunt dan een attribuut als volgt instellen: +Dit is handig als een branch in je project af is geweken of gespecialiseerd is, je wel in staat wilt zijn om veranderingen daarvan te mergen, maar je wilt bepaalde bestanden negeren. Stel dat je een database instellingen bestand hebt dat database.xml heet en dat in twee branches verschillend is, en je wilt de andere branch mergen zonder jouw database bestand te verprutsen. Je kunt dan een attribuut als volgt instellen: database.xml merge=ours -Als je in de andere branch samenvoegt, dan zul je in plaats van samenvoeg conflicten met je database.xml bestand zoiets als dit zien: +Als je in de andere branch merged, dan zul je in plaats van merge conflicten met je database.xml bestand zoiets als dit zien: $ git merge topic Auto-merging database.xml Merge made by recursive. -In dit geval blijft database.xml staan op welke versie je origineel ook had. +In dit geval blijft database.xml staan op de versie die je origineel al had. -## Git haken ## +## Git haken (hooks) ## -Zoals vele andere Versie Beheer Systemen, heeft Git een manier om eigengemaakte scripts op te starten wanneer bepaalde belangrijke acties voorkomen. Er zijn twee groepen van dit soort haken: aan de client kant en aan de server kant. De haken aan de client kant zijn voor client operaties zoals committen en samenvoegen. De haken voor de server kant zijn voor Git server operaties zoals het ontvangen van gepushte commits. Je kunt deze haken om allerlei redenen gebruiken, en je zult hier over een aantal ervan leren. +Zoals vele andere Versie Beheer Systemen, heeft Git een manier om eigengemaakte scripts op te starten wanneer bepaalde belangrijke acties plaatsvinden. Er zijn twee groepen van dit soort hooks: aan de client kant en aan de server kant. De hooks aan de client kant zijn voor client operaties zoals committen en mergen. De hooks voor de server kant zijn voor Git server operaties zoals het ontvangen van gepushte commits. Je kunt deze hooks om allerlei redenen gebruiken, en je zult hier over een aantal ervan leren. -### Een haak installeren ### +### Een hook installeren ### -De haken worden allemaal opgeslagen in de `hooks` submap van de Git map. In de meeste projecten is dat `.git/hooks`. Standaard voorziet Git deze map van een aantal voorbeeld scripts, waarvan de meeste al bruikbaar zijn; maar ze documenteren ook de invoer waarden van ieder script. Alle scripts zijn als shell script geschreven, met hier en daar wat Perl, maar iedere executable met de juiste naam zal prima werken – je kunt ze in Ruby of Python of wat je wil schrijven. Voor Git versies later dan 1.6, eindigen deze haak bestanden met .sample; je zult ze van naam moeten veranderen. Voor eerdere versies van Git, zijn de scripts al van de juiste naam voorzien, maar je moet ze nog uitvoerbaar maken. +De hooks zijn allemaal opgeslagen in de `hooks` subdirectory van de Git directory. In de meeste projecten is dat `.git/hooks`. Standaard voorziet Git deze map van een aantal voorbeeld scripts, waarvan de meeste op zich al bruikbaar zijn, maar ze documenteren ook de invoer waarden van elke script. Alle scripts zijn als shell script geschreven met hier en daar wat Perl, maar iedere executable met de juiste naam zal prima werken – je kunt ze in Ruby of Python of wat je wilt schrijven. De namen van de scripts eindigen op .sample; je zult ze van naam moeten veranderen. -Om een haak script aan te zetten, stop je een bestand met de juiste naam en dat uitvoerbaar is in de `hooks` map van je Git map. Vanaf dat punt zou het aangeroepen moeten worden. Ik zal de meestgebruikte haak bestandsnamen hier behandelen. +Om een hook script aan te zetten, zet je een bestand met de juiste naam en dat uitvoerbaar is in de `hooks` subdirectory van je Git directory. Vanaf dat moment zou het aangeroepen moeten worden. Ik zal de meestgebruikte hook bestandsnamen hier behandelen. -### Client-kant haken ### +### Hooks aan de client-kant ### -Er zijn veel client-kant haken. Deze sectie verdeeld ze in commit-werkwijze haken, e-mail-werkwijze scripts, en de rest van de client-kant scripts +Er zijn veel hooks aan de client-kant. Deze paragraaf verdeelt ze in commit-werkwijze hooks, e-mail-werkwijze scripts, en de rest van de client-kant scripts #### Commit-werkwijze haken #### -De eerste vier haken hebben te maken met het commit proces. De `pre-commit` haak wordt eerst uitgevoerd, nog voor je een commit boodschap intypt. Het wordt gebruikt om het snapshot dat op het punt staat gecommit te worden te inspecteren, om te zien of je iets bent vergeten, om er zeker van te zijn dat tests uitgevoerd worden, of om te onderzoeken wat je wilt in de code. Deze haak met een waarde anders dan nul afsluiten breekt de commit af, alhoewel je 'm kunt omzeilen met `git commit --no-verify`. Je kunt dingen doen als op code stijl controleren (voer lint of iets dergelijks uit), op aanhangende spaties controleren (de standaard haak doet dat), of om de juiste documentatie op nieuwe functies te controleren. +De eerste vier hooks hebben te maken met het commit proces. De `pre-commit` hook wordt eerst uitgevoerd, nog voor je een commit boodschap intypt. Het wordt gebruikt om het snapshot dat op het punt staat gecommit te worden te inspecteren, om te zien of je iets bent vergeten, om er zeker van te zijn dat tests uitgevoerd worden of om wat je maar wilt te onderzoeken in de code. Als deze hook met een exit-waarde anders dan nul eindigt breekt de commit af, alhoewel je dit kunt omzeilen met `git commit --no-verify`. Je kunt dingen doen als op code stijl controleren (door lint of iets dergelijks uit te voeren), op 'trailing whitespaces' te controleren (de standaard hook doet dat), of om de juiste documentatie op nieuwe methodes te controleren. -De `prepare-commit-msg` haak wordt uitgevoerd voordat de commit boodschap editor gestart wordt, maar nadat de standaard boodschap aangemaakt is. Het stelt je in staat om de standaard boodschap aan te passen voordat de commit auteur het ziet. Deze haak accepteert een aantal opties: het pad naar het bestand dat de huidige commit boodschap bevat, het type van de commit, en de SHA-1 van de commit als het een verbeterde commit betreft. Deze haak is voor normale commits niet zo bruikbaar; maar, het is goed voor commits waarbij de standaard boodschap automatisch gegenereerd wordt, zoals sjabloon commit boodschappen, samenvoeg commits, gesquashte commits en verbeterde commits. Je mag het samen met een commit sjabloon gebruiken om informatie in te voegen. +De `prepare-commit-msg` hook wordt uitgevoerd voordat de commit boodschap editor gestart wordt, maar nadat de standaard boodschap aangemaakt is. Het stelt je in staat om de standaard boodschap aan te passen voordat de commit auteur het ziet. Deze hook accepteert een aantal opties: het pad naar het bestand dat de huidige commit boodschap bevat, het type van de commit, en de SHA-1 van de commit als het een verbeterde (amended) commit betreft. Deze hook is voor normale commits niet zo bruikbaar, maar het is juist bruikbaar voor commits waarbij de standaard boodschap automatisch gegenereerd wordt, zoals sjabloon commit boodschappen, merge commits, gesquashte commits en amended commits. Je kan het samen met een commit sjabloon gebruiken om informatie programmatisch in te voegen. -De `commit-msg` hook accepteert één parameter, wat weer het pad naar een tijdelijk bestand is dat de huidige commit boodschap bevat. Als dit script eindigt met een waarde anders dan nul, dan zal Git het commit proces afbreken, dus je kunt het gebruiken om je project-status of de commit boodschap te valideren alvorens een commit toe te staan. In het laatste gedeelte van dit hoofdstuk, zal ik deze haak demonstreren om te controleren of je commit boodschap aan een bepaald patroon voldoet. +De `commit-msg` hook accepteert één parameter, wat weer het pad naar een tijdelijk bestand is dat de huidige commit boodschap bevat. Als dit script eindigt met een waarde anders dan nul, dan zal Git het commit proces afbreken, je kunt deze gebruiken om je project-status of de commit boodschap te valideren alvorens een commit toe te staan. In het laatste gedeelte van dit hoofdstuk, zal ik deze hook demonstreren hoe te controleren dat de commit boodschap aan een bepaald patroon voldoet. -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. +Nadat het hele commit proces afgerond is, zal de `post-commit` hook 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 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. +De commit-werkwijze scripts aan de client-kant kunnen gebruikt worden in vrijwel iedere werkwijze. Ze worden vaak gebruikt om een bepaald beleid af te dwingen, maar het is belangrijk om op te merken dat deze scripts niet overgedragen worden bij het klonen. Je kunt beleid afdwingen aan de server kant door 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 door hen op elk moment aangepast of omzeild kunnen worden. -#### E-mail werkwijze haken #### +#### E-mail werkwijze hooks #### -Je kunt drie client kant haken instellen voor een e-mail gebaseerde werkwijze. Ze worden allemaal aangeroepen door het `git am` commando, dus als je dat commando niet gebruikt in je werkwijze, dan kun je veilig doorgaan naar de volgende sectie. Als je patches aanneemt via e-mail, die door `git format-patch` geprepareerd zijn, dan zullen sommige van deze behulpzaam zijn voor je. +Je kunt drie client-kant hooks instellen voor een e-mail gebaseerde werkwijze. Ze worden allemaal aangeroepen door het `git am` commando dus als je dat commando niet gebruikt in je werkwijze, dan kun je gerust doorgaan naar de volgende paragraaf. Als je patches aanneemt via e-mail die door `git format-patch` geprepareerd zijn, dan zullen sommige van deze scripts nuttig zijn voor je. -De eerste haak die uitgevoerd wordt is `applypatch-msg`. Het accepteert een enkel argument: de naam van het tijdelijke bestand dat de voorgestelde commit boodschap bevat. Git breekt de patch als dit script met een waarde ongelijk aan nul eindigt. Je kunt dit gebruiken om er zeker van te zijn dat een commit boodschap juist geformatteerd is, of om de boodschap te normaliseren door het script de boodschap aan te laten passen. +De eerste hook die uitgevoerd wordt is `applypatch-msg`. Het accepteert één enkel argument: de naam van het tijdelijke bestand dat de voorgedragen commit boodschap bevat. Git breekt de patch als dit script met een waarde ongelijk aan nul eindigt. Je kunt dit gebruiken om je ervan te verzekeren dat een commit boodschap juist geformatteerd is, of om de boodschap te normaliseren door het script de boodschap aan te laten passen. -De volgende haak die wordt uitgevoerd tijdens het toepassen van patches via `git am` is `pre-applypatch`. Dit neemt geen argumenten aan en wordt uitgevoerd nadat de patch is toegepast, zodat je het kunt gebruiken om het snapshot te inspecteren alvorens de commit te doen. Je kunt tests uitvoeren of de werkmap op een andere manier inspecteren met behulp van dit script. Als er iets mist of één van de tests faalt, dan zal eindigen met niet nul het `git am` script afbreken zonder de patch te committen. +De volgende hook die wordt uitgevoerd tijdens het toepassen van patches via `git am` is `pre-applypatch`. Dit neemt geen argumenten aan en wordt uitgevoerd nadat de patch is toegepast, zodat je het kunt gebruiken om het snapshot te inspecteren alvorens de commit te doen. Je kunt tests uitvoeren of de werkmap op een andere manier inspecteren met behulp van dit script. Als er iets mist of één van de tests faalt, dan zal eindigen met niet nul het `git am` script afbreken zonder de patch te committen. -De laatste haak die uitgevoerd wordt tijdens een `git am` operatie is de `post-applypatch`. Je kunt dat gebruiken om een groep te notificeren of de auteur van de patch die je zojuist gepulled hebt. Je kunt het patch proces niet stoppen met behulp van dit script. +De laatste hook die uitgevoerd wordt tijdens een `git am` operatie is de `post-applypatch`. Je kunt dat gebruiken om een groep te notificeren of de auteur van de patch die je zojuist gepulled hebt. Je kunt het patch proces niet stoppen met behulp van dit script. -#### Andere client haken #### +#### Andere client hooks #### -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. +De `pre-rebase` hook 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 hook gebruiken om te voorkomen dat commits die al gepushed zijn gerebased worden. De voorbeeld `pre-rebase` hook 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. +Nadat je een succesvolle `git checkout` uitgevoerd hebt, wordt de `post-checkout` hook uitgevoerd; je kunt het gebruiken om je werkdiorectory goed in te stellen voor je project omgeving. Dit kan het invoegen van grote binaire bestanden die je niet in versie beheer wil hebben inhouden, of het automatisch genereren van documentatie of iets in die geest. -Als laatste wordt de `post-merge` haak uitgevoerd na een succesvol `merge` commando. Je kunt het gebruiken om gegevens in de boom die Git niet kan volgen terug te zetten, bijvoorbeeld permissie gegevens. Ook kan deze haak gebruikt worden om de aanwezigheid van bestanden buiten de controle van Git te controleren, die je misschien in je boom gekopieerd wil hebben zodra hij veranderd. +Als laatste wordt de `post-merge` hook uitgevoerd na een succesvolle `merge` commando. Je kunt deze gebruiken om gegevens in de werkstructuur terug te zetten die Git niet kan ophalen, bijvoorbeeld permissie gegevens. Ook kan deze hook gebruikt worden om bestanden, die buiten het beheer van Git liggen, in je werkstructuur gekopieerd te krijgen zodra deze veranderd. -### Server-kant haken ### +### Hooks aan de server-kant ### -Naast de client-kant haken, kun je als systeem administrator ook een paar belangrijke server-kant haken gebruiken om vrijwel ieder beleid op je project af te dwingen. Deze scripts worden voor en na de pushes op de server uitgevoerd. De pre haken kunnen met een ander getal dan nul eindigen om de push te weigeren en een foutmelding naar de client te sturen; je kunt een push beleid instellen dat zo complex is als je zelf wenst. +Naast de hooks aan de client-kant, kun je als systeem beheerder ook een paar belangrijke hooks aan de server-kant gebruiken om vrijwel elk beleid op het project af te dwingen. Deze scripts worden voor en na de pushes op de server uitgevoerd. De pre hooks kunnen met een getal anders dan nul laten eindigen om de push te weigeren en een foutmelding naar de client te sturen; je kunt een push beleid instellen dat zo complex is als je zelf wenst. #### 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 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. +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 van stdin; als het eindigt met een andere waarde dan nul, worden ze geen van allen geaccepteerd. Je kunt deze hook 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 uitvoert creatie, verwijder, of push toegang heeft, of toegang om wijzigingen te pushen voor 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. +De `post-receive` hook wordt uitgevoerd nadat het hele proces afgerond is, en het kan gebruikt worden om andere services te vernieuwen of gebruikers te notificeren. Het aanvaardt dezelfde stdin gegevens als de `pre-receive` hook. 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 worden. Dit script kan het push proces niet stoppen, maar de client verbreekt de connectie niet totdat het afgerond is, wees dus een voorzichtig als je iets probeert te doen dat een lange tijd in beslag neemt. #### update #### -Het update script is vergelijkbaar met het `pre-receive` script, behalve dan dat het uitgevoerd wordt voor iedere branch die de pusher probeert te vernieuwen. Als de pusher naar meerdere branches probeert te pushen, wordt `pre-receive` slechts één keer uitgevoerd, maar `update` bij iedere branch waar ze naar pushen. In plaats van stdin te lezen, aanvaardt dit script drie argumenten: de naam van de referentie (branch), de SHA-1 waar die referentie naar wees voor de push, en de SHA-1 die de gebruiker probeert te pushen. Als het update script met een andere waarde dan nul eindigt, wordt alleen die referentie geweigerd; andere referenties kunnen nog steeds vernieuwd worden. +Het update script is vergelijkbaar met het `pre-receive` script, behalve dat het uitgevoerd wordt voor iedere branch die de pusher probeert te vernieuwen. Als de pusher naar meerdere branches probeert te pushen wordt `pre-receive` slechts één keer uitgevoerd, daarentegen loopt `update` bij iedere branch waar ze naar pushen. In plaats van stdin te lezen, aanvaardt dit script drie argumenten: de naam van de referentie (branch), de SHA-1 waar die referentie naar wees vóór de push, en de SHA-1 die de gebruiker probeert te pushen. Als het update script met een andere waarde dan nul eindigt, wordt alleen die referentie geweigerd; andere referenties kunnen nog steeds vernieuwd worden. ## Een voorbeeld van Git-afgedwongen beleid ## -In dit gedeelte zul je gebruiken wat je geleerd hebt om een Git werkwijze vast te leggen, die controleert op een eigengemaakt commit boodschap formaat, afdwingt om alleen fast-forward pushes te accepteren, en alleen bepaalde gebruikers toestaat om bepaalde submappen te wijzigen in een project. Je zult client scripts maken die de ontwikkelaar helpen er achter te komen of hun push geweigerd zal worden, en server scripts die het beleid afdwingen. +In deze paragraaf ga je gebruiken wat je geleerd hebt om een Git werkwijze te maken, die controleert op een niet standaard commit boodschap formaat, afdwingt om alleen fast-forward pushes te accepteren en alleen bepaalde gebruikers toestaat om bepaalde subdirectories te wijzigen in een project. Je zult client scripts maken die de ontwikkelaar helpen te ontdekken of hun push geweigerd zal worden en server scripts die het beleid afdwingen. -Ik heb Ruby gebruikt om ze te schrijven, zowel omdat het mijn voorkeur script taal is en omdat ik vind dat het de meest pseudo code uitziende taal is van de scripttalen; dus je zou in staat moeten zijn om de code redelijk te kunnen volgen zelfs als je geen Ruby gebruikt. Maar, iedere taal zal prima werken. Alle voorbeeld haak scripts die met Git meegeleverd worden zijn Perl of Bash scripts, dus je kunt ook genoeg voorbeelden van haken in die talen zijn door naar de voorbeelden te kijken. +Ik heb Ruby gebruikt om ze te schrijven, zowel omdat het mijn voorkeur script taal is als omdat ik vind dat het de meest pseudo code uitziende taal is van de scripttalen; dus je zou in staat moeten zijn om de code redelijk te kunnen volgen zelfs als je geen Ruby gebruikt. Maar elke taal zou prima werken. Alle voorbeeld hook scripts die met Git meegeleverd worden zijn Perl of Bash scripts, dus je kunt ook genoeg voorbeelden van hooks in die talen vinden door naar die bestanden te kijken. -### Server-kant haak ### +### Server-kant hook ### -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: +Al het werk aan de server kant zal in het update bestand in je hooks directory 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 wellicht die gebruiker een shell wrapper geven die bepaalt welke gebruiker er connectie maakt op basis van de publieke sleutel, en dan een omgevingsvariabele instellen waarin die gebruiker wordt gespecificeerd. Ik ga 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 @@ -557,13 +621,13 @@ Al het werk aan de server kant zal in het update bestand in je haken map gaan. H puts "Enforcing Policies... \n(#{$refname}) (#{$oldrev[0,6]}) (#{$newrev[0,6]})" -Ja, ik gebruik een globale variabele. Veroordeel me niet – het is makkelijker om het op deze manier te laten zien. +Ja, ik gebruik globale variabelen. Veroordeel me niet – het is makkelijker om het op deze manier te laten zien. #### 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 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 eerste uitdaging is afdwingen dat elke commit bericht moet voldoen aan een specifiek formaat. Laten we zeggen dat ieder bericht een stuk tekst moet bevatten dat eruit ziet als "ref: 1234", omdat je wilt dat iedere commit gekoppeld is aan een werkonderdeel in je ticket systeem. Je moet dus kijken naar iedere commit die gepusht wordt, zien of die tekst in de commit boodschap zit en als de tekst in één van de commits ontbreekt, met niet nul eindigen zodat de push geweigerd wordt. -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: +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 (plumbing) commando genaamd `git rev-list` te geven. Dit is min of meer 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 @@ -572,9 +636,9 @@ Je kunt de lijst met alle SHA-1 waarden van alle commits die gepusht worden verk dfa04c9ef3d5197182f13fb5b9b1fb7717d2222a 17716ec0f1ff5c77eff40b7fe912f9f6cfd0e475 -Je kunt die uitvoer pakken, door ieder van die commit SHA's heen lopen, de boodschap daarvan pakken, en die boodschap testen tegen een reguliere expressie die op een bepaald patroon zoekt. +Je kunt die uitvoer pakken, door elk van die commit SHA's heen lopen, de boodschap daarvan pakken en die boodschap testen tegen een reguliere expressie die op een bepaald patroon zoekt. -Je moet uit zien te vinden hoe je de commit boodschap kunt krijgen van alle te testen commits. Om de rauwe commit gegevens te krijgen, kun je een andere sanitaire voorzieningen commando genaamd `git cat-file` gebruiken. Ik zal al deze sanitaire voorzieningen commando's behandelen in detail in Hoofdstuk 9; maar voor nu is dit wat het commando je geeft: +Je moet uit zien te vinden hoe je de commit boodschap kunt krijgen van alle te testen commits. Om de echte commit gegevens te krijgen, kun je een andere sanitaire-voorzieningen commando genaamd `git cat-file` gebruiken. Ik zal al deze sanitaire-voorzieningen commando's in detail behandelen in Hoofdstuk 9, maar voor nu is dit wat het commando je geeft: $ git cat-file commit ca82a6 tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf @@ -589,11 +653,11 @@ 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 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: +Je kunt die toverspreuk gebruiken om de commit boodschap te pakken van iedere commit die geprobeerd wordt te pushen 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+)\]/ - # afgedwongen eigen commit bericht formaat + # eigen commit bericht formaat afgedwongen def check_message_format missed_revs = `git rev-list #{$oldrev}..#{$newrev}`.split("\n") missed_revs.each do |rev| @@ -606,15 +670,15 @@ Je kunt die spreuk gebruiken om de commit boodschap te pakken van iedere commit end check_message_format -Door dat in je `update` script te stoppen, zal het updates weigeren die commits bevatten die berichten hebben die niet aan je regel voldoen. +Door dat in je `update` script te stoppen, zal het updates weigeren die commits bevatten die berichten hebben die niet aan jouw regel voldoen. #### 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 gepusht 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 bepaalde delen van je project. Sommige mensen hebben volledige toegang, en anderen hebben alleen toestemming om wijzigingen te pushen naar bepaalde subdirectories 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 zit. Je zult de `update` hook naar die regels laten kijken, zien welke bestanden worden geïntroduceerd voor elke commit die gepusht wordt en bepalen of de gebruiker die de push doet toestemming 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. +Het eerste dat je zult doen is de ACL schrijven. Hier zul je een formaat gebruiken wat 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 deze regel geldt (leeg betekent open toegang). Alle velden worden gescheiden door een pipe (`|`) karakter. -In dit geval heb je een aantal administrators, een aantal documentatie schrijvers met toegang tot de `doc` map, en één ontwikkelaar die alleen toegang heeft tot de `lib` en `test` mappen, en je ACL bestand ziet er zo uit: +In dit geval heb je een aantal beheerders, een aantal documentatie schrijvers met toegang tot de `doc` map, en één ontwikkelaar die alleen toegang heeft tot de `lib` en `test` mappen, en je ACL bestand ziet er zo uit: avail|nickh,pjhyett,defunkt,tpw avail|usinclair,cdickens,ebronte|doc @@ -638,7 +702,7 @@ Je begint met het lezen van deze gegevens in een structuur die je kunt gebruiken access end -Op het ACL bestand dat je eerder bekeken hebt, zal deze `get_acl_access_data` methode een gegevens structuur teruggeven die er zo uit ziet: +Gegeven het ACL bestand dat je eerder bekeken hebt, zal deze `get_acl_access_data` methode een gegevensstructuur opleveren die er als volgt uit ziet: {"defunkt"=>[nil], "tpw"=>[nil], @@ -649,22 +713,22 @@ 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 gepusht worden hebben aangepast, zodat je er zeker van kunt zijn dat de gebruiker die de push doet daar ook toegang tot heeft. +Nu je de rechten bepaald hebt, moet je bepalen welke paden de commits die gepusht worden hebben aangepast, zodat je kunt controleren 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): +Je kunt eenvoudig zien welke bestanden gewijzigd zijn in een enkele commit met de `--name-only` optie op het `git log` commando (kort besproken in Hoofdstuk 2): $ git log -1 --name-only --pretty=format:'' 9f585d README lib/test.rb -Als je gebruik maakt van de ACL structuur die wordt teruggegeven door de `get_acl_access_data` methode en dat controleert met de bestanden in elk van de commits, dan kun je bepalen of de gebruiker toegang heeft om al hun commits te pushen: +Als je gebruik maakt van de ACL structuur die wordt teruggegeven door de `get_acl_access_data` methode en dat gebruikt met de bestanden in elk van de commits, dan kun je bepalen of de gebruiker toegang heeft om al hun commits te pushen: - # staat alleen bepaalde gebruikers toe om bepaalde submappen in een project te wijzigen + # staat alleen bepaalde gebruikers toe om bepaalde subdirectories in een project te wijzigen def check_directory_perms access = get_acl_access_data('acl') - # zie of iemand iets probeert te pushen dat ze niet mogen + # kijk of iemand iets probeert te pushen waar ze niet bij mogen komen new_commits = `git rev-list #{$oldrev}..#{$newrev}`.split("\n") new_commits.each do |rev| files_modified = `git log -1 --name-only --pretty=format:'' #{rev}`.split("\n") @@ -687,17 +751,17 @@ 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 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. +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 het voorkomt in alle toegestane paden. -Nu kunnen je gebruikers geen commits pushen met slechte berichten of met aangepaste bestanden buiten hun toegewezen paden. +Nu kunnen je gebruikers geen commits pushen met slecht vormgegeven berichten of met aangepaste bestanden buiten hun toegewezen paden. #### Fast-forward-only pushes afdwingen #### -Het enige overgebleven ding om af te dwingen is fast-forward-only pushes. In Git versie 1.6 of nieuwer, kun je de `receive.denyDeletes` en `receive.denyNonFastForwards` instellingen aanpassen. Maar dit afdwingen met behulp van een haak werkt ook in oudere versies van Git, en je kunt het aanpassen zodat het alleen gebeurd bij bepaalde gebruikers of wat je later ook verzint. +Het laatste om af te dwingen is fast-forward-only pushes. Om dit te regelen, kan je simpelweg de `receive.denyDeletes` en `receive.denyNonFastForwards` instellingen aanpassen. Maar dit afdwingen met behulp van een hook werkt ook, en je kunt het aanpassen zodat het alleen gebeurt bij bepaalde gebruikers of om elke reden die je later bedenkt. -De logica om dit te controleren is zien of iedere commit die bereikbaar is vanuit de oudere revisie, niet bereikbaar is vanuit de nieuwere. Als er geen zijn, dan was het een fast-forward push; anders weiger je het: +De logica om dit te controleren, is zien of er een commit is die bereikbaar is vanuit de oudere revisie, maar niet bereikbaar is vanuit de nieuwere. Als er geen zijn dan was het een fast-forward push, anders weiger je het: - # dwingt fast-forward only pushes af + # dwingt fast-forward-only pushes af def check_fast_forward missed_refs = `git rev-list #{$newrev}..#{$oldrev}` missed_ref_count = missed_refs.split("\n").size @@ -709,7 +773,7 @@ De logica om dit te controleren is zien of iedere commit die bereikbaar is vanui check_fast_forward -Alles is ingesteld. Als je `chmod u+x .git/hooks/update` uitvoert, wat het bestand is waarin je al deze code gestopt hebt, en dan probeert te pushen naar een non-fast-forwarded referentie, krijg je zoiets als dit: +Alles is ingesteld. Als je `chmod u+x .git/hooks/update` uitvoert, wat het bestand is waarin je al deze code gestopt hebt, en dan probeert een non-fast-forwarded referentie te pushen krijg je zoiets als dit: $ git push -f origin master @@ -727,12 +791,12 @@ Alles is ingesteld. Als je `chmod u+x .git/hooks/update` uitvoert, wat het besta ! [remote rejected] master -> master (hook declined) error: failed to push some refs to 'git@gitserver:project.git' -Er zijn hier een aantal interessante dingen. Ten eerste, zie je dit als de haak start met uitvoeren. +Er zijn hier een aantal interessante dingen. Ten eerste, zie je dit als de hook start met uitvoeren. Enforcing Policies... (refs/heads/master) (fb8c72) (c56860) -Zie dat je dat afgedrukt hebt naar stdout aan het begin van je update script. Het is belangrijk om te zien dat alles dat je script naar stdout uitvoert, naar de client overgebracht wordt. +Merk op dat je dat afgedrukt hebt naar stdout aan het begin van je update script. Het is belangrijk om te zien dat alles dat je script naar stdout uitvoert, naar de client overgebracht wordt. Het volgende dat je op zal vallen is de foutmelding. @@ -740,15 +804,15 @@ Het volgende dat je op zal vallen is de foutmelding. error: hooks/update exited with error code 1 error: hook declined to update refs/heads/master -De eerste regel was door jou afgedrukt, de andere twee waren Git die je vertelde dat het update script met niet nul eindigde en dat dat hetgeen is dat je push weigerde. Als laatste heb je dit: +De eerste regel was door jou afgedrukt, de andere twee komen van Git die je vertelt dat het update script met niet nul geëindigd is en dat die degene is die je push weigerde. Tot slot heb je dit: To git@gitserver:project.git ! [remote rejected] master -> master (hook declined) error: failed to push some refs to 'git@gitserver:project.git' -Je zult een remote weiger bericht zien voor iedere referentie die je haak weigerde, en het verteld je dat het specifiek was geweigerd omdat het een haak fout was. +Je zult een remote weiger bericht zien voor elke referentie die door de hook wordt geweigerd, en het vertelt je dat het specifiek was geweigerd wegens een hook fout. -Daarnaast zul je een foutmelding zien dat je uitvoert als de ref marker niet in één van je commits zit. +Daarnaast zal je een foutmelding zien als in één van je commits de ref-marker ontbreekt. [POLICY] Your message is not formatted correctly @@ -757,15 +821,15 @@ Of als iemand een bestand probeert aan te passen waar ze geen toegang tot hebben [POLICY] You do not have access to push to lib/test.rb -Dat is alles. Vanaf nu, zolang als het `update` script aanwezig en uitvoerbaar is, zal je repository nooit teruggedraaid worden en zal nooit een commit bericht zonder je patroon erin bevatten, en je gebruikers zullen ingeperkt zijn. +Dat is alles. Vanaf nu, zolang als het `update` script aanwezig en uitvoerbaar is, zal je repository nooit teruggedraaid worden en zal nooit een commit bericht bevattenb waar je patroon niet in zit, en je gebruikers zullen in hun bewegingsruimte beperkt zijn. -### Client-kant haken ### +### Hooks aan de client-kant ### -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 nadeel van deze aanpak is het zeuren dat geheid zal beginnen zodra de commits van je gebruikers geweigerd worden. Het feit dat hun zorgzaam vervaardigde werk op het laatste moment pas geweigerd wordt kan enorm frustrerend en verwarrend zijn en daarnaast zullen ze hun geschiedenis moeten aanpassen om het te corrigeren, wat niet altijd geschikt is voor de wat angstiger aangelegde mensen. -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. +Het antwoord op dit dilemma is een aantal client-kant hooks te leveren, die gebruikers kunnen gebruiken 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 lastiger 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 in hun `.git/hooks` map laten zetten en ze uitvoerbaar maken. Je kunt deze hooks 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: +Om te beginnen zou je de 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` hook 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 dwingen om de commit af te breken als het niet juist is: #!/usr/bin/env ruby message_file = ARGV[0] @@ -778,18 +842,18 @@ Om te beginnen zou je je commit boodschap moeten controleren, vlak voordat ieder exit 1 end -Als dat script op z'n plaats staat (in `.git/hooks/commit-msg`) en uitvoerbaar is, en je commit met een verkeerd formaat bericht, dan zie je dit: +Als dat script op z'n plaats staat (in `.git/hooks/commit-msg`), uitvoerbaar is en je commit met een verkeerd geformateerd bericht, dan zie je dit: $ git commit -am 'test' [POLICY] Your message is not formatted correctly -In dat geval was er geen commit afgerond. Maar, als je bericht het juiste patroon bevat, dan staat Git je toe te committen: +In dat geval is er geen commit gedaan. Maar als je bericht het juiste patroon bevat, dan staat Git je toe te committen: $ git commit -am 'test [ref: 132]' [master e05c914] test [ref: 132] 1 files changed, 1 insertions(+), 0 deletions(-) -Vervolgens wil je er zeker van zijn dat je geen bestanden buiten je ACL scope aanpast. Als de `.git` map van je project een kopie van het ACL bestand bevat dat je eerder gebruikte, dan zal het volgende `pre-commit` script die beperkingen op je toepassen: +Vervolgens wil je er zeker van zijn dat je geen bestanden buiten je ACL scope aanpast. Als de `.git` directory van je project een kopie van het ACL bestand bevat dat je eerder gebruikte, dan zal het volgende `pre-commit` script die beperkingen voor je controleren: #!/usr/bin/env ruby @@ -818,7 +882,7 @@ Vervolgens wil je er zeker van zijn dat je geen bestanden buiten je ACL scope aa check_directory_perms -Dit is ongeveer hetzelfde script als aan de server kant, maar met twee belangrijke verschillen. Als eerste staat het ACL bestand op een andere plek, omdat dit script vanuit je werkmap draait, niet vanuit je Git map. Je moet het pad naar het ACL bestand wijzigen van dit +Dit is bijna hetzelfde script als aan de server kant, maar met twee belangrijke verschillen. Als eerste staat het ACL bestand op een andere plek, omdat dit script vanuit je werkdirectory draait, en niet vanuit je Git directory. Je moet het pad naar het ACL bestand wijzigen van dit access = get_acl_access_data('acl') @@ -826,7 +890,7 @@ in dit: access = get_acl_access_data('.git/acl') -Het andere belangrijke verschil is de manier waarop je een lijst krijgt met bestanden die je gewijzigd hebt. Omdat de server kant methode naar de log van commits kijkt, en op dit punt je commit nog niet opgeslagen is, moet je je bestandslijst in plaats daarvan uit het stage gebied halen. In plaats van +Het andere belangrijke verschil is de manier waarop je een lijst krijgt met bestanden die gewijzigd is. Omdat de server kant methode naar de log van commits kijkt en nu je commit nog niet opgeslagen is, moet je de bestandslijst in plaats daarvan uit het stage gebied halen. In plaats van files_modified = `git log -1 --name-only --pretty=format:'' #{ref}` @@ -834,14 +898,13 @@ 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 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 gepusht hebt, of een andere lokale branch naar dezelfde remote branch proberen te pushen. +Maar dat zijn de enige twee verschillen, verder werkt het script op dezelfde manier. Een voorwaarde is dat het van je verlangt dat je lokaal werkt als dezelfde gebruiker die pushed naar de remote machine. Als dat anders is, moet je de `$user` variabele handmatig instellen. -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. +Het laatste wat je moet doen is het controleren dat je niet probeert non-fast-forward referenties te pushen, maar dat komt minder voor. Om een referentie te krijgen dat non-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 hook de push tegenhoudt, is het enige ding wat je kunt proberen af te vangen het abusievelijk 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: +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 ergens 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: #!/usr/bin/env ruby @@ -865,14 +928,14 @@ 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 gepusht zijn door dit uit te voeren: +Dit script gebruikt een syntax dat niet behandeld is in de Revisie Selectie paragraaf 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} -De `SHA^@` syntax wordt vervangen door alle ouders van die commit. Je bent aan het kijken naar iedere commit die bereikbaar is vanuit de laatste commit op de remote en die niet bereikbaar is vanuit elke ouder van de SHA's die je probeert te pushen – wat betekend dat het een fast-forward is. +De `SHA^@` syntax wordt vervangen door alle ouders van die commit. Je bent op zoek naar een commit die bereikbaar is vanuit de laatste commit op de remote en die niet bereikbaar is vanuit enige ouder van alle SHA's die je probeert te pushen – wat inhoudt dat het een fast-forward is. -Het grote nadeel van deze aanpak is dat het erg traag kan zijn en vaak onnodig is – als je de push niet probeert te forceren met de `-f` optie, dan zal de server je proberen te waarschuwen en de push niet accepteren. Maar, het is een aardige oefening en kan je in theorie helpen om een rebase te omzeilen die je later zult moeten herstellen. +Het grote nadeel van deze aanpak is dat het erg traag kan zijn en vaak onnodig is, als je de push niet probeert te forceren met de `-f` optie, dan zal de server je al waarschuwen en de push niet accepteren. Maar, het is een aardige oefening en kan je in theorie helpen om een rebase te voorkomen die je later zult moeten herstellen. ## Samenvatting ## -Je hebt nu de meeste manieren behandeld waarin je je Git client en server aan kunt passen om aan jouw werkwijze en projecten te voldoen. Je hebt over alle soorten configuratie instellingen geleerd, bestands-gebaseerde attributen, en gebeurtenis haken, en je hebt een voorbeeld server met een afgedwongen beleid gebouwd. Je zou nu in staat moeten zijn om Git bijna iedere werkwijze die je kunt verzinnen te laten doen. +Je hebt nu de meeste manieren behandeld waarin je jouw Git client en server aan kunt passen om aan jouw werkwijze en projecten te voldoen. Je hebt allerhande configuratie instellingen geleerd, bestands-gebaseerde attributen, en gebeurtenis hooks (event hooks) en je hebt een voorbeeld gemaakt van een server die beleid afdwingt. Je zou nu in staat moeten zijn om Git bijna iedere werkwijze die je kunt verzinnen te laten doen. From b909bfdff73d7c7ef21c6b3499038bb5e0eb3f7d Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 10:18:03 -0600 Subject: [PATCH 161/690] Reviewing "Public Small Project" --- it/05-distributed-git/01-chapter5.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index a21356ba6..64f713342 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -385,7 +385,7 @@ Figura 5-15. Sequenza base di questo workflow con team separati. Contribuire ad un progetto pubblico è leggermente differente. Poiché non hai il permesso di aggiornare direttamente i rami del progetto, devi far avere il tuo lavoro ai mantenitori in qualche altro modo. Questo primo esempio descrive come contribuire con i fork su host Git che lo supportano in maniera semplice. I siti di repo.or.cz e GitHub lo supportano, e molti mantenitori di progetti si aspettano questo tipo di contribuzione. La sezione successiva tratta i progetti che preferiscono ricevere le patch per e-mail -Innanzitutto, probabilemnte dovrai clonare il repository principale, creare un ramo per le modifiche che hai in programma di fare, e fare li il tuo lavoro. La sequenza è grosso modo questa: +Per iniziare probabilemnte dovrai clonare il repository principale, creare un branch per le modifiche che programmi di fare, quindi lavorarci. La sequenza è grosso modo questa: $ git clone (url) $ cd project @@ -395,13 +395,13 @@ Innanzitutto, probabilemnte dovrai clonare il repository principale, creare un r $ (lavoro) $ git commit -Potresti voler usare `rebase -i` per ridurre il tuo lavoro ad un singolo commit, o riorganizzare il lavoro nei commit per rendere le modifiche semplice da controllare per il mantenitore - vedi il Capitolo 6 per altre informazioni sul rebasing interattivo. +Potresti voler usare `rebase -i` per ridurre il tuo lavoro a una singola commit, o riorganizzare il lavoro delle commit per facilitare il lavoro di revisione dei mantenitori - vedi il Capitolo 6 per altre informazioni sul rebase interattivo. -Quando il tuo lavoro sul ramo è completato e sei pronto per farlo avere ai mantenitori, vai alla pagina principale del progetto e clicca sul link "Fork", creando una tua copia scrivibile del progetto. Dovrai poi aggiungere questo nuovo URL di repository come secondo URL remoto, in questo caso chiamato `miofork`: +Quando il lavoro sul tuo branch è completato e sei pronto per condividerlo con i mantenitori, vai alla pagina principale del progetto e clicca sul pulsante "Fork", creando la tua copia modificabile del progetto. Dovrai quindi aggiungere l'URL di questo nuovo repository come un secondo remoto, chiamato in questo caso `miofork`: $ git remote add miofork (url) -Dovrai eseguire un push del tuo lavoro verso esso. E' più semplice eseguire il push del ramo su cui stai lavorando piuttosto che unirlo al ramo master ed eseguire il push di quest'ultimo. La ragione è che se il tuo lavoro non è accettato, oppure lo è solo in parte, non dovrai tornare indietro nei commit sul tuo ramo master. Se i mantenitori uniscono, eseguono un rebase, o prendono pezzi dal tuo lavoro, riuscirai in ogni caso a recuperarlo eseguendo un pull dal loro repository: +E dovrai eseguire una push del tuo lavoro verso il nuovo repository. È più semplice fare la push del branch a cui stai lavorando piuttosto che unirlo al tuo master e fare la push di quest'ultimo. La ragione è che se il tuo lavoro non verrà accettato, oppure lo sarà solo in parte, non dovrai ripristinare il tuo master. Se i mantenitori uniscono, fanno un rebase, o prendono pezzi dal tuo lavoro col cherry-pick, otterrai il nuovo master alla prossima pull dal loro repository: $ git push myfork funzionalitaA From 7d348e209fb5d07259bc72602e465dafba76cfee Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 10:54:00 -0600 Subject: [PATCH 162/690] Reviewing "Public Small Project" --- it/05-distributed-git/01-chapter5.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 64f713342..75f37dca7 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -405,9 +405,9 @@ E dovrai eseguire una push del tuo lavoro verso il nuovo repository. È più sem $ git push myfork funzionalitaA -Quando hai eseguito il push del tuo lavoro verso il tuo fork, devi farlo sapere al mantenitore. Questo passaggio è chiamato spesso richiesta di pull (pull request), e puoi farlo sia tramite il sito - GitHub ha un pulsante "pull request" che automaticamente notifica al mantenitore - o eseguire il comando `git request-pull` ed inviare l'output il mantenitore manualmente. +Quando avrai eseguito la push del tuo lavoro sul tuo fork, devi avvisare i mantenitori. Questo passaggio viene spesso definito "richiesta di pull" (pull request), e puoi farlo tramite lo stesso sito - GitHub ha un pulsante "pull request" che automaticamente notifica i mantenitori - o eseguire il comando `git request-pull` e inviare manualmente via email l'output ai mantenitori. -Il comando `request-pull` riceve come parametri il ramo base sul quale vuoi far applicare le modifiche ed l'URL del repository Git da cui vuoi estrarle, ed in output fornisce un riassunto di tutte queste modifiche. Per esempio, se Jessica volesse inviare a John una richiesta di pull, e lei ha eseguito due commit sul ramo di cui ha appena effettuato il push, può eseguire questo: +Il comando `request-pull` riceve come parametri il branch di base sul quale vuoi far applicare le modifiche e l'URL del repository Git da cui vuoi che le prendano, e produce il sommario di tutte queste modifiche in output. Se, per esempio, Jessica volesse inviare a John una richiesta di pull, e avesse eseguito due commit sul branch di cui ha appena effettuato il push, può eseguire questo: $ git request-pull origin/master miofork The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40: @@ -425,9 +425,9 @@ Il comando `request-pull` riceve come parametri il ramo base sul quale vuoi far lib/simplegit.rb | 10 +++++++++- 1 files changed, 9 insertions(+), 1 deletions(-) -L'output può essere inviato al mantenitore. Esso riporta da dove è stato creato il nuovo ramo, un riassunto dei commit e dice da dove si può eseguire il pull. +L'output può essere inviato ai mantenitori: riporta da dove è stato creato il nuovo branch, un riassunto delle commit e da dove si possono scaricare. -Su un progetto dove non sei il mantenitore, è generalmente comune avere un ramo come `master` sempre collegato a `origin/master` ed eseguire il tuo lavoro su rami che puoi eliminare nel caso non venissero accettati. Avere il lavoro suddiviso in rami inoltre rende semplice per te eseguire il rebase del tuo lavoro se è stato modificato il repository principale ed i tuoi commit non possono venire applicati in maniera pulita. Per esempio, se vuoi aggiungere un secondo argomento di lavoro ad un progetto, non continuare a lavorare sul ramo di cui hai appena fatto il push - creane un altro partendo dal ramo `master` del repository: +In un progetto dove non sei il mantenitore normalmente è comodo avere un branch come `master` sempre collegato a `origin/master` e lavorare su altri branch che puoi eliminare nel caso non venissero accettati. Suddividere il lavoro in branch ti rende più semplice ribasare il tuo lavoro se il repository principale è stato modificato e le tue commit non possono venire applicate in maniera pulita. Se per esempio vuoi aggiungere un'altra caratteristica al progetto, invece di continuare a lavorare sul branch di cui hai appena fatto la push, creane un altro partendo dal `master` del repository: $ git checkout -b funzionalitaB origin/master $ (lavoro) From 1679be770e7a70a40f445ced669b2e52ac9f9431 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 11:01:19 -0600 Subject: [PATCH 163/690] Reviewing "Public Small Project" --- it/05-distributed-git/01-chapter5.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 75f37dca7..720824037 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -427,7 +427,7 @@ Il comando `request-pull` riceve come parametri il branch di base sul quale vuoi L'output può essere inviato ai mantenitori: riporta da dove è stato creato il nuovo branch, un riassunto delle commit e da dove si possono scaricare. -In un progetto dove non sei il mantenitore normalmente è comodo avere un branch come `master` sempre collegato a `origin/master` e lavorare su altri branch che puoi eliminare nel caso non venissero accettati. Suddividere il lavoro in branch ti rende più semplice ribasare il tuo lavoro se il repository principale è stato modificato e le tue commit non possono venire applicate in maniera pulita. Se per esempio vuoi aggiungere un'altra caratteristica al progetto, invece di continuare a lavorare sul branch di cui hai appena fatto la push, creane un altro partendo dal `master` del repository: +In un progetto dove non sei il mantenitore normalmente è comodo avere un branch come `master` sempre collegato a `origin/master` e lavorare su altri branch che puoi eliminare nel caso non venissero accettati. Suddividere il lavoro in branch per argomento ti rende più semplice ribasare il tuo lavoro se il repository principale è stato modificato e le tue commit non possono venire applicate in maniera pulita. Se per esempio vuoi aggiungere un'altra caratteristica al progetto, invece di continuare a lavorare sul branch di cui hai appena fatto la push, creane un altro partendo dal `master` del repository: $ git checkout -b funzionalitaB origin/master $ (lavoro) From 04b2d6d444b72524f59d82145e0a6af891fc92d7 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 11:05:23 -0600 Subject: [PATCH 164/690] Reviewing "Public Small Project" --- it/05-distributed-git/01-chapter5.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 720824037..0e32465cb 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -436,10 +436,10 @@ In un progetto dove non sei il mantenitore normalmente è comodo avere un branch $ (email al mantenitore) $ git fetch origin -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. +Ora ognuno dei tuoi lavori è separato come in una coda di modifiche che puoi riscrivere, ribasare e modificare senza che gli argomenti interferiscano o dipendano dagli altri, come in Figura 5-16. Insert 18333fig0516.png -Figura 5-16. Conologia iniziale dei commit con del lavoro su funzionalitaB. +Figura 5-16. Conologia iniziale col 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: From 536812c9979886f0c51b8a1055f0ee9849366bb3 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 11:08:21 -0600 Subject: [PATCH 165/690] Reviewing "Public Small Project" --- it/05-distributed-git/01-chapter5.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 0e32465cb..9f275c97d 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -441,16 +441,16 @@ Ora ognuno dei tuoi lavori è separato come in una coda di modifiche che puoi ri Insert 18333fig0516.png Figura 5-16. Conologia iniziale col 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: +Supponiamo che il mantenitore del progetto ha inserito una manciata di altre modifiche e provato il tuo primo branch ma non riesce più ad applicare tali modifiche in maniera pulita. In questo caso puoi provare a ribasare il nuovo `origin/master` su quel branch, risolvere i conflitti per poi inviare di nuovo le tue modifiche: $ git checkout funzionalitaA $ git rebase origin/master $ git push –f miofork featureA -Questo riscrive la tua cronologia per farla diventare come quella di Figura 5-17. +Questo riscrive la tua cronologia per essere come quella di Figura 5-17. Insert 18333fig0517.png -Fgiura 5-17. La cronologia dei commit dopo il lavoro su funzionalitaA. +Fgiura 5-17. La cronologia ddopo il lavoro su funzionalitaA. Dato che hai eseguito un rebase del ramo, devi specificare l'opzione `-f` per eseguire un push, per poter sostituire il ramo `funzionalitaA` sul server con un commit che non discende da esso. Un'alternativa potrebbe essere un push di questo nuovo lavoro verso un diverso branch sul server (chiamato ad esempio `funzionalitaAv2`). From 723b8342ec217f4d8bfc24125d12e39578071bd8 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 11:23:03 -0600 Subject: [PATCH 166/690] Revied "Public Small Project" --- it/05-distributed-git/01-chapter5.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 9f275c97d..f637601a7 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -452,9 +452,9 @@ Questo riscrive la tua cronologia per essere come quella di Figura 5-17. Insert 18333fig0517.png Fgiura 5-17. La cronologia ddopo il lavoro su funzionalitaA. -Dato che hai eseguito un rebase del ramo, devi specificare l'opzione `-f` per eseguire un push, per poter sostituire il ramo `funzionalitaA` sul server con un commit che non discende da esso. Un'alternativa potrebbe essere un push di questo nuovo lavoro verso un diverso branch sul server (chiamato ad esempio `funzionalitaAv2`). +Poiché hai eseguito un rebase del branch, per poter sostituire il branch `funzionalitaA` sul server con una commit che non discenda dallo stesso, devi usare l'opzione `-f` perché la push funzioni. Un'alternativa sarebbe fare una push di questo nuovo lavoro su un branch diverso (chiamato per esempio `funzionalitaAv2`). -Diamo un'occhiata ad un possibile scenario: il mantenitore ha guardato al tuo lavoro in un secondo ramo, e gradisce il concetto ma vorrebbe che tu cambiassi dei dettagli dell'implementazione. Potresti inoltre cogliere questa opportunità per basarti sul ramo `master` corrente. Crei un nuovo ramo basato sul corrente `origin/master`, sposti i cambiamenti di `funzionalitaB` qui, risolvi i conflitti, cambi l'implementazione, e poi esegui il push come un nuovo ramo: +Diamo un'occhiata a un altro scenario possibile: il mantenitore ha visto tuo lavoro nel secondo branch e gli piace il concetto ma vorrebbe che tu cambiassi un dettaglio dell'implementazione. Potresti cogliere l'occasione per ribasarti sul `master` corrente. Crea un nuovo branch basato sull'`origin/master` attuale, sposta lì le modifiche di `funzionalitaB`, risolvi gli eventuali conflitti, fai la modifica all'implementazione ed esegui la push del tutto su un nuovo branch: $ git checkout -b funzionalitaBv2 origin/master $ git merge --no-commit --squash funzionalitaB @@ -462,12 +462,12 @@ Diamo un'occhiata ad un possibile scenario: il mantenitore ha guardato al tuo la $ git commit $ git push miofork funzionalitaBv2 -L'opzione `--squash` prende tutto il lavoro nel ramo da unire e lo aggiunge come un singolo commit al ramo in cui sei. L'opzione `no-commit` dice a Git di non eseguire automaticamente il commit. Questo ti consente di aggiungere i cambiamenti da un altro ramo e poi eseguire altre modifiche prima di effettuare il nuovo commit. +L'opzione `--squash` prende tutto il lavoro dal branch da unire e lo aggiunge come una singola commit nel branch dove sei. L'opzione `--no-commit` dice a Git di non fare la commit automaticamente. Questo ti permette di aggiungere le modifiche di un altro branch e fare ulteriori modifiche prima di effettuare la nuovo commit. -Ora puoi inviare al mantenitore un messaggio dicendo che hai effettuato i cambiamenti richiesti e che può trovare nel ramo `funzionalitaBv2` (vedi Figura 5-18). +Ora puoi avvisare i mantenitori che hai effettuato le modifiche richieste e che possono trovarle nel branch `funzionalitaBv2` (vedi Figura 5-18). Insert 18333fig0518.png -Figura 5-18. La cronologia dei commit dopo il lavoro su funzionalitaBv2. +Figura 5-18. La cronologia dopo il lavoro su funzionalitaBv2. ### Grande Progetto Pubblico ### From 8b13b617aa354ac2327b3befe84a0594d2930374 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 12:02:01 -0600 Subject: [PATCH 167/690] Reviewing "Public Large Project" --- it/05-distributed-git/01-chapter5.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index f637601a7..76c08d2e2 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -471,7 +471,7 @@ Figura 5-18. La cronologia dopo il lavoro su funzionalitaBv2. ### Grande Progetto Pubblico ### -Molti grandi progetti hanno definito delle procedure da seguire per poter inviare delle patch. Avrai bisogno di leggere le specifiche regole di ogni progetto, perchè queste potranno differire tra loro. Tuttavia, molti grandi progetti pubblici accettano patch tramite una mailing list degli sviluppatori, quindi tratterò ora un esempio di questo genere. +Molti grandi progetti hanno definito delle procedure per l'invio delle patch: dovrai leggere le specifiche di ciascun progetto, perchè saranno diverse. Tuttavia molti grandi progetti pubblici accettano patch tramite la mailing list degli sviluppatori, quindi tratterò ora questo caso. Il flusso di lavoro è simile ai casi precedenti: crei un ramo per ognuna delle modifiche sulle quali intendi lavorare. La differenza sta in come invii tali modifiche al progetto. Invece di fare un tuo fork del progetto e di inviare le tue modifiche ad esso tramite push, crei una versione e-mail di ognuno dei commit e l invii tramite posta elettronica alla mailing list degli sviluppatori: From 5fd61afef7fd1b0b09e2a27ac89445b8799579b8 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 12:03:57 -0600 Subject: [PATCH 168/690] Reviewing "Public Large Project" --- it/05-distributed-git/01-chapter5.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 76c08d2e2..8d209b772 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -473,7 +473,7 @@ Figura 5-18. La cronologia dopo il lavoro su funzionalitaBv2. Molti grandi progetti hanno definito delle procedure per l'invio delle patch: dovrai leggere le specifiche di ciascun progetto, perchè saranno diverse. Tuttavia molti grandi progetti pubblici accettano patch tramite la mailing list degli sviluppatori, quindi tratterò ora questo caso. -Il flusso di lavoro è simile ai casi precedenti: crei un ramo per ognuna delle modifiche sulle quali intendi lavorare. La differenza sta in come invii tali modifiche al progetto. Invece di fare un tuo fork del progetto e di inviare le tue modifiche ad esso tramite push, crei una versione e-mail di ognuno dei commit e l invii tramite posta elettronica alla mailing list degli sviluppatori: +Il flusso di lavoro è simile al caso precedente: crei un branch per ognuna delle modifiche sulle quali intendi lavorare. La differenza sta nel modo in cui invii tali modifiche al progetto. Invece di fare un tuo fork del progetto e di inviare le tue modifiche con una push, crei una versione e-mail di ogni commit e invii il tutto per email alla mailing list degli sviluppatori: $ git checkout -b topicA $ (work) From 5bfefdba259324bc348f8ff99ceef1cbb249e2cf Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 12:19:53 -0600 Subject: [PATCH 169/690] Reviewing "Public Large Project" --- it/05-distributed-git/01-chapter5.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 8d209b772..0ccc3ab3e 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -481,13 +481,13 @@ Il flusso di lavoro è simile al caso precedente: crei un branch per ognuna dell $ (work) $ git commit -Ora hai due commit che vuoi inviare alla mailing list. Usi `git format-patch` per generare un file formato mbox che puoi inviare via e-mail alla mailing list. Il comando `git format-patch` trasforma ogni commit in un messaggio email il cui oggetto è formato dalla prima linea del messaggio del commit e il cui contenuto è il rimanente testo del commit più la patch delle modifiche. La cosa bella di tutto ciò è che applicando i commit da un'email si conservano tutte le informazioni in essi contenute in maniera appropriata, come vedrai meglio nella prossima sezione: +Ora hai due commit che vuoi inviare alla mailing list. Usi `git format-patch` per generare un file formato mbox che possa inviare via e-mail alla lista: questo trasforma ogni commit in un messaggio email il cui oggetto è la prima linea del messaggio della commit e il contenuto è dato dal resto del messaggio della commit più la patch delle modifiche. La cosa bella di tutto ciò è che, applicando le commit da un'email, vengono mantenute le informazioni delle commit, come vedrai meglio nella prossima sezione: $ git format-patch -M origin/master 0001-add-limit-to-log-function.patch 0002-changed-log-output-to-30-from-25.patch -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: +Il comando `format-patch` visualizza i nomi dei file delle patch che crea. Il parametro `-M` indica a Git di tener traccia dei file rinominati. I file alla fine avranno questo aspetto: $ cat 0001-add-limit-to-log-function.patch From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 @@ -517,7 +517,7 @@ Il comando `format-patch` visualizza i nomi dei file patch che vengono creati. I -- 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 per aggiungere maggiori informazioni per la mailing list che però non vuoi che vengano visualizzate all'interno del messaggio della commit. Se aggiungi del testo tra la riga con `---` e l'inizio della patch (ad esempio la riga `lib/simplegit.rb`), gli sviluppatori potranno leggerlo ma verrà escluso dal messaggio della commit una volta che la patch sarà 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. From 757615a88d18f259021d6a4f2ab22466f9f364e2 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 14:01:05 -0600 Subject: [PATCH 170/690] Reviewed "Public Large Project" --- it/05-distributed-git/01-chapter5.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 0ccc3ab3e..ffedbe393 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -519,9 +519,9 @@ Il comando `format-patch` visualizza i nomi dei file delle patch che crea. Il pa Puoi anche modificare questi file per aggiungere maggiori informazioni per la mailing list che però non vuoi che vengano visualizzate all'interno del messaggio della commit. Se aggiungi del testo tra la riga con `---` e l'inizio della patch (ad esempio la riga `lib/simplegit.rb`), gli sviluppatori potranno leggerlo ma verrà escluso dal messaggio della commit una volta che la patch sarà 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. +Per inviare le patch alla mailing list, puoi copiare ed incollare il file nel tuo programma di posta o inviare il tutto dalla riga di comando. Incollare il testo è spesso causa di problemi di formattazione, sopratutto con i client di posta "intelligenti" che non mantengono correttamente i caratteri di a-capo e altri caratteri di spaziatura. Fortunatamente Git fornisce uno strumento che ti aiuta a inviare correttamente le patch tramite IMAP, che potrebbe facilitarti il compito. Ti mostrerò come mandare una patch con Gmail perché è il client di posta che utilizzo, ma troverai istruzioni dettagliate per molti client di posta alla fine del documento `Documention/SubmittingPatches`, che trovi nel codice sorgente di Git. -Prima di tutto, devi configurare la sezione imap nel tuo file `~/.gitconfig`. Puoi settare ogni valore separatamente con una serie di comandi `git config` o aggiungerli manualmente al suo interno tramite un editor di testo. Alla fine il tuo file di configurazione dovrebbe essere più o meno così: +Prima di tutto devi configurare la sezione imap nel tuo file `~/.gitconfig`. Puoi configurare ogni parametro separatamente con una serie di comandi `git config` o scriverli direttamente con un editor di testo. Alla fine il tuo file di configurazione dovrebbe comunque essere più o meno così: [imap] folder = "[Gmail]/Drafts" @@ -531,7 +531,7 @@ Prima di tutto, devi configurare la sezione imap nel tuo file `~/.gitconfig`. Pu port = 993 sslverify = false -Se il tuo server IMAP non usa SSL, le ultime due righe probabilmente non ti saranno necessarie e il valore del campo host sarà `imap://` anzichè `imaps://`. Quando tutto ciò è configurato, puoi usare `git send-email` per inviare la serie di patch alla cartella "Bozze" del tuo server IMAP: +Se il tuo server IMAP non usa SSL, probabilmente le ultime due righe non ti saranno necessarie e il valore del campo host sarà `imap://` invece di `imaps://`. Quando avrai configurato tutto, potrai usare `git send-email` per inviare la serie di patch alla cartella "Bozze" del tuo server IMAP: $ git send-email *.patch 0001-added-limit-to-log-function.patch @@ -541,7 +541,7 @@ Se il tuo server IMAP non usa SSL, le ultime due righe probabilmente non ti sara 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: +Per ciascuna patch che stai per inviare, Git produce alcune informazioni di log che appariranno più o meno così: (mbox) Adding cc: Jessica Smith from \line 'From: Jessica Smith ' @@ -558,7 +558,7 @@ Poi, Git produce alcune informazioni di log che figureranno più o meno così pe Result: OK -A questo punto, dovresti essere in grado di andare nella tua cartella delle bozze, cambiare il campo "A:" con la mailing list alla quale vuoi inviare la patch, aggiungere in copia il mantenitore del progetto o la persona responsabile per quella determinata sezione ed inviare il codice. +A questo punto, dovresti essere in grado di andare nella cartella bozze del tuo account, inserire nel campo "A:" la mailing list alla quale vuoi inviare la patch, magari aggiungendo in copia il mantenitore del progetto o la persona responsabile per quella determinata sezione e manda l'email. ### Sommario ### From e00b315fdd17693af57b08b375a8f71a6a340838 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 14:11:53 -0600 Subject: [PATCH 171/690] typo --- it/05-distributed-git/01-chapter5.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index ffedbe393..83227cd10 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -52,7 +52,7 @@ Questo tipo di workflow non è comune ma può essere utile in progetti molto gra Ci sono alcuni workflow utilizzati comunemente che sono possibili con un sistema distribuito come Git, ma esistono molte possibili varianti per adattarli al tuo caso specifico. Ora che hai (spero) determinato quale combinazione di workflow possa funzionare per te, illustrerò alcuni esempi sui ruoli principali dei diversi workflow. -## Contribuire ad un Progetto ## +## Contribuire a un Progetto ## Conosci i diversi workflow e dovresti aver chiaro i fondamentali di Git. In questa sezione imparerai alcuni metodi comuni per contribuire a un progetto. @@ -562,7 +562,7 @@ A questo punto, dovresti essere in grado di andare nella cartella bozze del tuo ### Sommario ### -Questa sezione ha coperto un certo numero di workflow comuni che è facile incontrare quando si ha a che fare con tipi diversi di progetti Git e ha introdotto un paio di nuovi strumenti che ti possono aiutare a gestire questo processo. Ora, vedrai come si lavora con l'altra faccia della medaglia: mantenere un progetto Git. Imparerai ad essere un dittatore benevolo o integration manager. +Questa sezione ha trattato alcuni workflow comuni che è facile incontrare quando si ha a che fare con progetti Git diversi e ha introdotto un paio di strumenti nuovi per aiutarti a gestire questo processo. Vedremo ora l'altra faccia della medaglia: mantenere un progetto Git. Imparerai ad essere un dittatore benevolo (_benevolent dictator_) o un manager d'integrazione (_integration manager_). ## Mantenere un Progetto ## From 7601fbfc4b9c232528dac078b3eb50c388f00e62 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 14:31:40 -0600 Subject: [PATCH 172/690] Reviewed "Maintaining a Project" --- it/05-distributed-git/01-chapter5.markdown | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 83227cd10..4f004224f 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -531,7 +531,8 @@ Prima di tutto devi configurare la sezione imap nel tuo file `~/.gitconfig`. Puo port = 993 sslverify = false -Se il tuo server IMAP non usa SSL, probabilmente le ultime due righe non ti saranno necessarie e il valore del campo host sarà `imap://` invece di `imaps://`. Quando avrai configurato tutto, potrai usare `git send-email` per inviare la serie di patch alla cartella "Bozze" del tuo server IMAP: +Se il tuo server IMAP non usa SSL, probabilmente le ultime due righe non ti saranno necessarie e il valore del campo host sarà `imap://` invece di `imaps://`. +Quando avrai configurato tutto, potrai usare `git send-email` per inviare la serie di patch alla cartella "Bozze" del tuo server IMAP: $ git send-email *.patch 0001-added-limit-to-log-function.patch @@ -566,7 +567,7 @@ Questa sezione ha trattato alcuni workflow comuni che è facile incontrare quand ## Mantenere un Progetto ## -Oltre a sapere come contribuire ad un progetto in maniera effettiva, dovrai probabilmente sapere anche come mantenerne uno. Ciò consiste nell'accettare ed applicare le patch generate usando il comando `format-patch` e ricevute tramite e-mail oppure nell'integrare cambiamenti in rami dei repository che hai impostato come remote del tuo progetto. Sia che tu mantenga un repository o che tu voglia contribuire nel verificare le patch, devi sapere come eseguire il tuo compito in maniera chiara per gli altri contributori del progetto e sostenibile per te nel lungo periodo. +Oltre a sapere come contribuire ad un progetto in maniera effettiva, dovrai probabilmente sapere anche come mantenerne uno. Ciò consiste nell'accettare ed applicare le patch generate con il comando `format-patch` e ricevute tramite e-mail oppure nell'integrare le modifiche dei branch remoti che hai definito nel tuo progetto come remoti. Sia che mantenga un repository o che voglia contribuire verificando o approvando le patch, devi sapere come svolgere il tuo compito in modo che sia chiaro per gli altri contributori del progetto e sostenibile per te nel lungo periodo. ### Lavorare sui Topic Branches ### From 5e44433921c2e95fe0cd8b8f142477bb2c405f28 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 16:57:19 -0600 Subject: [PATCH 173/690] Reviewed "Working in Topic Branches" --- it/05-distributed-git/01-chapter5.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 4f004224f..bf2e1c11e 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -569,17 +569,17 @@ Questa sezione ha trattato alcuni workflow comuni che è facile incontrare quand Oltre a sapere come contribuire ad un progetto in maniera effettiva, dovrai probabilmente sapere anche come mantenerne uno. Ciò consiste nell'accettare ed applicare le patch generate con il comando `format-patch` e ricevute tramite e-mail oppure nell'integrare le modifiche dei branch remoti che hai definito nel tuo progetto come remoti. Sia che mantenga un repository o che voglia contribuire verificando o approvando le patch, devi sapere come svolgere il tuo compito in modo che sia chiaro per gli altri contributori del progetto e sostenibile per te nel lungo periodo. -### Lavorare sui Topic Branches ### +### Lavorare coi branch per argomento ### -Quando pensi di integrare un nuovo lavoro, è generalmente una buona idea quella di provarlo in un "topic branch", ovvero un ramo temporaneo creato specificatamente per provare le modifiche introdotte dalla patch. In questo modo è semplice modificare la singola patch e, se questa non funziona, lasciarla intalterata fino a quando non avrai il tempo di tornarci nuovamente. Se crei un ramo con un nome semplice basato sull'argomento della patch, ad esempio `ruby_client`, ti sarà poi facile individuarlo nel caso tu debba lasciare temporaneamente il lavoro sulla patch per tornarci più avanti. Il mantenitore del progetto Git usa dare uno spazio dei nomi a questi rami, come ad esempio `sc/ruby_client`, dove `sc` sono le iniziali della persona che ha contribuito al lavoro. Come ricorderai, puoi creare un ramo partendo dal tuo ramo master con questi comandi: +Quando pensi di integrare un nuovo lavoro generalmente è una buona idea provarlo in un branch per argomento: un branch temporaneo, creato specificatamente per provare le modifiche dalla patch. In questo modo è semplice verificare la singola patch e, se questa non funziona, lasciarla intalterata fino a quando non avrai il tempo di ritornarci. Se crei un branch col nome dell'argomento della patch che proverai, per esempio `ruby_client` o qualcosa ugualmente descrittiva, ti sarà facile individuarlo nel caso tu debba temporaneamente lasciare il lavoro sulla patch per ritornarci più avanti. Il mantenitore del progetto Git usa dare uno gerarchia ai nomi di questi branch: come `sc/ruby_client`, dove `sc` sono le iniziali della persona che ha realizzato la patch. Come ricorderai, puoi creare un branch partendo dal tuo master così: $ git branch sc/ruby_client master -Oppure, se vuoi anche passare al nuovo ramo immediatamente, puoi usare il comando `checkout -b`: +E, se vuoi passare immediatamente al nuovo branch, puoi usare il comando `checkout -b`: $ git checkout -b sc/ruby_client master -Ora sei pronto per aggiungere il lavoro a questo ramo e determinare se vuoi unirlo a uno dei rami del tuo progetto. +Ora sei pronto per aggiungere il lavoro a questo branch e decidere se vuoi unirlo a uno dei branch principali del tuo progetto. ### Applicare le patch da un'e-mail ### From 5eaab104fff752b0728bc8f96342b1699e3e2a54 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 17:00:11 -0600 Subject: [PATCH 174/690] Reviewed "Applying Patches from E-mail" --- it/05-distributed-git/01-chapter5.markdown | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index bf2e1c11e..6b8335f8f 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -571,7 +571,8 @@ Oltre a sapere come contribuire ad un progetto in maniera effettiva, dovrai prob ### Lavorare coi branch per argomento ### -Quando pensi di integrare un nuovo lavoro generalmente è una buona idea provarlo in un branch per argomento: un branch temporaneo, creato specificatamente per provare le modifiche dalla patch. In questo modo è semplice verificare la singola patch e, se questa non funziona, lasciarla intalterata fino a quando non avrai il tempo di ritornarci. Se crei un branch col nome dell'argomento della patch che proverai, per esempio `ruby_client` o qualcosa ugualmente descrittiva, ti sarà facile individuarlo nel caso tu debba temporaneamente lasciare il lavoro sulla patch per ritornarci più avanti. Il mantenitore del progetto Git usa dare uno gerarchia ai nomi di questi branch: come `sc/ruby_client`, dove `sc` sono le iniziali della persona che ha realizzato la patch. Come ricorderai, puoi creare un branch partendo dal tuo master così: +Quando pensi di integrare un nuovo lavoro generalmente è una buona idea provarlo in un branch per argomento: un branch temporaneo, creato specificatamente per provare le modifiche dalla patch. In questo modo è semplice verificare la singola patch e, se questa non funziona, lasciarla intalterata fino a quando non avrai il tempo di ritornarci. Se crei un branch col nome dell'argomento della patch che proverai, per esempio `ruby_client` o qualcosa ugualmente descrittiva, ti sarà facile individuarlo nel caso tu debba temporaneamente lasciare il lavoro sulla patch per ritornarci più avanti. Il mantenitore del progetto Git usa dare uno gerarchia ai nomi di questi branch: come `sc/ruby_client`, dove `sc` sono le iniziali della persona che ha realizzato la patch. +Come ricorderai, puoi creare un branch partendo dal tuo master così: $ git branch sc/ruby_client master @@ -583,7 +584,7 @@ Ora sei pronto per aggiungere il lavoro a questo branch e decidere se vuoi unirl ### Applicare le patch da un'e-mail ### -Se ricevi via e-mail le patch che vuoi integrare nel tuo progetto, devi applicarle ognuna al relativo `topic branch` per poterle provare. Ci sono due modi per applicare una patch ricevuta via email: con `git apply` oppure con `git am`. +Se ricevi le patch via e-mail e le vuoi integrarle nel tuo progetto, devi prima applicarle per poterle giudicare. Ci sono due modi per applicare una patch ricevuta via email: con `git apply` o con `git am`. #### Applicare una patch con apply #### From f3a4e29190524b74ee6d8cb58577e42b1b2edff5 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 17:07:50 -0600 Subject: [PATCH 175/690] Reviewed "Applying a Patch with apply" --- it/05-distributed-git/01-chapter5.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 6b8335f8f..31b1c5ff9 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -588,19 +588,19 @@ Se ricevi le patch via e-mail e le vuoi integrarle nel tuo progetto, devi prima #### Applicare una patch con apply #### -Se hai ricevuto la patch da qualcuno che l'ha generata usando il comando `git diff` o un qualsiasi comando Unix `diff`, puoi applicarla usando `git apply`. Se per esempio la patch è stata salvata in `/tmp/patch-ruby-client.patch`, puoi applicarla con il seguente comando: +Se hai ricevuto la patch da qualcuno che l'ha generata usando il comando `git diff` o un qualsiasi comando Unix `diff`, puoi applicarla usando `git apply`. Se hai salvato la patch in `/tmp/patch-ruby-client.patch`, puoi applicarla così: $ git apply /tmp/patch-ruby-client.patch -Ciò modifica i file nella tua directory corrente. E' quasi uguale ad eseguire il comando `patch -p1` per applicare la patch, anche se questo comando è più paranoico e accetta meno corrispondenze di patch. Esso gestisce anche l'aggiunta, la rimozione e il cambio del nome dei file se ciò è descritto nel formato di `git diff`, cosa che il comando `patch` non fa. Infine, `git apply` segue il modello "applica tutto o rigetta tutto" dove vengono applicato tutte le modifiche oppure nessuna, mentre `patch` può applicarle anche solo parzialmente, lasciando la tua directory corrente in uno stato intermedio. `git apply` è in generale più paranoico di `patch`. Non creerà un commit per te: una volta eseguito, devi effettuare lo stage e il commit dei file manualmente. +Ciò modifica i file nella tua directory corrente. E' quasi uguale ad eseguire il comando `patch -p1` per applicare la patch, anche se questo comando è più paranoico e accetta meno corrispondenze di patch. Gstisce anche l'aggiunta, la rimozione e il cambio del nome dei file se ciò è descritto nel formato di `git diff`, cose che non fa `patch`. Infine `git apply` segue il modello "applica tutto o rigetta tutto" per cui o vengono applicato tutte le modifiche oppure nessuna, mentre `patch` può anche applicarne solo alcune, lasciando la tua directory corrente in uno stato intermedio. `git apply` è in generale molto più paranoico di `patch`. Non creerà una commit per te: una volta eseguito devi eseguire manualmente lo stage delle modifiche e farne la commit. -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: +Puoi anche usare `git apply` per verificare se una patch può essere applicata in maniera pulita, prima di applicarla veramente eseguendo `git apply --check` sulla 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 -Se non viene visualizzato alcun output, allora la patch può essere applicata in maniera pulita. Questo comando termina con un valore diverso da zero se il controllo fallisce, quindi puoi usarlo anche all'interno di uno script. +Se non viene visualizzato alcun output, allora la patch può essere applicata in maniera pulita. Questo comando restituisce un valore diverso da zero se la verifica fallisce, quindi puoi usarlo anche in uno script. #### Applicare una patch con am #### From fe57416ccde30dd8503879c6f8f53376fe43b528 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 17:44:40 -0600 Subject: [PATCH 176/690] Reviewing "Applying a Patch with am" 100% reviewed existing translation --- it/05-distributed-git/01-chapter5.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 31b1c5ff9..e0ca7b48d 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -604,9 +604,9 @@ Se non viene visualizzato alcun output, allora la patch può essere applicata in #### Applicare una patch con am #### -Se il contributore è un utente Git ed è stato abbastanza bravo a usare il comando `format-patch` per generare la sua patch, allora il tuo lavoro è più facile perché la patch contiene le informazioni sull'autore e un messaggio di commit per te. Se ti è possibile incoraggia i tuoi collaboratori ad utilizzare `format-patch` invece di `diff` per generare le patch per te. Dovresti dover usare solo `git apply` per le patch precedenti e altre cose del genere. +Se il contributore è un utente Git ed è stato abbastanza bravo a usare il comando `format-patch` per generare la sua patch, allora il tuo lavoro sarà più facile perché la patch già contiene le informazioni sull'autore e un messaggio di commit. Se pouoi, per generare le patch per te, incoraggia i tuoi collaboratori ad utilizzare `format-patch` invece di `diff`. Dovresti dover usare solo `git apply` per le patch precedenti e altre cose del genere. -Per applicare una patch generata con `format-patch` si usa `git am`. Tecnicamente `git am` è fatto per leggere un file mbox, che ha un formato semplice di solo testo per memorizzare uno o più messaggi email in un solo file che assomiglia a questo: +Per applicare una patch generata con `format-patch`, userai `git am`. Tecnicamente `git am` è fatto per leggere un file mbox, che è un file piatto di puro testo per memorizzare uno o più messaggi email in un solo file. Assomiglia a questo: From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith @@ -615,14 +615,14 @@ Per applicare una patch generata con `format-patch` si usa `git am`. Tecnicament Limit log functionality to the first 20 -Questo è l'inizio dell'output del comando 'format-patch' che hai visto nella sezione precedente, ed è anche un formato valido per mbox. Se qualcuno ti ha inviato la patch usando 'git send-email' e l'hai scaricata nel formato mbox, allora puoi puntare al file mbox da 'git am' e lui inizierà ad applicare tutte le patch che troa. Se hai un client di posta elettronica che ti permette di salvare più messaggi in un file mbox allora puoi salvare tutta una serie di patch in un singolo file e usare `git am` per applicarle tutte assieme. +Questo è l'inizio dell'output del comando 'format-patch' che hai visto nella sezione precedente, ma è anche un formato valido per mbox per le email. Se qualcuno ti ha inviato la patch usando 'git send-email' e l'hai scaricata nel formato mbox, allora puoi selezionare il file mbox in 'git am' che inizierà ad applicare tutte le patch che trovi. Se hai un client di posta elettronica che ti permette di salvare più messaggi in un file mbox allora puoi salvare tutta una serie di patch in un singolo file e usare `git am` per applicarle tutte assieme. -Se però qualcuno ha caricato su un sistema di ticket (o qualcosa di simile) una patch generata con `format-patch`, tu puoi salvare il file localmente e passarlo a `git am` perché lo applichi: +Se invece qualcuno ha caricato una patch generata con `format-patch` su un sistema di ticket e tracciamento, puoi salvare localmente il file e passarlo a `git am` perché lo applichi: $ git am 0001-limit-log-function.patch Applying: add limit to log function -Puoi vedere che ha applicato automaticamente e senza errori le modifiche e creato una commit per te. Le informazioni sull'autore e la data della commit vengono prese delle intestazioni dell'email (rispettivamente da `From` e `Date`), mentre il messaggio della commit è preso dal `Subject` e dal corpo dell'email, prima della patch. Se, per esempio questa patch fosse stata applicata dall'esempio dell'mbox appena mostrato, la commit generata apparirebbe così: +Puoi vedere che ha applicato senza errori le modifiche e ha creato automaticamente una nuova commit per te. Le informazioni sull'autore e la data della commit vengono prese delle intestazioni `From` e `Date` dell'email, mentre il messaggio della commit è preso dal `Subject` e dal corpo dell'email che precede la patch. Se questa patch fosse stata applicata dall'esempio dell'mbox appena mostrato, la commit generata apparirebbe così: $ git log --pretty=fuller -1 commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 From 2d9194f47e06d56b0bd48893185072239b92fd5d Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 18:07:33 -0600 Subject: [PATCH 177/690] Translating "Applying a Patch with am" --- it/05-distributed-git/01-chapter5.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index e0ca7b48d..1dbe6ca3f 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -635,9 +635,9 @@ Puoi vedere che ha applicato senza errori le modifiche e ha creato automaticamen 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. +`Commit` indica chi ha applicato la patch e `CommitDate` quando. `Author` chi ha creato la patch originariamente e quando. -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: +Ma è possibile che la patch non sia applicabile correttamente. Il tuo branch principale potrebbe essere cambiato troppo rispetto al branch da cui deriva la patch o che la patch dipenda da altre che non hai ancora applicato. In questo caso il processo di `git am` fallirà e ti chiederà cosa voglia fareprocess 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 From 6f645b60eca503e48eb4e71c760141aded86593d Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 18:21:47 -0600 Subject: [PATCH 178/690] Translated "Applying a Patch with am" --- it/05-distributed-git/01-chapter5.markdown | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 1dbe6ca3f..5d8ff1c17 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -648,14 +648,14 @@ Ma è possibile che la patch non sia applicabile correttamente. Il tuo branch pr 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: +Questo comando aggiunge dei marcatori di conflicco in ciascun file che presenti un problema, similmente a quanto avviene nelle operazioni di merge o rebase. E tu risolverai il problema allo stesso modo: modifica il file per risolvere il conflitto, mettilo nello stage ed esegui `git am --resolved` per continuare con la patch successiva: $ (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: +Se vuoi che Git provi a risolvere i conflitti più intelligentemente, puoi passargli l'opzione `-3`, e Git proverà a eseguire un merge a 3-vie. Quest'opzione non è attiva di default perché non funziona se la patch si basa su una commit che non hai nel tuo repository. Se invece hai quella commit (ovvero se la patch è basata su una commit pubblica) allora generalmente l'opzione `-3` è più intelligente nell'applicare una patch con conflitti: $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem @@ -665,9 +665,9 @@ If you want Git to try a bit more intelligently to resolve the conflict, you can 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. +In questo caso sto cercando di applicare una patch che ho già applicato. Senza l'opzione `-3` sembrerebbe che ci sia un conflitto. -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: +Se stai applicando una serie di patch da un file mbox puoi eseguire il comando `am` anche in modalità interattiva, che si ferma ogni volta che incontra una patch per chiederti se vuoi applicarla: $ git am -3 -i mbox Commit Body is: @@ -676,9 +676,9 @@ If you’re applying a number of patches from an mbox, you can also run the `am` -------------------------- 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. +Questo è utile se hai una serie di patch salvate, perché se non ti ricordi cosa sia puoi rivedere la patch, o non applicarla se l'hai già applicata. -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. +Quando tutte la patch per l'orgomento sono state applicate e committate nel tuo branch, puoi decidere se e come integrarle in un branch principale. ### Checking Out Remote Branches ### From 166150105afaadc590b3b7d681fae2ce21662fd1 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 18:31:34 -0600 Subject: [PATCH 179/690] Translating "Checking Out Remote Branches" --- it/05-distributed-git/01-chapter5.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 5d8ff1c17..65dec88b3 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -680,19 +680,19 @@ Questo è utile se hai una serie di patch salvate, perché se non ti ricordi cos Quando tutte la patch per l'orgomento sono state applicate e committate nel tuo branch, puoi decidere se e come integrarle in un branch principale. -### Checking Out Remote Branches ### +### Scaricare branch remoti ### -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. +Se la contribuzione viene da un utente Git che ha un proprio repository su cui ha pubblicato una serie di modifiche e ti ha mandato l'indirizzo del repository e il nome del branch remoto in cui sono le stesse, puoi aggiungerlo come remoto e unirle localmente. -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: +Se, per esempio, Jessica ti invia un'email dicendoti che nel branch `ruby-client` del suo repository ha sviluppato un'interessante funzionalità, tu puoi testarla aggiungendo il branch remoto e scaricarlo come uno localmente: $ 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. +Se successivamente t'invia un'altra email con un altro branch che contenga un'altra funzionalità interessante tu puoi scaricarla più velocemente perché hai già configurato il repository remoto. -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. +Questa configurazione è molto utile se lavori molto con una persona. Se qualcuno produce una sola patch di tanto in tanto può essere più rapido accettarle per email, invece di chiedere a tutti di avere un proprio server pubblico e aggiungere in continuazione dei repository remoti per poche modifiche. Allo stesso tempo non vorrai centinaia di repository remoti per qualcuno che contribuisce solo con una patch o due. In ogni caso degli script o servizi di hostin possono rendere il tutto più semplice e principalmente dipende da come sviluppate tu e i tuoi contributori. 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. From db040e1d249065ad6b9301a1611664e8875d7fab Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 18:36:13 -0600 Subject: [PATCH 180/690] Translated "Checking Out Remote Branches" --- it/05-distributed-git/01-chapter5.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 65dec88b3..08b42cb2c 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -694,9 +694,9 @@ Se successivamente t'invia un'altra email con un altro branch che contenga un'al Questa configurazione è molto utile se lavori molto con una persona. Se qualcuno produce una sola patch di tanto in tanto può essere più rapido accettarle per email, invece di chiedere a tutti di avere un proprio server pubblico e aggiungere in continuazione dei repository remoti per poche modifiche. Allo stesso tempo non vorrai centinaia di repository remoti per qualcuno che contribuisce solo con una patch o due. In ogni caso degli script o servizi di hostin possono rendere il tutto più semplice e principalmente dipende da come sviluppate tu e i tuoi contributori. -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. +L'altro vantaggio di questo approccio è che in aggiunta ricevi la cronologia delle commit. Sebbene tu possa avere problemi coi merge saprai su quale parte della tua cronologia si basi il lavoro dei contributori, il merge a 3-vie è il default e non richiede di specificare l'opzione `-3` e la patch potrebbe essere generata da una commit pubblica a cui tu abbia accesso. -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: +Se non lavori spesso con una persona ma vuoi comunque prendere le modifiche in questo modo puoi sempre passare l'URL del repository remoto al comando `git pull`. Questo farà una pull una tantum senza salvare l'URL come un riferimento remoto: $ git pull git://github.com/onetimeguy/project.git From git://github.com/onetimeguy/project From df1dfb053ecf326e35be0b3ae93cb17e88cc9ee7 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 18:57:56 -0600 Subject: [PATCH 181/690] Translating "Determining What Is Introduced" --- it/05-distributed-git/01-chapter5.markdown | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 08b42cb2c..22daae6e7 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -703,11 +703,11 @@ Se non lavori spesso con una persona ma vuoi comunque prendere le modifiche in q * branch HEAD -> FETCH_HEAD Merge made by recursive. -### Determining What Is Introduced ### +### Determinare cos'è stato introdotto ### -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. +Hai un branch che contiene il lavoro di un contributore. A questo punto puoi decidere cosa farne. Questa sezione rivisita un paio di comandi così che tu possa vedere come usarli per revisionare con precisione cosa introdurrai se unissi queste modifiche al tuo branch principale. -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: +Spesso è utile revisionare le commit del branch che non sono ancora nel tuo master. Puoi escludere le commit di un branch aggiungendo l'opzione `--not` prima del nome del branch. Se un tuo contributore ti manda due patch e tu crei un branch chiamato `contrib` dove applichi le patch, puoi eseguire: $ git log contrib --not master commit 5b6235bd297351589efc4d73316f0a68d484f118 @@ -722,17 +722,17 @@ It’s often helpful to get a review of all the commits that are in this branch 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. +Ricorda che puoi passare l'opzione `-p` a `git log` per vedere le modifiche di ciascuna commit, così che all'output aggiungerà le differenze introdotte da ciascuna 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: +Per vedere tutte le differenze che verrebbero applicate se unissi il branch attuale con un altro dovrai usare un trucchetto per vedere il risultato corretto. Potresti pensare di usare: $ 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. +Ed effettivamente questo comando esegue una differenza, ma può essere causa di errori. Se il tuo branch `master` si fosse spostato in avanti rispetto a quando hai creato il branch vedrai risultati strani. Questo succede perché Git confronta direttamente l'istantanea ('snapshots') dell'ultima commit del branch con l'istantanea dell'ultima commit di `master`. Se, per esempio, hai aggiunto una riga in un file su `master` branch, un confronto diretto delle istantanee sembrerà indicare che il branch rimuova quella riga. -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. +Se `master` è un antenato diretto del branch allora non sarà un problema, ma se le due cronologie si sono biforcate ti apparirà che stai aggiungendo tutte le cose nuove del tuo branch e rimuovendo tutto ciò che è solo in `master`. -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. +Quello che vuoi realmente vedere sono le modifiche aggiunte nel branch: il lavoro che effettivamente introdurrai se le unissi al master. Potrai ottenerlo facendo si che Git confronti l'ultima commit del branch col primo antenato comune con il branch master. Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it: From d53299c9c2affb0cdd521f612ee39ece2cc3a8ba Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 19:06:21 -0600 Subject: [PATCH 182/690] Translated "Determining What Is Introduced" --- it/05-distributed-git/01-chapter5.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 22daae6e7..681e85183 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -734,17 +734,17 @@ Se `master` è un antenato diretto del branch allora non sarà un problema, ma s Quello che vuoi realmente vedere sono le modifiche aggiunte nel branch: il lavoro che effettivamente introdurrai se le unissi al master. Potrai ottenerlo facendo si che Git confronti l'ultima commit del branch col primo antenato comune con il branch master. -Technically, you can do that by explicitly figuring out the common ancestor and then running your diff on it: +Tecnicamente puoi farlo tu scoprendo l'antenato comune ed eseguendo quindi la diff: $ 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: +Questo però è scomodo e Git fornisce un modo più veloce per farlo: i tre punti. Nel contesto del comando `diff`, puoi usare tre punti dopo il nome di un branch per eseguire una `diff` tra l'ultima commit del branch in cui sei e l'antenato comune con un altro 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. +Questo comando ti mostra solo le modifiche introdotte dal branch attuale a partire dall'antenato comune con master. Questa sintassi è molto utile da ricordare. ### Integrating Contributed Work ### From d4ba71becb8dd543518866dd4028bde8323d77f3 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 19:10:03 -0600 Subject: [PATCH 183/690] Translated "Integrating Contributed Work" --- it/05-distributed-git/01-chapter5.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 681e85183..7ff3b27a9 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -746,9 +746,9 @@ Questo però è scomodo e Git fornisce un modo più veloce per farlo: i tre punt Questo comando ti mostra solo le modifiche introdotte dal branch attuale a partire dall'antenato comune con master. Questa sintassi è molto utile da ricordare. -### Integrating Contributed Work ### +### Integrare il lavoro dei contributori ### -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. +Quando tutto il lavoro del tuo branch è pronto per essere integrato in un branch principale nasce il prblema di come farlo. Inoltre, quale workflow vuoi usare per mantenere il tuo progetto? Hai una serie di scelte e ne tratterò alcune. #### Merging Workflows #### From 1152a4fe85972db2f206dfb5d15fc52a0daf76de Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 19:28:30 -0600 Subject: [PATCH 184/690] Translating "Merging Workflows" --- it/05-distributed-git/01-chapter5.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 7ff3b27a9..c252105c9 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -750,17 +750,17 @@ Questo comando ti mostra solo le modifiche introdotte dal branch attuale a parti Quando tutto il lavoro del tuo branch è pronto per essere integrato in un branch principale nasce il prblema di come farlo. Inoltre, quale workflow vuoi usare per mantenere il tuo progetto? Hai una serie di scelte e ne tratterò alcune. -#### Merging Workflows #### +#### I workflow per il merge #### -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. +Un workflow semplice unisce le modifiche nel branch `master`. In questo scenario hai un `master` che contiene del codice stabile. Quando hai del lavoro in un branch secondario che sia tuo o di un contributore e di cui tu abbia già verificato il buon funzionamento, lo unisci al master, cancelli il branch e così via. Se abbiamo un repository che abbia delle modifiche in due branch chiamati `ruby_client` e `php_client` questo apparirà come in Figura 5-19 e se unissimo prima `ruby_client` e poi `php_client` allora la nostra cronologia apparirà come quella in Figura 5-20. Insert 18333fig0519.png -Figure 5-19. History with several topic branches. +Figure 5-19. Cronologia con branch multipli. Insert 18333fig0520.png -Figure 5-20. After a topic branch merge. +Figure 5-20. Dopo l'unione dei branch. -That is probably the simplest workflow, but it’s problematic if you’re dealing with larger repositories or projects. +Probabilmente questo è il workflow più semplice, ma è anche problematico se stai lavorando con repository o progetti grandi. 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). From f8bdcf5c9d586d5f77522aa6873d2874971be54a Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 19:38:14 -0600 Subject: [PATCH 185/690] Transled "Merging Workflows" --- it/05-distributed-git/01-chapter5.markdown | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index c252105c9..4c62c8575 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -762,19 +762,19 @@ Figure 5-20. Dopo l'unione dei branch. Probabilmente questo è il workflow più semplice, ma è anche problematico se stai lavorando con repository o progetti grandi. -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). +Se hai più sviluppatori o lavori in un progetto grande, probabilmente vorrai usare un ciclo d'unione a due fasi. In questo scenario hai due branch principali, `master` e `develop`, e hai deciso che `master` viene aggiornato esclusivamente con un rilascio molto stabile e tutto il codice nuovo viene integrato nel branch `develop`. Condividi regolarmente entrambi i branch su un repository pubblico e ogni volta che hai un nuovo branch da integrare (Figura 5-21) lo fai in `develop` (Figura 5-22), quindi taggi il rilascio e fai un `fast-forward` di `master` al punto in cui `develop` è stabile (Figura 5-23). Insert 18333fig0521.png -Figure 5-21. Before a topic branch merge. +Figure 5-21. Prima dell'unione del branch. Insert 18333fig0522.png -Figure 5-22. After a topic branch merge. +Figure 5-22. Dopo l'unione del branch. Insert 18333fig0523.png -Figure 5-23. After a topic branch release. +Figure 5-23. Dopo il rilascio di un branch. -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. +In questo modo quando qualcuno clona il repository del tuo progetto, questi può scaricare il master per avere l'ultima versione stabile e tenersi aggiornato, o scaricare la versione di sviluppo che contiene le ultime cose. +Puoi estendere questo concetto avendo un branch in cui integri tutto il nuovo lavoro. Quando il codice di questo branch è stabile e ha passato tutti i test lo unisci al branch di sviluppo e quando questo ha dimostrato di essere stabile per un po', fai un `fast-forward` del tuo master. #### Large-Merging Workflows #### From 098b6d7b96e3395c0c493fb162c42237eecc1eb2 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 19:40:09 -0600 Subject: [PATCH 186/690] Translated all "Figure" --- it/05-distributed-git/01-chapter5.markdown | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 4c62c8575..619c5540e 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -755,38 +755,38 @@ Quando tutto il lavoro del tuo branch è pronto per essere integrato in un branc Un workflow semplice unisce le modifiche nel branch `master`. In questo scenario hai un `master` che contiene del codice stabile. Quando hai del lavoro in un branch secondario che sia tuo o di un contributore e di cui tu abbia già verificato il buon funzionamento, lo unisci al master, cancelli il branch e così via. Se abbiamo un repository che abbia delle modifiche in due branch chiamati `ruby_client` e `php_client` questo apparirà come in Figura 5-19 e se unissimo prima `ruby_client` e poi `php_client` allora la nostra cronologia apparirà come quella in Figura 5-20. Insert 18333fig0519.png -Figure 5-19. Cronologia con branch multipli. +Figura 5-19. Cronologia con branch multipli. Insert 18333fig0520.png -Figure 5-20. Dopo l'unione dei branch. +Figura 5-20. Dopo l'unione dei branch. Probabilmente questo è il workflow più semplice, ma è anche problematico se stai lavorando con repository o progetti grandi. Se hai più sviluppatori o lavori in un progetto grande, probabilmente vorrai usare un ciclo d'unione a due fasi. In questo scenario hai due branch principali, `master` e `develop`, e hai deciso che `master` viene aggiornato esclusivamente con un rilascio molto stabile e tutto il codice nuovo viene integrato nel branch `develop`. Condividi regolarmente entrambi i branch su un repository pubblico e ogni volta che hai un nuovo branch da integrare (Figura 5-21) lo fai in `develop` (Figura 5-22), quindi taggi il rilascio e fai un `fast-forward` di `master` al punto in cui `develop` è stabile (Figura 5-23). Insert 18333fig0521.png -Figure 5-21. Prima dell'unione del branch. +Figura 5-21. Prima dell'unione del branch. Insert 18333fig0522.png -Figure 5-22. Dopo l'unione del branch. +Figura 5-22. Dopo l'unione del branch. Insert 18333fig0523.png -Figure 5-23. Dopo il rilascio di un branch. +Figura 5-23. Dopo il rilascio di un branch. In questo modo quando qualcuno clona il repository del tuo progetto, questi può scaricare il master per avere l'ultima versione stabile e tenersi aggiornato, o scaricare la versione di sviluppo che contiene le ultime cose. Puoi estendere questo concetto avendo un branch in cui integri tutto il nuovo lavoro. Quando il codice di questo branch è stabile e ha passato tutti i test lo unisci al branch di sviluppo e quando questo ha dimostrato di essere stabile per un po', fai un `fast-forward` del tuo master. #### 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. +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 Figura 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. +Figura 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). +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 Figura 5-25). Insert 18333fig0525.png -Figure 5-25. Merging contributed topic branches into long-term integration branches. +Figura 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. @@ -794,10 +794,10 @@ When a topic branch has finally been merged into `master`, it’s removed from t 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. +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 Figura 5-26. Insert 18333fig0526.png -Figure 5-26. Example history before a cherry pick. +Figura 5-26. Example history before a cherry pick. If you want to pull commit `e43a6` into your master branch, you can run @@ -806,10 +806,10 @@ If you want to pull commit `e43a6` into your master branch, you can run [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. +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 Figura 5-27. Insert 18333fig0527.png -Figure 5-27. History after cherry-picking a commit on a topic branch. +Figura 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. @@ -822,7 +822,7 @@ When you’ve decided to cut a release, you’ll probably want to drop a tag so 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`: +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 Figura out which key you want by running `gpg --list-keys`: $ gpg --list-keys /Users/schacon/.gnupg/pubring.gpg From 5db8b20df5ba2f9714de0c37cb9a02265dde2b9a Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 19:58:02 -0600 Subject: [PATCH 187/690] Translated "Large-Merging Workflows" --- it/05-distributed-git/01-chapter5.markdown | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 619c5540e..3d159afc8 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -752,43 +752,43 @@ Quando tutto il lavoro del tuo branch è pronto per essere integrato in un branc #### I workflow per il merge #### -Un workflow semplice unisce le modifiche nel branch `master`. In questo scenario hai un `master` che contiene del codice stabile. Quando hai del lavoro in un branch secondario che sia tuo o di un contributore e di cui tu abbia già verificato il buon funzionamento, lo unisci al master, cancelli il branch e così via. Se abbiamo un repository che abbia delle modifiche in due branch chiamati `ruby_client` e `php_client` questo apparirà come in Figura 5-19 e se unissimo prima `ruby_client` e poi `php_client` allora la nostra cronologia apparirà come quella in Figura 5-20. +Un workflow semplice unisce le modifiche nel branch `master`. In questo scenario hai un `master` che contiene del codice stabile. Quando hai del lavoro in un branch funzionale che sia tuo o di un contributore e di cui tu abbia già verificato il buon funzionamento, lo unisci al master, cancelli il branch e così via. Se abbiamo un repository che abbia delle modifiche in due branch funzionali chiamati `ruby_client` e `php_client` questo apparirà come in Figura 5-19 e se unissimo prima `ruby_client` e poi `php_client` allora la nostra cronologia apparirà come quella in Figura 5-20. Insert 18333fig0519.png -Figura 5-19. Cronologia con branch multipli. +Figura 5-19. Cronologia con branch funzionali multipli. Insert 18333fig0520.png -Figura 5-20. Dopo l'unione dei branch. +Figura 5-20. Dopo l'unione dei branch funzionali. Probabilmente questo è il workflow più semplice, ma è anche problematico se stai lavorando con repository o progetti grandi. -Se hai più sviluppatori o lavori in un progetto grande, probabilmente vorrai usare un ciclo d'unione a due fasi. In questo scenario hai due branch principali, `master` e `develop`, e hai deciso che `master` viene aggiornato esclusivamente con un rilascio molto stabile e tutto il codice nuovo viene integrato nel branch `develop`. Condividi regolarmente entrambi i branch su un repository pubblico e ogni volta che hai un nuovo branch da integrare (Figura 5-21) lo fai in `develop` (Figura 5-22), quindi taggi il rilascio e fai un `fast-forward` di `master` al punto in cui `develop` è stabile (Figura 5-23). +Se hai più sviluppatori o lavori in un progetto grande, probabilmente vorrai usare un ciclo d'unione a due fasi. In questo scenario hai due branch principali, `master` e `develop`, e hai deciso che `master` viene aggiornato esclusivamente con un rilascio molto stabile e tutto il codice nuovo viene integrato nel branch `develop`. Condividi regolarmente entrambi i branch su un repository pubblico e ogni volta che hai un nuovo branch funzionale da integrare (Figura 5-21) lo fai in `develop` (Figura 5-22), quindi taggi il rilascio e fai un `fast-forward` di `master` al punto in cui `develop` è stabile (Figura 5-23). Insert 18333fig0521.png -Figura 5-21. Prima dell'unione del branch. +Figura 5-21. Prima dell'unione del branch funzionale. Insert 18333fig0522.png -Figura 5-22. Dopo l'unione del branch. +Figura 5-22. Dopo l'unione del branch funzionale. Insert 18333fig0523.png -Figura 5-23. Dopo il rilascio di un branch. +Figura 5-23. Dopo il rilascio di un branch funzionale. In questo modo quando qualcuno clona il repository del tuo progetto, questi può scaricare il master per avere l'ultima versione stabile e tenersi aggiornato, o scaricare la versione di sviluppo che contiene le ultime cose. Puoi estendere questo concetto avendo un branch in cui integri tutto il nuovo lavoro. Quando il codice di questo branch è stabile e ha passato tutti i test lo unisci al branch di sviluppo e quando questo ha dimostrato di essere stabile per un po', fai un `fast-forward` del tuo master. -#### Large-Merging Workflows #### +#### Workflow per unioni grandi #### -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 Figura 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. +Il progetto Git ha quattro branch principali: `master`, `next`, e `pu` (aggiornamenti suggeriti - `proposed updates`) per il nuovo lavoro, e `maint` per la manutenzione dei backport. Quando un contributore introduce una modifica, questa viene raccolta nei branch funzionali del repository del mantenitore in modo simile a quanto ho già descritto (vedi Figura 5-24). A questo punto le modifiche vengono valutate per deteminare se sono sicure e pronte per essere utilizzate o se hanno bisogno di ulteriore lavoro. Se sono sicure vengono unite in `next` e questo branch viene condiviso perché chiunque possa provarle tutte assieme. Insert 18333fig0524.png -Figura 5-24. Managing a complex series of parallel contributed topic branches. +Figura 5-24. Gestire una serie complessa di branch funzionali paralleli. -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 Figura 5-25). +Se la funzione ha bisogno di ulteriori modifiche viene unita invece in `pu` e quando viene ritenuta realmente stabile viene unita di nuovo su `master` e viene ricostruita dal codice che era in `next`, ma non è ancora promossa su `master`. Questo significa che `master` va quasi sempre avanti, `next` raramente è ribasato e `pu` viene ribasato molto spesso (see Figura 5-25). Insert 18333fig0525.png -Figura 5-25. Merging contributed topic branches into long-term integration branches. +Figura 5-25. Unire branch di contribuzione nei branch principali. -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. +Quando un branch funzionale viene finalmente unito in `master` viene anche rimosso dal repository. Il progetto Git ha anche un branch `maint` che è un fork dell'ultima release per fornire patch a versioni precedenti nel caso sia necessaria un rilascio di manutenzione. Quindi, quando cloni il repository di Git puoi usare quattro branch per valutare il progetto in stadi diversi dello sviluppo, a seconda che tu voglia le ultime funzionalità o voglia contribuire, e il mantenitore ha strutturato il workflow in modo da favorire nuove contribuzioni. #### Rebasing and Cherry Picking Workflows #### From 45a1c5bf9a6da23d7f7ae9c747c8be123c497ce6 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 20:07:22 -0600 Subject: [PATCH 188/690] Translating "Rebasing and Cherry Picking Workflows" --- it/05-distributed-git/01-chapter5.markdown | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 3d159afc8..36f94446d 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -40,7 +40,7 @@ Questo è un workflow comune con siti come GitHub, dove è facile eseguire un fo Questa è una variante del workflow con repository multipli. Viene generalmente usata da grandi progetti con centinaia di collaboratori: un esempio famoso è il Kernel Linux. Molti manager d'integrazione sono responsabili di certe parti del repository e vengono chiamati tenenti. Tutti i tenenti hanno un manager d'integrazione conosciuto come "dittatore benevolo". Il repository del dittatore benevolo è il repository di riferimento dal quale tutti i collaboratori prendono il codice. Il flusso di lavoro è il seguente (vedi Figura 5-3): -1. Sviluppatori normali lavorano sul loro branch ed eseguono un `rebase` del proprio lavoro sul master. Il branch master è quello del dittatore. +1. Sviluppatori normali lavorano sul loro branch ed eseguono un _rebase_ del proprio lavoro sul master. Il branch master è quello del dittatore. 2. I tenenti uniscono il lavoro degli sviluppatori nel proprio branch master. 3. Il dittatore esegue l'unione dei branch master dei tenenti nel proprio branch master. 4. Il dittatore esegue una push del proprio ramo master nel repository di riferimento, cosicché gli sviluppatori possano accedervi. @@ -774,7 +774,7 @@ Insert 18333fig0523.png Figura 5-23. Dopo il rilascio di un branch funzionale. In questo modo quando qualcuno clona il repository del tuo progetto, questi può scaricare il master per avere l'ultima versione stabile e tenersi aggiornato, o scaricare la versione di sviluppo che contiene le ultime cose. -Puoi estendere questo concetto avendo un branch in cui integri tutto il nuovo lavoro. Quando il codice di questo branch è stabile e ha passato tutti i test lo unisci al branch di sviluppo e quando questo ha dimostrato di essere stabile per un po', fai un `fast-forward` del tuo master. +Puoi estendere questo concetto avendo un branch in cui integri tutto il nuovo lavoro. Quando il codice di questo branch è stabile e ha passato tutti i test lo unisci al branch di sviluppo e quando questo ha dimostrato di essere stabile per un po', fai un _fast-forward_ del tuo master. #### Workflow per unioni grandi #### @@ -790,9 +790,9 @@ Figura 5-25. Unire branch di contribuzione nei branch principali. Quando un branch funzionale viene finalmente unito in `master` viene anche rimosso dal repository. Il progetto Git ha anche un branch `maint` che è un fork dell'ultima release per fornire patch a versioni precedenti nel caso sia necessaria un rilascio di manutenzione. Quindi, quando cloni il repository di Git puoi usare quattro branch per valutare il progetto in stadi diversi dello sviluppo, a seconda che tu voglia le ultime funzionalità o voglia contribuire, e il mantenitore ha strutturato il workflow in modo da favorire nuove contribuzioni. -#### Rebasing and Cherry Picking Workflows #### +#### Workflow per il rebase e lo _cherry pick_ #### -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. +Altri mantenitori preferiscono ribasare o usare lo _cherry-pick_ aggiungere i contributi nel loro branch master, piuttosto che unirli, per mantenere una cronologia il più lineare possibile. Quando hai delle modifiche in un branch funzionale e hai deciso che vuoi integrarle, ti sposti su quel branch ed esegui il comando _rebase_ per replicare le modifiche del tuo master attuale (o `develop` e così via). Se queste funzionano, allora fai un _fast-forward_ del tuo `master` e ti ritroverai con un progetto dalla cronologia lineare. 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 Figura 5-26. From fa1e6daa07cf859dc9068cf9a79ff4acaf19f939 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 20:13:48 -0600 Subject: [PATCH 189/690] Translated "Rebasing and Cherry Picking Workflows" --- it/05-distributed-git/01-chapter5.markdown | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 36f94446d..c69f91cb6 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -794,24 +794,24 @@ Quando un branch funzionale viene finalmente unito in `master` viene anche rimos Altri mantenitori preferiscono ribasare o usare lo _cherry-pick_ aggiungere i contributi nel loro branch master, piuttosto che unirli, per mantenere una cronologia il più lineare possibile. Quando hai delle modifiche in un branch funzionale e hai deciso che vuoi integrarle, ti sposti su quel branch ed esegui il comando _rebase_ per replicare le modifiche del tuo master attuale (o `develop` e così via). Se queste funzionano, allora fai un _fast-forward_ del tuo `master` e ti ritroverai con un progetto dalla cronologia lineare. -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 Figura 5-26. +L'altro modo per spostare il lavoro dei contributori da un branch all'altro è di usare lo _cherry-pick_. Lo _cherry-pick_ in Git è come una rebase per una commit singola. Prende la patch introdotta nella commit e prova a riapplicarla sul branch dove sei. Questo è utile se hai molte commit in un branch funzionale e vuoi integrarne solo alcune o se hai un'unica commit in un branch funzionale e preferisci usare lo `cherry-pick` piuttosto che ribasare. Immagina di avere un progetto che sembri quello di Figura 5-26. Insert 18333fig0526.png -Figura 5-26. Example history before a cherry pick. +Figura 5-26. Cronologia prima dello _cherry pick_. -If you want to pull commit `e43a6` into your master branch, you can run +Se vuoi introdurre la commit `e43a6` nel tuo master puoi eseguire $ 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 Figura 5-27. +Che replica le stesse modifiche introdotte in `e43a6`, ma produce una nuova commit con un suo SHA-1 differente perché le date sono diverse. La tua cronologia ora assomiglia a quella in Figura 5-27. Insert 18333fig0527.png -Figura 5-27. History after cherry-picking a commit on a topic branch. +Figura 5-27. Cronologia dopo lo _cherry-picking_ dal branch funzionale. -Now you can remove your topic branch and drop the commits you didn’t want to pull in. +Puoi ora eliminare il branch funzionale e cancellare le commit che non vuoi integrare. ### Tagging Your Releases ### From f8de5f5929aea6bc1e5b880af52bdeb8063d9754 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 20:26:16 -0600 Subject: [PATCH 190/690] Translated "Tagging Your Releases" --- it/05-distributed-git/01-chapter5.markdown | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index c69f91cb6..bf8ed6595 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -813,16 +813,16 @@ Figura 5-27. Cronologia dopo lo _cherry-picking_ dal branch funzionale. Puoi ora eliminare il branch funzionale e cancellare le commit che non vuoi integrare. -### Tagging Your Releases ### +### Tagga i tuoi rilasci ### -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: +Quando hai deciso di eseguire un rilascio probabilmente vorrai anche taggarla, così che tu possa ricrearla in qualsiasi momento nel futuro. Puoi aggiungere un nuovo tag come discusso nel Capitolo 2. Se vuoi firmare il tag in quanto mantenitore, il tag potrebbe apparire come il seguente: $ 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 Figura out which key you want by running `gpg --list-keys`: +Se firmi il tuo tag potresti avere il problema di distribuire la chiave PGP usata per firmarlo. Il mantenitore del progetto Git lo ha risolto includendo le chiavi dei mantenitori come un blob sul repository e aggiungendo quindi un tag che vi punti direttamente. Per farlo dovrai identificare la chiave che vuoi esportare eseguendo `gpg --list-keys`: $ gpg --list-keys /Users/schacon/.gnupg/pubring.gpg @@ -831,20 +831,20 @@ If you do sign your tags, you may have the problem of distributing the public PG 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: +Potrai quindi importare la chiave direttamente nel database di Git esportandola e mettendola in pipe con `git hash-object`, che scrive in Git un nuovo blob con il suo contenuto e ti restituisce l'hash SHA-1: $ 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: +Ora che hai importato il contenuto della tua chiave in Git puoi creare un tag che vi punti direttamente, specificando l'SHA-1 appena ottenuto: $ 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: +Se esegui `git push --tags` verrà condiviso con tutti il tag `maintainer-pgp-pub`. Se qualcuno volesse verificare il tag potrà farlo importando la tua chiave PGP scaricando il blob dal database e importandolo in 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. +Può quindi usare la chiave per verificare tutti i tag che hai firmato. Inoltre, se aggiungi delle istruzioni nel messaggio del tag, eseguendo `git show ` darai all'utente finale maggiori informazioni specifiche su come verificare il tag. ### Generating a Build Number ### From 5dd8e6b2b9cfe2d4f62499b3cc9ccc47cc036bb3 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 20:46:34 -0600 Subject: [PATCH 191/690] Translated "Preparing a Release" --- it/05-distributed-git/01-chapter5.markdown | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index bf8ed6595..15c992b42 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -846,30 +846,30 @@ Se esegui `git push --tags` verrà condiviso con tutti il tag `maintainer-pgp-pu Può quindi usare la chiave per verificare tutti i tag che hai firmato. Inoltre, se aggiungi delle istruzioni nel messaggio del tag, eseguendo `git show ` darai all'utente finale maggiori informazioni specifiche su come verificare il tag. -### Generating a Build Number ### +### Generare un numero di build ### -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: +Poiché Git non usa una numerazione incrementale come 'v123' o un equivalente associato a ciascuna commit, se vuoi un nome per una commit che sia intellegibile, puoi usare il comando `git describe` su quella commit. Git restituirà il nome del tag più vicino assieme al numero di commit successivi e una parte dell'SHA-1 della commit che vuoi descrivere: $ 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. +In questo modo puoi esportare un'istantanea o una build echiamarla in modo che le persone possano capire. Se infatti fai una build di Git dai sorgenti clonati dal repository di Git repository, `git --version` ti restituirà qualcosa che gli assomigli. Se vuoi descrivere una commit che hai taggato, Git ti darà il nome del tag. -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. +Il comando `git describe` predilige i tag annotati (i tags creati con`-a` o `-s`) e quindi i tag dei rilasci dovrebbero essere creati in questo modo se usi `git describe`, per assicurarsi che le commit vengano denominate correttamente quando vengono descritte. Puoi usare questa stringa per i comandi `checkout` o `show`, sebbene il basarsi sull'SHA-1 abbreviato potrebbe renderla non valida per sempre. Per esempio, recentemente il kernel di Linux è passato recentemente da 8 a 10 caratteri per garantire l'unicità degli SHA-1 abbreviati, e quindi gli output precedenti di `git describe` non sono più validi. -### Preparing a Release ### +### Pronti per il rilascio ### -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`: +Vuoi ora rilasciare una build. Una delle cose che vorrai fare sarà creare un archivio con l'ultima istantanea del tuo codice per quelle anime dannate che non usano Git. Il comando è `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`: +Quando qualcuno aprirà questo tarball, troverà l'ultima versione del tuo progetto nella directory `project`. Allo stesso modo puoi creare un archivio zip passando l'opzione `--format=zip` a `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. +Ora hai un tarball e uno zip del rilascio del tuo progetto che puoi caricare sul tuo sito o inviare per email. ### The Shortlog ### From 5e9e42a3388bbb797337ef1911c2999940e0a970 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 22:27:42 -0600 Subject: [PATCH 192/690] Translated "The Shortlog" --- it/05-distributed-git/01-chapter5.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index 15c992b42..e40f43d4b 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -871,9 +871,9 @@ Quando qualcuno aprirà questo tarball, troverà l'ultima versione del tuo prog Ora hai un tarball e uno zip del rilascio del tuo progetto che puoi caricare sul tuo sito o inviare per email. -### The Shortlog ### +### Lo 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: +È il momento di inviare un'email alla lista di persone che vogliono sapere cosa succede nel tuo progetto. Un modo piacevole per produrre una specie di changelog delle modifiche dall'ultimo rilascio o dall'ultima email è usando il comando `git shortlog`, che riassume tutte le commit nell'intervallo dato. L'esempio seguente produce il sommario di tutte le commit dall'ultimo rilascio, assumento che lo abbia chiamato v1.0.1: $ git shortlog --no-merges master --not v1.0.1 Chris Wanstrath (8): @@ -890,7 +890,7 @@ It’s time to e-mail your mailing list of people who want to know what’s happ 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. +Ottieni un sommario pulito di tutte le commit dalla v1.0.1, raggruppate per autore che puoi quindi inviare per email alla tua lista. ## Summary ## From 5e0dd343b39107e30779b597ab5cd531aa4dea73 Mon Sep 17 00:00:00 2001 From: Davide Fiorentino lo Regio Date: Mon, 3 Feb 2014 22:31:13 -0600 Subject: [PATCH 193/690] Complete translation of chapter 5 --- it/05-distributed-git/01-chapter5.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index e40f43d4b..adb3990f0 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -892,6 +892,6 @@ Ora hai un tarball e uno zip del rilascio del tuo progetto che puoi caricare sul Ottieni un sommario pulito di tutte le commit dalla v1.0.1, raggruppate per autore che puoi quindi inviare per email alla tua lista. -## Summary ## +## Sommario ## -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. +Dovresti sentirti ora a tuo agio nel contribuire a progetti Git, tanto quanto mantenere il tuo progetto o integrare i contributi di altri utenti. Congratulazione per essere un vero sviluppatore Git! Nel prossimo capitolo imparerai alcuni strumenti molto potenti e suggerimenti per affrontare situazione complesse che ti faranno diventare un maestro di Git. From a57637487ca01d898cba5bbac356226d86b2be43 Mon Sep 17 00:00:00 2001 From: cor Date: Tue, 4 Feb 2014 20:35:03 +0100 Subject: [PATCH 194/690] [nl] Retranslate chapter 06, clarify some of the sentences and remove Babelfishes. --- nl/06-git-tools/01-chapter6.markdown | 314 ++++++++++++++------------- 1 file changed, 165 insertions(+), 149 deletions(-) diff --git a/nl/06-git-tools/01-chapter6.markdown b/nl/06-git-tools/01-chapter6.markdown index e0e619490..9dbbf4cca 100644 --- a/nl/06-git-tools/01-chapter6.markdown +++ b/nl/06-git-tools/01-chapter6.markdown @@ -1,20 +1,20 @@ # Git tools # -Nu heb je de meeste commando's en werkwijzen geleerd die je dagelijks nodig hebt om een Git repository voor je broncode te beheren en te onderhouden. Je hebt de basistaken van het tracken en committen van bestanden uitgevoerd, en je hebt de kracht van de staging area en lichtgewicht topic branching en mergen in handen. +Nu heb je de meeste commando's en werkwijzen geleerd die je dagelijks nodig hebt om een Git repository voor je broncode te beheren en te onderhouden. Je hebt de basistaken van het tracken en committen van bestanden onder de knie, en je hebt de kracht van de staging area en lichtgewicht topic branching en mergen in de vingers. -Nu ga je een aantal zeer krachtige dingen verkennen die Git kan, die je niet per se dagelijks gebruikt, maar die je op een bepaald punt toch nodig kunt hebben. +Nu ga je een aantal zeer krachtige dingen verkennen die Git kan, die je niet per se dagelijks gebruikt, maar die je op een bepaald moment toch nodig kunt gaan hebben. ## Revisie selectie ## -Git staat je toe om specifieke commits of een serie commits op meerdere manieren te specificeren. Ze zijn niet per se voor de hand liggend, maar behulpzaam om te weten. +Git stelt je in staat om specifieke commits of een serie commits op diverse manieren te specificeren. Ze zijn niet per se voor de hand liggend, maar behulpzaam om te weten. ### Enkele revisies ### -Natuurlijk kun je naar een commit refereren door de SHA-1 hash die het toegekend is, maar er zijn ook meer mensvriendelijke manieren om naar een commit te refereren. Deze sectie laat de diverse manieren zien waarop je naar een enkele commit kunt refereren. +Natuurlijk kun je naar een commit refereren door de SHA-1 hash die het toegekend is, maar er zijn ook meer mensvriendelijke manieren om naar een commit te refereren. In deze paragraaf worden diverse manieren getoond waarop je naar een enkele commit kunt refereren. ### Korte SHA ### -Git is slim genoeg om uit te vinden welke commit je bedoelde te typen als je de eerste karakters opgeeft, zolang je gedeeltelijke SHA-1 minstens vier karakters lang en ondubbelzinnig is – dat wil zeggen dat slechts één object in de huidige repository begint met die gedeeltelijke SHA-1. +Git is slim genoeg om uit te vinden welke commit je bedoelde te typen als je het de eerste karakters geeft, zolang je gedeeltelijke SHA-1 minstens vier karakters lang en ondubbelzinnig is; dat wil zeggen dat slechts één object in de huidige repository begint met die gedeeltelijke SHA-1. Bijvoorbeeld, stel dat je om een specifieke commit te zien een `git log` commando uitvoert en de commit identificeert waarin je een bepaalde functionaliteit hebt toegevoegd: @@ -38,13 +38,13 @@ Bijvoorbeeld, stel dat je om een specifieke commit te zien een `git log` command added some blame and merge stuff -In dit geval, kies `1c002dd...`. Als je op die commit `git show` uitvoert, dan zijn de volgende commando's equivalent (aangenomen dat de kortere versies ondubbelzinnig zijn): +In dit geval, kiezen we `1c002dd....`. Als je op die commit `git show` uitvoert, dan zijn de volgende commando's gelijkwaardig (aangenomen dat de kortere versies ondubbelzinnig zijn): $ git show 1c002dd4b536e7479fe34593e72e6c6c1819e53b $ git show 1c002dd4b536e7479f $ git show 1c002d -Git kan een korte unieke afkorting voor je SHA-1 waardes uitvinden. Als je `--abbrev-commit` meegeeft aan het `git log` commando, dan zal de output kortere waarden gebruiken maar ze uniek houden; het gebruikt standaard zeven karakters, maar maakt ze langer om de SHA-1 ondubbelzinnig te houden: +Git kan met een korte unieke afkorting voor je SHA-1 waarde uit de voeten. Als je `--abbrev-commit` meegeeft aan het `git log` commando, dan zal de output kortere waarden gebruiken maar ze uniek houden; het gebruikt standaard zeven karakters maar maakt ze langer indien nodig om de SHA-1 ondubbelzinnig te houden: $ git log --abbrev-commit --pretty=oneline ca82a6d changed the version number @@ -53,15 +53,15 @@ Git kan een korte unieke afkorting voor je SHA-1 waardes uitvinden. Als je `--ab Over het algemeen zijn acht tot tien karakters meer dan voldoende om binnen een project uniek te zijn. Een van de grootste Git projecten, de Linux kernel, begint 12 karakters van de mogelijke 40 nodig te hebben om uniek te blijven. -### Een korte notitie over SHA-1 ### +### EEN KORTE NOTITIE OVER SHA-1 ### -Veel mensen zijn bezorgd geworden dat ze op een bepaald punt, door random toeval, twee objecten in hun repository hebben die naar dezelfde SHA-1 waarde hashen. Wat dan? +Veel mensen beginnen bezorgd te raken dat ze op een bepaald moment door puur toeval, twee objecten in hun repository hebben die naar dezelfde SHA-1 waarde hashen. Wat dan? -Mocht je een object committen dat hashed naar dezelfde SHA-1 waarde als een vorig object in je repository, dan zal Git het vorige reeds aanwezige object in je Git database zien en aannemen dat het al geschreven was. Als je dat object opnieuw probeert uit te checken op een bepaald punt, dan zul je altijd de gegevens van het eerste object krijgen. +Mocht je een object committen dat hashed naar dezelfde SHA-1 waarde als een vorig object in je repository, dan zal Git het vorige reeds aanwezige object in je Git database zien en aannemen dat het al geschreven was. Als je dat object opnieuw probeert uit te checken op een bepaald moment, dan zul je altijd de gegevens van het eerste object krijgen. -Maar, je moet je bewust zijn hoe belachelijk onwaarschijnlijk dit scenario is. De SHA-1 waarde is 20 bytes of 160 bits. Het aantal benodigde random gehashte objecten om een 50% waarschijnlijkheid van een enkele botsing te garanderen is ongeveer 2^80 (de formule om botsingswaarschijnlijkheid te bepalen is `p = (n(n-1)/2) * (1/2^160)`). 2^80 is 1.2 x 10^24 of 1 miljoen miljard miljard. Dat is 1.200 keer het aantal zandkorrels op de aarde. +Maar, je moet je bewust zijn hoe vreselijk onwaarschijnlijk dit scenario is. De SHA-1 waarde is 20 bytes, of 160 bits. Het aantal benodigde random gehashte objecten om een 50% waarschijnlijkheid van een botsing te garanderen is ongeveer 2^80 (de formule om botsingswaarschijnlijkheid te bepalen is `p = (n(n-1)/2) * (1/2^160)`). 2^80 is 1.2 x 10^24 of 1 miljoen miljard miljard. Dat is 1.200 keer het aantal zandkorrels op de aarde. -Hier is een voorbeeld om je een idee te geven wat er voor nodig is om een SHA-1 botsing te krijgen. Als alle 6.5 miljard mensen op aarde zouden gaan programmeren, en iedere seconde zou iedereen code genereren die gelijk was aan de hele Linux kernel-geschiedenis (1 miljoen Git objecten) en dat in één gigantische Git repository pushen, dan zou het vijf jaar duren voordat die repository genoeg objecten zou bevatten om een 50% waarschijnlijkheid van één enkele SHA-1 object botsing te krijgen. Er bestaat een grotere kans dat ieder lid van je programmeerteam zal worden aangevallen en worden gedood door wolven in ongerelateerde incidenten op dezelfde avond. +Hier is een voorbeeld om je een idee te geven wat er voor nodig is om een SHA-1 botsing te krijgen. Als alle 6.5 miljard mensen op aarde zouden programmeren, en iedere seconde zou ieder van hen code genereren die gelijk was aan de hele Linux kernel-geschiedenis (1 miljoen Git objecten) en dat in één gigantische Git repository pushen, dan zou het vijf jaar duren voordat die repository genoeg objecten zou bevatten om een 50% waarschijnlijkheid van één enkele SHA-1 object botsing te krijgen. Er bestaat een grotere kans dat elk lid van je programmeerteam zal worden aangevallen en gedood door wolven in ongerelateerde incidenten op dezelfde avond. ### Branch referenties ### @@ -70,14 +70,14 @@ De meest eenvoudige manier om een commit te specificeren heeft als voorwaarde da $ git show ca82a6dff817ec66f44342007202690a93763949 $ git show topic1 -Als je wil zien naar welke specifieke SHA een branch wijst, of als je wil zien wat ieder van deze voorbeelden in termen van SHA's voorstellen, dan kun je een Git onderwatertool genaamd `rev-parse` gebruiken. Je kunt in Hoofdstuk 9 kijken voor meer informatie over onderwatertools; eigenlijk bestaat `rev-parse` voor low-level operaties en is niet ontworpen om in dagelijkse operaties gebruikt te worden. Maar, het kan behulpzaam zijn op momenten dat je moet zien wat er echt aan de hand is. Hier kun je `rev-parse` uitvoeren op je branch. +Als je wil zien naar welke specifieke SHA een branch wijst, of als je wil zien wat ieder van deze voorbeelden in termen van SHA's voorstellen, dan kun je een Git sanitaire voorzieningen (plumbin) tool genaamd `rev-parse` gebruiken. Je kunt in Hoofdstuk 9 kijken voor meer informatie over plumbingtools, eigenlijk is `rev-parse` er voor low-level operaties en is niet ontworpen voor dagelijks gebruik. Maar het kan behulpzaam zijn op momenten dat je moet zien wat er echt aan de hand is. Hier kun je `rev-parse` uitvoeren op je branch. $ git rev-parse topic1 ca82a6dff817ec66f44342007202690a93763949 -### RefLog afkortingen ### +### RefLog verkorte namen ### -Een van de dingen die Git in de achtergrond doet terwijl jij zit te werken is een reflog bijhouden – een log waar je HEAD en branchreferenties zijn gebleven in de laatste paar maanden. +Een van de dingen die Git in de achtergrond doet terwijl jij zit te werken is een reflog bijhouden: een log waar de staat van HEAD en branchreferenties in de laatste paar maanden in is vastgelegd. Je kunt je reflog zien door `git reflog` te gebruiken: @@ -90,7 +90,7 @@ Je kunt je reflog zien door `git reflog` te gebruiken: 1c36188... HEAD@{5}: rebase -i (squash): updating HEAD 7e05da5... HEAD@{6}: rebase -i (pick): updating HEAD -Iedere keer als de punt van je branch om een of andere reden is gewijzigd, dan bewaart Git die informatie voor je in deze tijdelijke geschiedenis. En je kunt ook oudere commits hiermee specificeren. Als je de vijfde voorgaande waarde van de HEAD van je repository wil zien, dan kun je de `@{n}` referentie gebruiken, die je in de reflog output kunt zien: +Iedere keer als de punt van je branch om een of andere reden is gewijzigd, dan bewaart Git die informatie voor je in deze tijdelijke geschiedenis. En je kunt ook oudere commits met deze gegevens specificeren. Als je de vijfde voorgaande waarde van de HEAD van je repository wilt zien, dan kun je de `@{n}` referentie gebruiken, die je in de reflog output kunt zien: $ git show HEAD@{5} @@ -100,7 +100,7 @@ Je kunt deze syntax ook gebruiken om te zien waar een branch een bepaalde hoevee Dat laat je zien waar de punt van de branch gisteren was. Deze techniek werkt alleen voor gegevens die nog steeds in je reflog staan, dus je kunt het niet gebruiken om te kijken naar commits die ouder zijn dan een paar maanden. -Om reflog informatie te zien, die in hetzelfde formaat gezet is als de `git log` output, kun je `git log -g` uitvoeren: +Om reflog informatie te zien, in hetzelfde formaat als de `git log` output, kun je `git log -g` uitvoeren: $ git log -g master commit 734713bc047d87bf7eac9674765ae793478c50d3 @@ -119,11 +119,11 @@ Om reflog informatie te zien, die in hetzelfde formaat gezet is als de `git log` Merge commit 'phedders/rdocs' -Het is belangrijk om te zien dat deze informatie strikt lokaal is – het is een log van wat jij hebt gedaan in jouw repository. De referenties zullen niet hetzelfde zijn in iemand anders zijn kopie van de repository; en meteen nadat je een eerste kloon van een repository hebt gemaakt, heb je een lege reflog, omdat er nog geen activiteit is geweest in je repository. `git show HEAD@{2.months.ago}` uitvoeren werkt alleen als je het project minstens twee maanden geleden gekloond hebt – als je het vijf minuten geleden gekloond hebt, krijg je geen resultaten. +Het is belangrijk om te zien dat deze informatie strikt lokaal is, het is een log van wat je hebt gedaan in jouw repository. De referenties zullen niet hetzelfde zijn in de kopie van de repository die iemand anders gemaakt heeft, en meteen nadat je een eerste kloon van een repository hebt gemaakt heb je een lege reflog, omdat er nog geen activiteit is geweest in je repository. `git show HEAD@{2.months.ago}` uitvoeren werkt alleen als je het project minstens twee maanden geleden gekloond hebt, als je het vijf minuten geleden gekloond hebt krijg je geen resultaten. ### Voorouder referenties ### -De andere veelgebruikte manier om een commit te specificeren is via zijn voorouder. Als je een `^` aan het einde van een referentie zet, zal Git hieruit herleiden dat het de ouder van de commit betekent. +De andere veelgebruikte manier om een commit te specificeren is via zijn voorouders. Als je een `^` aan het einde van een referentie zet zal Git hieruit herleiden dat het de ouder van die commit betekent. Stel dat je naar de geschiedenis van je project kijkt: $ git log --pretty=format:'%h %s' --graph @@ -146,7 +146,7 @@ Dan zie je de vorige commit door `HEAD^` te specificeren, wat "de ouder van HEAD Merge commit 'phedders/rdocs' -Je kunt ook een nummer na de `^` zetten – bijvoorbeeld, `d921970^2` betekent "de tweede ouder van d921970." Deze syntax is alleen bruikbaar voor merge commits, die meer dan één ouder hebben. De eerste ouder is de branch waar jij op was toen je merge-te, en de andere is de commit op de branch die je ingemerged hebt: +Je kunt ook een getal na de `^` zetten, bijvoorbeeld `d921970^2` betekent "de tweede ouder van d921970." Deze syntax is alleen bruikbaar voor merge commits, die meer dan één ouder hebben. De eerste ouder is de branch waar jij op was toen je mergede, en de andere is de commit op de branch die je gemerged hebt: $ git show d921970^ commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b @@ -162,7 +162,7 @@ Je kunt ook een nummer na de `^` zetten – bijvoorbeeld, `d921970^2` betekent " Some rdoc changes -De andere manier om ouders mee te specificeren is de `~`. Dit refereert ook naar de eerste ouder, dus `HEAD~` en `HEAD^` zijn gelijk. Het verschil wordt duidelijk als je een nummer specificeert. `HEAD~2` betekent "de eerste ouder van de eerste ouder", of "de grootouder" – het bewandelt de eerste ouders het aantal keren dat je specificeert. Bijvoorbeeld, in de geschiedenis die eerder getoond werd, zou `HEAD~3` zijn +De andere manier om voorouders mee te specificeren is de `~`. Dit refereert ook naar de eerste ouder, dus `HEAD~` en `HEAD^` zijn gelijk. Het verschil wordt pas duidelijk als je een getal specificeert. `HEAD~2` betekent "de eerste ouder van de eerste ouder", of "de grootouder", het doorloopt de eerste ouders het aantal keren dat je specificeert. Bijvoorbeeld, in de geschiedenis die eerder getoond werd, zou `HEAD~3` het volgende resultaat geven $ git show HEAD~3 commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d @@ -171,7 +171,7 @@ De andere manier om ouders mee te specificeren is de `~`. Dit refereert ook naar ignore *.gem -Dit kan ook geschreven worden als `HEAD^^^`, wat nogmaals de eerste ouder van de eerste ouder van de eerste ouder is: +Dit kan ook geschreven worden als `HEAD^^^` wat, nogmaals, de eerste ouder van de eerste ouder van de eerste ouder is: $ git show HEAD^^^ commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d @@ -180,26 +180,26 @@ Dit kan ook geschreven worden als `HEAD^^^`, wat nogmaals de eerste ouder van de ignore *.gem -Je kunt deze syntaxen combineren – je kunt de tweede ouder van de vorige reference krijgen (aangenomen dat het een merge commit was) door `HEAD~3^2` te gebruiken, enzovoort. +Je kunt deze syntaxen combineren: je kunt de tweede ouder van de vorige referentie krijgen (aangenomen dat het een merge commit was) door `HEAD~3^2` te gebruiken, enzovoort. ### Commit reeksen ### -Nu dat je individuele commits kunt specificeren, laten we zien hoe je reeksen van commits kunt specificeren. Dit is erg bruikbaar om je branches te beheren – als je veel branches hebt, kun je reeks specificaties gebruiken om vragen te beantwoorden zoals, "Wat voor werk zit er op deze branch dat ik nog niet in mijn hoofdbranch heb?" +Nu je individuele commits kunt specificeren, laten we zien hoe je reeksen van commits kunt specificeren. Dit is vooral erg bruikbaar bij het beheren van je branches; als je veel branches hebt, kan je reeks-specificaties gebruiken om vragen te beantwoorden als: "Wat voor werk zit er op deze branch dat ik nog niet in mijn hoofdbranch heb?" -#### Dubbele punt #### +#### Dubbel-punt #### -De meest voorkomende reeks specificatie is de dubbele punt syntax. Dit vraagt Git een reeks commits op te zoeken, die bereikbaar zijn van één commit maar niet vanuit een ander. Bijvoorbeeld, stel dat je een commitgeschiedenis hebt die eruit ziet zoals in Figuur 6-1. +De meest voorkomende reeks specificatie is de dubbel-punt syntax. Dit vraagt Git een reeks commits op te zoeken, die bereikbaar zijn van de ene commit maar niet vanuit een ander. Bijvoorbeeld, stel dat je een commit-geschiedenis hebt die eruit ziet zoals in Figuur 6-1. Insert 18333fig0601.png -Figuur 6-1. Voorbeeldgeschiedenis voor reeksselectie. +Figuur 6-1. Voorbeeldgeschiedenis voor reeks-selectie. -Je wilt zien wat er in je experimentele branch zit dat nog niet in je hoofdbranch gemerged is. Je kunt Git vragen om je een log te tonen van alleen die commits met `master..experiment` – wat betekent "alle commits die bereikbaar zijn door experiment, die niet bereikbaar zijn door master". Om de voorbeelden kort en duidelijk te houden zal ik de letters van de commitobjecten in het diagram gebruiken in plaats van de echte log output, in de volgorde waarin ze getoond zouden worden: +Je wilt zien wat er in je experimentele branch zit dat nog niet in je hoofdbranch gemerged is. Je kunt Git vragen om je een log te tonen van alleen die commits met `master..experiment`, wat zoveel betekent als "alle commits die bereikbaar zijn voor experiment, die niet bereikbaar zijn voor master". Om de voorbeelden kort en duidelijk te houden zal ik de letters van de commitobjecten in het diagram gebruiken in plaats van de echte log output, in de volgorde waarin ze getoond zouden worden: $ git log master..experiment D C -Als je aan de andere kant het tegenovergestelde wilt zien – alle commits in `master` die niet bereikbaar zijn in `experiment` – dan kun je de branchnamen omdraaien. `experiment..master` toont je alles in `master` wat niet bereikbaar is in `experiment`: +Als je echter het tegenovergestelde wilt zien: alle commits in `master` die niet bereikbaar zijn in `experiment`, dan moet je de branchnamen omdraaien. `experiment..master` toont je alles in `master` wat niet bereikbaar is vanuit `experiment`: $ git log experiment..master F @@ -209,23 +209,23 @@ Dit is handig als je de `experiment` branch up to date wilt houden en vast wilt $ git log origin/master..HEAD -Dit commando toont je alle commits in je huidige branch, die niet in de `master` branch op je `origin` remote zitten. Als je een `git push` uitvoert, en je huidige branch volgt de `origin/master`, dan zijn de commits die getoond worden door `git log origin/master..HEAD` de commits die verstuurd zullen worden naar de server. -Je kunt ook één kant van de syntax weglaten en Git de HEAD laten aannemen. Bijvoorbeeld, je krijgt dezelfde resultaten als in het vorige voorbeeld door `git log origin/master..` te typen – Git vult HEAD in als er een kant mist. +Dit commando toont je alle commits in je huidige branch, die niet in de `master` branch op je remote `origin` zitten. Als je een `git push` uitvoert, en je huidige branch volgt de `origin/master`, dan zijn de commits die getoond worden door `git log origin/master..HEAD` de commits die verstuurd zullen worden naar de server. +Je kunt ook één kant van de syntax weglaten om Git de HEAD laten aannemen. Bijvoorbeeld, je krijgt dezelfde resultaten als in het vorige voorbeeld door `git log origin/master..` te typen; Git vult HEAD in als er één kant ontbreekt. #### Meerdere punten #### -De dubbele punt is makkelijk als een afkorting; maar misschien wil je meer dan twee branches specificeren om je revisie aan te geven, zoals zien welke commits in één van een serie branches zit, die nog niet in de branch zit waar je nu op zit. Git laat je dit doen door of het `^` karakter te gebruiken, of `--not` voor iedere referentie waarvan je de bereikbare commits niet wilt zien. Dus deze drie commando's zijn gelijk: +De syntax met de dubbel-punt is makkelijk als een afkorting, maar misschien wil je meer dan twee branches specificeren om je revisie aan te geven, zoals het zien welke commits in één van een serie branches zit, die nog niet in de branch zit waar je nu op zit. Git laat je dit doen door of het `^` karakter te gebruiken, of `--not` voor iedere referentie waarvan je de bereikbare commits niet wilt zien. Dus deze drie commando's zijn gelijk: $ git log refA..refB $ git log ^refA refB $ git log refB --not refA -Dit is fijn omdat met deze syntax je meer dan twee referenties in je vraag kunt specificeren, wat je niet met de dubbele put syntax kan. Bijvoorbeeld, als je alle commits wilt zien die bereikbaar zijn vanuit `refA` of `refB`, maar niet vanuit `refC`, dan kun je één van deze intypen: +Dit is prettig omdat met deze syntax je meer dan twee referenties in je vraag kunt specificeren, wat je niet met de dubbel punt syntax kan. Bijvoorbeeld, als je alle commits wilt zien die bereikbaar zijn vanuit `refA` of `refB`, maar niet vanuit `refC`, dan kun je één van deze intypen: $ git log refA refB ^refC $ git log refA refB --not refC -Dit zorgt voor een erg krachtig revisie vraagsysteem dat je zou moeten helpen om uit te zoeken wat in je branches zit. +Dit zorgt voor een erg krachtig revisie vraagsysteem dat je kan helpen om uit te zoeken wat in je branches zit. #### Drievoudige punt #### @@ -238,7 +238,7 @@ Als je wilt zien wat in je `master` of in je `experiment` zit, maar geen gedeeld D C -Nogmaals, dit geeft je normale `log` output, maar toont je alleen de commitinformatie voor die vier commits, getoond in de traditionele committijdstip volgorde. +Nogmaals, dit geeft je normale `log` output, maar toont je alleen de commit-informatie voor deze vier commits, getoond in de traditionele volgorde van committijdstip. Een veelgebruikte optie bij het `log` command in dit geval is `--left-right`, wat je laat zien aan welke kant van de reeks elke commit zit. Dit helpt de data bruikbaarder te maken: @@ -252,8 +252,8 @@ Met deze tools, kun je Git eenvoudiger laten weten welke commit of commits je wi ## Interactief stagen ## -Bij Git zitten een aantal scripts, die sommige commandline taken makkelijker maken. Hier zul je een aantal interactieve commando's zien, die je kunnen helpen om je commits zo te maken dat ze alleen bepaalde combinaties en delen van bestanden bevatten. Deze tools zijn erg bruikbaar als je een serie bestanden aanpast en dan besluit dat je deze veranderingen in een aantal gefocuste commits wilt hebben in plaats van een rommelige commit. Op deze manier ben je er zeker van dat je commits logische aparte wijzigingensets zijn en makkelijk gereviewed kunnen worden door je mede-ontwikkelaars. -Als je `git add` uitvoert met de `-i` of `--interactive` optie, dan gaat Git over in de interactieve shell modus, waarbij zoiets als dit getoond wordt: +Bij Git zitten een aantal scripts, die sommige commandline taken makkelijker maken. Hier zul je een aantal interactieve commando's zien, die je kunnen helpen om je commits zo te maken dat ze alleen bepaalde combinaties en delen van bestanden bevatten. Deze tools zijn erg nuttig als je een serie bestanden aanpast en dan besluit dat je deze veranderingen in een aantal gefocuste commits wilt hebben in plaats van één grote rommelige commit. Op deze manier ben je er zeker van dat je commits logische aparte wijzigingensets zijn en makkelijk gereviewed kunnen worden door je mede-ontwikkelaars. +Als je `git add` uitvoert met de `-i` of `--interactive` optie, dan schakelt Git over naar een interactieve shell modus, waarbij zoiets als dit getoond wordt: $ git add -i staged unstaged path @@ -266,9 +266,9 @@ Als je `git add` uitvoert met de `-i` of `--interactive` optie, dan gaat Git ove 5: patch 6: diff 7: quit 8: help What now> -Je kunt zien dat dit commando je een heel andere view van je staging area geeft – eigenlijk dezelfde informatie die je krijgt met het `git status` commando, maar dan compacter en meer informatief. Het toont links de wijzigingen die je gestaged hebt, en de niet gestagede wijzigingen rechts. +Je kunt zien dat dit commando je een heel andere kijk op je staging area geeft: eigenlijk dezelfde informatie die je krijgt met het `git status` commando, maar dan compacter en meer informatief. Het toont links de wijzigingen die je gestaged hebt, en de niet gestagede wijzigingen rechts. -Hierna volgt een commandosectie. Hier kun je een aantal dingen mee doen, inclusief bestanden stagen, bestanden unstagen, delen van bestanden stagen, ongevolgde bestanden toevoegen, en diffs zien van wat gestaged is. +Hierna volgt een commando-sectie. Hier kun je een aantal dingen doen, staging bestanden toevoegen, bestanden unstagen, delen van bestanden stagen, ongevolgde bestanden toevoegen, en diffs zien van wat gestaged is. ### Bestanden stagen en unstagen ### @@ -281,7 +281,7 @@ Als je `2` of `u` op de `What now>` prompt typt, dan vraagt het script welke bes 3: unchanged +5/-1 lib/simplegit.rb Update>> -Om de TODO en index.html bestanden te stagen, kun je de nummers typen: +Om de TODO en index.html bestanden te stagen, kun je de getallen typen: Update>> 1,2 staged unstaged path @@ -290,7 +290,7 @@ Om de TODO en index.html bestanden te stagen, kun je de nummers typen: 3: unchanged +5/-1 lib/simplegit.rb Update>> -De `*` naast ieder bestand betekent dat het bestand geselecteerd staat om gestaged te worden. Als je Enter indrukt na niets getypt te hebben op de `Update>>` prompt, dan zal Git alles wat geselecteerd staat pakken en voor je stagen: +De `*` naast ieder bestand geeft aan dat het bestand geselecteerd staat om gestaged te worden. Als je Enter indrukt na niets getypt te hebben op de `Update>>` prompt, dan zal Git alles wat geselecteerd staat pakken en voor je stagen: Update>> updated 2 paths @@ -322,7 +322,7 @@ Nu kun je zien dat de TODO en index.html bestanden gestaged zijn, en het simpleg Revert>> [enter] reverted one path -Nogmaals kijkend naar je Git status, kun je zien dat je het TODO bestand unstaged hebt: +Als je nu nog eens naar je Git status kijkt, kun je zien dat je het TODO bestand ge-unstaged hebt: *** Commands *** 1: status 2: update 3: revert 4: add untracked @@ -333,7 +333,7 @@ Nogmaals kijkend naar je Git status, kun je zien dat je het TODO bestand unstage 2: +1/-1 nothing index.html 3: unchanged +5/-1 lib/simplegit.rb -Om de diff te zien van wat je gestaged hebt, kun je het `6` of `d` (voor diff) commando gebruiken. Het toont je een lijst van je gestagede bestanden, en je kunt degenen selecteren waarvan je de gestagede diff wilt zien. Dit is vergelijkbaar met het specificeren van `git diff --cached` op de commando regel: +Om de diff te zien van wat je gestaged hebt, kun je het `6` of `d` (voor diff) commando gebruiken. Het toont je een lijst van je gestagede bestanden, en je kunt diegenen selecteren waarvan je de gestagede diff wilt zien. Dit is vergelijkbaar met het specificeren van `git diff --cached` op de commando regel: *** Commands *** 1: status 2: update 3: revert 4: add untracked @@ -355,11 +355,11 @@ Om de diff te zien van wat je gestaged hebt, kun je het `6` of `d` (voor diff) c