diff --git a/.travis.yml b/.travis.yml index 021aa63ec..9071e3867 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ language: ruby rvm: - 1.9.3 -script: rake ci:check +script: rake ci:parallel_check notifications: - email: false \ No newline at end of file + email: + recipients: + - jn.avila@free.fr + diff --git a/Gemfile b/Gemfile index 79f6c3029..59fd845ae 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,5 @@ source 'https://rubygems.org' -gem 'maruku', '0.6.1' +gem 'maruku', '0.7.1' gem 'redcarpet' -gem 'rdiscount' +gem 'parallel' diff --git a/README.md b/README.md index 5e72d6d1f..39d3f6dfa 100644 --- a/README.md +++ b/README.md @@ -1,58 +1,9 @@ -[![Build Status](https://secure.travis-ci.org/progit/progit.png?branch=master)](https://travis-ci.org/progit/progit) +# Pro Git, 1st Edition -# Pro Git Book Contents +This is the source for the 1st edition of the Pro Git book. The second edition has since been released and is what will be maintained and published going forward. Please suggest any changes to that version instead. -This is the source code 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: +You can find the new edition at: -http://tinyurl.com/amazonprogit +https://github.com/progit/progit2 -It is also available online at: - -http://git-scm.com/book/ - -and fully translated in 10 languages. - -# Making Ebooks - -On Fedora (16 and later) you can run something like this:: - - $ yum install ruby calibre rubygems ruby-devel rubygem-ruby-debug rubygem-rdiscount - $ makeebooks en # will produce a mobi - -On MacOS you can do like this:: - -1. INSTALL ruby and rubygems -2. `$ gem install rdiscount` -3. DOWNLOAD Calibre for MacOS and install command line tools. You'll need some dependencies to generate a PDF: - * pandoc: http://johnmacfarlane.net/pandoc/installing.html - * xelatex: http://tug.org/mactex/ -4. `$ makeebooks zh` #will produce a mobi - -## Notes on pandoc - -Please use Pandoc version 1.11.1 or later as older versions(confirmed on 1.9.1.1) has a [bug](https://github.com/jgm/pandoc/issues/964) which hides a word after tilde `~`. You can do `pandoc -v` to see which version you have installed. - -# Errata - -If you see anything that is technically wrong or otherwise in need of -correction, please [open an issue](https://github.com/progit/progit/issues/new) and one of the maintainers will take a look. - - -# Translation - -If you wish to translate the book, your work will be put up on the -git-scm.com site. Please put your translation into the appropriate -subdirectory of this project, using the -[ISO 639](http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) -and send a pull request. - -# Sending a pull request - -* Be careful to use UTF-8 encoding in your files. -* Do not mix changes to the original english with translations in a single pull request. -* If your pull request changes a translation, prefix your pull request and commits'messages with the ISO 639 code, e.g. `[de] Update chapter 2`. Please only push files where there is already some translation done. -* Make sure the translation changes can be automatically merged. The maintainers can not make the merge manually if there are some conflicts. -* Make as sure as possible that the changes work correctly for publishing to pdf, ebooks and the git-scm.com website +If you're looking for the original README content, it can be found in the [README.original.md](README.original.md) file. diff --git a/README.original.md b/README.original.md new file mode 100644 index 000000000..b6556fd75 --- /dev/null +++ b/README.original.md @@ -0,0 +1,70 @@ +[![Build Status](https://secure.travis-ci.org/progit/progit.png?branch=master)](https://travis-ci.org/progit/progit) + +# Pro Git Book Contents + +This is the source code 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: + +http://tinyurl.com/amazonprogit + +It is also available online at: + +http://git-scm.com/book/ + +and fully translated in 10 languages. + +# Making Ebooks + +On Fedora (16 and later) you can run something like this:: + + $ yum install ruby calibre rubygems ruby-devel rubygem-ruby-debug rubygem-rdiscount + $ makeebooks en # will produce a mobi + +On MacOS you can do like this: + +1. INSTALL ruby and rubygems +2. `$ gem install rdiscount` +3. DOWNLOAD Calibre for MacOS and install command line tools. You'll need some dependencies to generate a PDF: + * pandoc: http://johnmacfarlane.net/pandoc/installing.html + * xelatex: http://tug.org/mactex/ +4. `$ makeebooks zh` #will produce a mobi + +On Windows you can do like this: + +1. Install ruby and related tool from http://rubyinstaller.org/downloads/ + * RubyInstaller (ruby & gem) + * Development Kit (to build rdiscount gem) +2. Open `cmd` and `$ gem install rdiscount` +3. Install Calibre for Windows from http://calibre-ebook.com/download +4. `$ SET ebook_convert_path=c:\Program Files\Calibre2\ebook-convert.exe`. Modify to suit with your Calibre installed path. +5. Make ebooks: + * `$ ruby makeebooks vi` #will produce a mobi + * `$ SET FORMAT=epub` then `$ ruby makeebooks vi` #will produce an epub + +## Notes on pandoc + +Please use Pandoc version 1.11.1 or later as older versions (confirmed on 1.9.1.1) has a [bug](https://github.com/jgm/pandoc/issues/964) which hides a word after tilde `~`. You can do `pandoc -v` to see which version you have installed. + +# Errata + +If you see anything that is technically wrong or otherwise in need of +correction, please [open an issue](https://github.com/progit/progit/issues/new) and one of the maintainers will take a look. + + +# Translation + +If you wish to translate the book, your work will be put up on the +git-scm.com site. Please put your translation into the appropriate +subdirectory of this project, using the +[ISO 639](http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) code +and send a pull request. + +# Sending a pull request + +* Be careful to use UTF-8 encoding in your files. +* Do not mix changes to the original English with translations in a single pull request. +* If your pull request changes a translation, prefix your pull request and commits' messages with the ISO 639 code, e.g. `[de] Update chapter 2`. Please only push files where there is already some translation done. +* Make sure the translation changes can be automatically merged. The maintainers can not make the merge manually if there are some conflicts. +* Make as sure as possible that the changes work correctly for publishing to PDF, ebooks and the git-scm.com website. diff --git a/Rakefile b/Rakefile index c9b0d9b3f..3aeaebf78 100644 --- a/Rakefile +++ b/Rakefile @@ -160,15 +160,100 @@ 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, out) + 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} + source_files = FileList.new(File.join(lang, '0*', '*.markdown')).sort + source_files.each do |mk_filename| + 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:]]+$/ + out<< "\nBadly formatted title in #{mk_filename}: #{line}\n" + error_code = true + end + end + if line.match /^\s*Insert\s(.*)/i + if line.match /^\s*Insert\s(.*)/ + figure_count = figure_count + 1 + else + out << "\n#{lang}: Badly cased Insert directive: #{line}\n" + error_code = true + end + 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 + out << "\nToo many figures declared in #{mk_filename}\n" + error_code = true + end + end + begin + mark = (source_files.map{|mk_filename| File.open(mk_filename, 'r'){ + |mk| mk.read.encode("UTF-8")}}).join("\n\n") + require 'maruku' + code = Maruku.new(mark, :on_error => :raise, :error_stream => StderrDecorator.new(out)) + rescue + print $! + error_code = true + end + 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| + 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? + end + + (FileList.new('??')+FileList.new('??-??')).each do |lang| + desc "testing " + lang + task (lang+"_check").to_sym do + error_code = test_lang(lang, $out) + fail "processing #{lang} KO\n" if error_code + print "processing #{lang} OK\n" + end + end desc "Continuous Integration" task :check do @@ -184,59 +269,17 @@ 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} - langs.each do |lang| + errors = langs.map 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, $out) + if error_code print "KO\n" - print $! - error_code = true + else + print "OK\n" end + error_code end - fail "At least one language conversion failed" if error_code + fail "At least one language conversion failed" if errors.any? end end diff --git a/ar/01-introduction/01-chapter1.markdown b/ar/01-introduction/01-chapter1.markdown index c91e325ea..6ec46b534 100644 --- a/ar/01-introduction/01-chapter1.markdown +++ b/ar/01-introduction/01-chapter1.markdown @@ -168,7 +168,7 @@ If a particular version of a file is in the git directory, it’s considered com هناك طريقتين للتنصيب على ماك أو اس، الأسهل هي استخدام الواجهة الرسومية للتنصيب، والتي يمكنك تحميلها من صفحة المشروع على غوغل كود (انظر الشكل 1-7): - http://code.google.com/p/git-osx-installer + http://sourceforge.net/projects/git-osx-installer/ Insert 18333fig0107.png الشكل 1-7. تنصيب Git على ماك أو اس. diff --git a/ar/02-git-basics/01-chapter2.markdown b/ar/02-git-basics/01-chapter2.markdown index 42771d7b9..72948c863 100644 --- a/ar/02-git-basics/01-chapter2.markdown +++ b/ar/02-git-basics/01-chapter2.markdown @@ -1,4 +1,4 @@ -# مبادئ Git # +# مبادئ Git # إذا كان هناك فصل واحد عليك قراءته لكي تبدأ بإستخدام Git، فعليك بهذا الفصل! يغطي هذا الفصل جميع الأوامر الأساسية التي عليك معرفتها لكي تتمكن من القيام بأغلب الأمور أثناء استخدامك لـ Git. في نهاية هذا الفصل يجب أن تكون قادراً على انشاء واعداد الـ repository لمشروعك وعلى تحديد الملفات التي ستتم متابعتها والتي ستترك، وعلى تهييئ التغييرات لعمل commit عليها. ستتعلم أيضاً كيف تعد Git لكي تتجاهل بعض أنواع الملفات، كيف تقوم بالتراجع عن الأخطاء التي سترتكبها بسرعة وبسهولة، كيف تتصفح تاريخ مشروعك وكيف تعرض التغيرات بين الـ commits، وكيف تنشر وتسحب (push & pull) التغيرات من الـ repositories البعيدة عنك. @@ -40,27 +40,26 @@ هناك عدد من البروتوكولات المختلفة التي يمكنك اسستعمالها لنقل المعلومات في git. المثال السابق يستعمل بروتوكول 'git://'، ولكن من الممكن أن تجد أيضاً استخداماً لـ 'http(s)://' أو 'user@server:/path.git'، والتي تستعمل بروتوكول SSH في النقل. في الفصل الرابع من الكتاب ستتعرف على الخيارات المتوفرة للتواصل مع الـ repository الخاصة بك وميزات ومساوئ كل منها. ## تسجيل التعديلات في الـ repository ## +لديك repository أصلي ونسخة لتعمل عليها من ملفات المشروع. عليك أن تقوم ببعض التعديلات ثم تعمل commit لهذه التعديلات في repository الخاص بك في كل مرة يصل فيها المشروع إلى نقطة تود تسجيلها. -You have a bona fide Git repository and a checkout or working copy of the files for that project. You need to make some changes and commit snapshots of those changes into your repository each time the project reaches a state you want to record. +تذكر أنه كل ملف في مجلد العمل يمكن أن يكون في إحدى الحالتين فقط: مٌتَتَبّع tracked أو غير مٌتَتَبّع untracked. الملفات المٌتتبّعة هي ملفات كانت في أخر snapshot ويمكن إلغاء التعديلات عليها أو التعديل عليها أو وضعه في حالة staged (جاهز من أجل commit). الملفات غير المُتتبّعة هي كل الملفات الآخرى - أي ملف في مجلد العمل لم يكن موجوداً في آخر snapshot وليس معلماً بأنه staged. عندما تقوم باستنساخ repository جميع ملفاتك تكون بحالة متتبّعة tracked و غير معدلة unmodified لأنك قمت للتو بعمل check out ولم تقم بأي تعديل. -Remember that each file in your working directory can be in one of two states: tracked or untracked. Tracked files are files that were in the last snapshot; they can be unmodified, modified, or staged. Untracked files are everything else - any files in your working directory that were not in your last snapshot and are not in your staging area. When you first clone a repository, all of your files will be tracked and unmodified because you just checked them out and haven’t edited anything. - -As you edit files, Git sees them as modified, because you’ve changed them since your last commit. You stage these modified files and then commit all your staged changes, and the cycle repeats. This lifecycle is illustrated in Figure 2-1. +عندما تعدل الملفات، سيقوم git بتأشيرهم على أنهم modified، لأنك قمت بتغيرهم عن آخر commit. تقوم بعمل stage لهذه الملفات المعدلة ثم تقوم بعمل commit لجميع التغيرات في منطقة stage، وتتكرر العملية. يوضع الشكل 2-1 دورة العملية. Insert 18333fig0201.png -Figure 2-1. The lifecycle of the status of your files. +الشكل 2-1. دورة حالة الملفات. -### Checking the Status of Your Files ### +### تفقد حالة ملفاتك ### -The main tool you use to determine which files are in which state is the git status command. If you run this command directly after a clone, you should see something like this: +باستخدام الأمر git status يمكننا معرفة حالة الملفات لدينا. إذا قمت بتشغيل هذا الأمر مباشرة بعد قيامك بعمل clone يجب أن ترى شيئاً يشبه التالي: $ git status # On branch master - nothing to commit (working directory clean) + nothing to commit, working directory clean -This means you have a clean working directory—in other words, there are no tracked and modified files. 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. +وهذا يعني أنه لديك مجلد عمل نظيف - بمعنى آخر، لايوجد أي ملفات معدلة أو ملفات غير مُتتبّعة. كما أنّ هذا الأمر يخبرك بأي فرع branch أنت تعمل. حالياً، دائماً هو master، وهو الافتراضي؛ في الفصل المقبل سنمر على الأفرع و المرجعيات references بالتفصيل. -Let’s say you add a new file to your project, a simple README file. If the file didn’t exist before, and you run `git status`, you see your untracked file like so: +لنقل بأنك قمت بإضافة ملف جديد على مشروعك، وليكن ملف README بسيط. إذا لم يكن الملف موجوداً مسبقاً، وقمت بتنفيذ الأمر `git status` سترى الملف غير مُتتبّعاً كما يلي: $ vim README $ git status @@ -71,15 +70,15 @@ Let’s say you add a new file to your project, a simple README file. If the fil # 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. +يمكنك ملاحظة أنّ ملفك الجديد README غير مُتتبّع، فهو تحت تبويب "untracked files" في خرج الأمر. ويعني ذلك أنّ git يرى ملفاً جديداً على commit السابقة؛ علماً أنّ git لن يقوم بإضافة هذا الملف إلى الملفات المتتبعة إلا إذا قمت بطلب ذلك بشكل مباشر، والهدف من ذلك من أجل حماية المشروع من الضم الخاطئ لملفات binary أو أي ملفات لا تود بإضافتها. إلاّ أنّك ترغب في إضافة README إلى الملفات المتتبّعة. وسنقوم بذلك حالاً. -### Tracking New Files ### +### تتبع الملفات الجديدة ### -In order to begin tracking a new file, you use the command `git add`. To begin tracking the README file, you can run this: +للقيام بتتبع ملف جديد عليه استخدام الأمر `git add` . مثلاً لنقم بتتبع الملف الجديد README: $ git add README -If you run your status command again, you can see that your README file is now tracked and staged: +إذا قمنا بتنفيذ الأمر `git status` مرة أخرى سنلاحظ أن الملف README أصبح متتبعاً وجاهزاً staged للقيام بعملية commit: $ git status # On branch master @@ -89,11 +88,11 @@ If you run your status command again, you can see that your README file is now t # 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. +نستطيع معرفة بأن الملف staged من خلال ملاحظته تحت بند "changes to be comitted". إذا قمت بعمل commit في هذه اللحظة، سيقوم git بإضافة النسخة الحالية من الملف إلى snapshot. تذكر عندما قمنا بعمل git init سابقاً، ثم قمنا بإضافة الملفات عن طريق git add، كان ذلك للقيام ببدء تتبع الملفات في مجلد المشروع. يقبل الأمر git add مسار لملف أو لمجلد؛ فإذا كان المسار لمجلد سيقوم git بإضافة جميع الملفات والمجلدات ضمنه بشكل تعاودي recursively. -### Staging Modified Files ### +### تجهيز الملفات المعدلة ### -Let’s change a file that was already tracked. If you change a previously tracked file called `benchmarks.rb` and then run your `status` command again, you get something that looks like this: +لنقم بالتعديل على ملف قمنا بإضافته سابقاً. إذا قمنا مثلاً بالتعديل على ملف متتبع مسبقاً يدعى `benchmarks.rb` وقمنا بتنفيذ الأمر git status، سيكون الخرج مشابهاً للخرج التالي: $ git status # On branch master @@ -108,7 +107,7 @@ Let’s change a file that was already tracked. If you change a previously track # 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: +يظهر الملف benchmarks.rb تحت بند "changes not staged for commit" وهذا يعني أن الملف المُتتبّع قد خضع لعملية تعديل لكنه لم يخضع للتجهيز من أجل commit. للقيام بتجهيزه (أو تأشيره للإضافة إلى commit الجديد) يجب علينا تنفيذ الأمر `git add` (لاحظ بأنّه أمر متعدد الوظائف - نستطيع استخدامه لتتبع الملفات الجديدة، تجهيز الملفات من أجل commit، والقيام بأمور أخرى مثل حل الاعتراضات في حال القيام بدمج merge). لنقم بتنفيذ git add الآن لوضع benchmarks.rb بحالة staged، ومن ثم لنقم بتنفيذ الأمر git status لنرى ما الذي قد تغيّر: $ git add benchmarks.rb $ git status @@ -120,7 +119,7 @@ The benchmarks.rb file appears under a section named “Changes not staged for c # 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: +كلا الملفين الآن جاهز للإدخال بعملية commit المقبلة. في هذه النقطة، لنفرض أنك تود القيام بتعديل على ملف benchmarks.rb قبل القيام بعملية commit، ستقوم بفتح الملف والتعديل عليه وأنك جاهز للقيام بعملية commit. لكن قبل ذلك، دعنا نقوم بتنفيذ الأمر git status مرة إضافية: $ vim benchmarks.rb $ git status @@ -137,7 +136,7 @@ Both files are staged and will go into your next commit. At this point, suppose # 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: +ما الذي يحصل؟ كيف أصبح benchmarks.rb موجوداً تحت التبويبين staged و unstaged؟ لقد اتضح لنا أنّ git يقوم بتجهيز الملف على حالته عند قيامك بتنفيذ الأمر git add. إذا قمت بعمل commit الآن، ستكون نسخة benchmarks.rb كما كانت عند قيامك بتنفيذ الأمر git add وليس النسخة الجديدة التي حصلنا عليها بعد قيامنا بتعديل الملف. لذا إذا قمنا بتعديل ملف قبل قيامنا بتنفيذ git add، وقبل القيام بعملية commit، علينا تجهيز الملف مرة أخرى لعملية commit، وذلك بتنفيذ الأمر git add مرة جديدة: $ git add benchmarks.rb $ git status @@ -149,26 +148,26 @@ What the heck? Now benchmarks.rb is listed as both staged and unstaged. How is t # modified: benchmarks.rb # -### Ignoring Files ### +### تجاهل الملفات ### -Often, you’ll have a class of files that you don’t want Git to automatically add or even show you as being untracked. These are generally automatically generated files such as log files or files produced by your build system. In such cases, you can create a file listing patterns to match them named .gitignore. Here is an example .gitignore file: +غالباً ما تود من git تجاهل صنف من الملفات بحث لا يقوم بإضافتها تلقائياً أو لا يظهرها بأنّها غير متتبعة. تكون هذه الملفات عادة ملفات مولدة بشكل تلقائي مثل ملفات log و الملفات الوسيطة التي تولدها أدوات التطوير لديك. في مثل هذه الحالات/ يمكن إنشاء ملف .gitignore يحوي على أنماط لأسماء الملفات التي نرغب بتجاهلها. هذا مثال عمّا قد يحتويه ملف .gitignore: $ cat .gitignore *.[oa] *~ -The first line tells Git to ignore any files ending in .o or .a — object and archive files that may be the product of building your code. The second line tells Git to ignore all files that end with a tilde (`~`), which is used by many text editors such as Emacs to mark temporary files. You may also include a log, tmp, or pid directory; automatically generated documentation; and so on. Setting up a .gitignore file before you get going is generally a good idea so you don’t accidentally commit files that you really don’t want in your Git repository. +أول سطر يقوم بتوجيه git إلى تجاهل أي ملفات ذات لواحق من النوع o أو a - ملفات الكائنات وملفات الأرشيف وهي ملفات وسيطة تولدها أدوات بناء الكود عادة. السطر الثاني يوجه git إلى تجاهل أي ملفات تنتهي بالرمز (~) والتي تكون ملفات مؤقتة عادةً تستخدمها بعض برامج تحرير الكود. قد ترغب أيضاً بإضافة مجلدات log و tmp أو pid؛ أو حتى ملفات التوثيق تلقائية التوليد (من الكود عادة)، وغيرها. ينصح بإضافة ملف .gitignore في بداية إنشاء repository حتى نتجنب إضافة بعض الملفات عن طريق الخطأ وتلويث respository. -The rules for the patterns you can put in the .gitignore file are as follows: +قواعد الأنماط التي يمكن وضعها ضمن ملف .gitignore هي كالتالي: -* Blank lines or lines starting with # are ignored. -* Standard glob patterns work. -* You can end patterns with a forward slash (`/`) to specify a directory. -* You can negate a pattern by starting it with an exclamation point (`!`). +* الأسطر التي تبدأ بالرمز (#) يتم تجاهلها. +* أنماط glob القياسية تعمل. +* يمكن إنهاء النمط برمز (/) للدلالة على أنه يستهدف مجلداً. +* يمكن نفي نمط ما عن طريق وضع علامة التعجب (!) في بداية السطر قبل النمط. -Glob patterns are like simplified regular expressions that shells use. An asterisk (`*`) matches zero or more characters; `[abc]` matches any character inside the brackets (in this case a, b, or c); a question mark (`?`) matches a single character; and brackets enclosing characters separated by a hyphen(`[0-9]`) matches any character between them (in this case 0 through 9) . +أنماط Glob عبارة عن نسخة مبسطة من Regular Expressions يتم استخدامها ضمن واجهة الأوامر shell. رمز النجمة (`*`) يطابق صفر-محرفاً أو أكثر. `[abc]` تطابق أي محارف ضمن الأقواس المربعة في هذه الحالة تكون a b c؛ علامة الاستفهام (?) تطابق محرفاً واحداً فقط؛ بينما تطابق الأقواس المربعة التي تحوي على محارف مفصولة بإشارة hyphen أي محرفاً يقع في المجال بين محرف البداية والنهاية - مثلا [0-9] يطابق محارف الأرقام بين 0 و 9 ضمناً. -Here is another example .gitignore file: +مثال عن ملف .gitignore: # a comment – this is ignored # no .a files @@ -182,11 +181,12 @@ Here is another example .gitignore file: # ignore doc/notes.txt, but not doc/server/arch.txt doc/*.txt -### Viewing Your Staged and Unstaged Changes ### +### مشاهدة التغيّرات المجهّزة والتغيّرات غير المجهّزة ### -If the `git status` command is too vague for you — you want to know exactly what you changed, not just which files were changed — you can use the `git diff` command. We’ll cover `git diff` in more detail later; but you’ll probably use it most often to answer these two questions: What have you changed but not yet staged? And what have you staged that you are about to commit? Although `git status` answers those questions very generally, `git diff` shows you the exact lines added and removed — the patch, as it were. +إذا لم تكتف بالمعلومات التي يقدمها لك أمر `git status` يمكنك استخدام أمر `git diff` للحصول على معلومات تفصيلية حول التغيرات التي طرأت على الملفات. سنقوم لاحقاً بالتعمق في هذا الأمر، لكن الآن سنكتفي بالإشارة إلى الاستخدامات الغالبة له؛ حيث أنك ستستخدمه غالباً للحصول على أجوبة على هذين السؤالين: ما الذي قمنا بالتعديل عليه ولم نجهزه بعد لعملية commit؟ ما الملفات التي أصبحت جاهزة للدخول في عملية commit المقبلة؟ +بالرغم من أنه يمكننا أن نحصل على هذه المعلومات باستخدام أمر `git status` إلا أنّ أمر `git diff` يوضح لنا التغيرات التي جرت على مستوى السطر والحرف - ما الذي قمنا بإضافته وما الذي أزلناه! -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: +لنقل أنك قمت بالتعديل على ملف README مرة أخرى وأشرته للإضافة إلى عملية commit وقمت بالتعديل على ملف benchmarks.rb ولم تضفه إلى قائمة الملفات الجاهزة لعملية commit؛ إذا قمت بتنفيذ الأمر `status` ستشاهد مرة أخرى شيئاً من الشكل: $ git status # On branch master @@ -201,7 +201,7 @@ Let’s say you edit and stage the README file again and then edit the benchmark # modified: benchmarks.rb # -To see what you’ve changed but not yet staged, type `git diff` with no other arguments: +لترى ما قمت بالتعديل عليه ولم تجهزه للإضافة نفذ الأمر `git diff` بدون إضافات: $ git diff diff --git a/benchmarks.rb b/benchmarks.rb @@ -220,9 +220,9 @@ To see what you’ve changed but not yet staged, type `git diff` with no other a log = git.commits('master', 15) log.size -That command compares what is in your working directory with what is in your staging area. The result tells you the changes you’ve made that you haven’t yet staged. +يقوم هذا الأمر بعمل مقارنة بين الملفات ضمن مجلد العمل والملفات الموجودة في منطقة التعديلات المجهزة للإضافة staging area. وتخبرنا نتيجته بالتعديلات التي أجريناها ولم نقم بتجهيزها للإضافة إلى عملية commit المقبلة. -If you want to see what you’ve staged that will go into your next commit, you can use `git diff –-cached`. (In Git versions 1.6.1 and later, you can also use `git diff –-staged`, which may be easier to remember.) This command compares your staged changes to your last commit: +لمشاهدة الملفات ذات الحالة staged والتي ستدخل في عملية commit المقبلة، يمكن استخدام الأمر `git diff --cached` (بالنسبة للإصدارات 1.6.1 وما بعد من git يمكنك أيضاً استخدام الأمر `git diff --staged` )، كالتالي: $ git diff --cached diff --git a/README b/README @@ -237,9 +237,9 @@ If you want to see what you’ve staged that will go into your next commit, you + +Grit is a Ruby library for extracting information from a Git repository -It’s important to note that `git diff` by itself doesn’t show all changes made since your last commit — only changes that are still unstaged. This can be confusing, because if you’ve staged all of your changes, `git diff` will give you no output. +من الجدير بالذكر أن أمر `git diff` لوحده لا يقوم بعرض جميع التعديلات التي تمت من آخر commit - فهو يقوم بعرض فقط التعديلات التي لم تؤشر على أنها staged. ويمكن أن يسبب ذلك بعض الإرباك، حيث أنك إذا قمت بإضافة جميع التعديلات إلى قائمة staged فلن يقوم بعرض أي شي في خرج تنفيذه. -For another example, if you stage the benchmarks.rb file and then edit it, you can use `git diff` to see the changes in the file that are staged and the changes that are unstaged: +كمثال أيضاً، إذا قمنا بإضافة benchmarks.rb إلى قائمة staged ومن ثم قمنا بالتعديل عليه من جديد، يمكننا استخدام أمر `git diff` للحصول على لائحة بالتغييرات التي حصلت ولم تضف إلى قائمة staged كالتالي: $ git add benchmarks.rb $ echo '# test line' >> benchmarks.rb @@ -255,7 +255,6 @@ For another example, if you stage the benchmarks.rb file and then edit it, you c # modified: benchmarks.rb # -Now you can use `git diff` to see what is still unstaged $ git diff diff --git a/benchmarks.rb b/benchmarks.rb @@ -268,7 +267,7 @@ Now you can use `git diff` to see what is still unstaged ##pp Grit::GitRuby.cache_client.stats +# test line -and `git diff --cached` to see what you’ve staged so far: +وباستخدام `git diff --cached` نتمكن من رؤية ما تم تجهيزه للإضافة إلى عملية commit القادمة: $ git diff --cached diff --git a/benchmarks.rb b/benchmarks.rb @@ -287,16 +286,15 @@ and `git diff --cached` to see what you’ve staged so far: log = git.commits('master', 15) log.size -### Committing Your Changes ### +### القيام بعملية (اعتماد) commit للتغيّرات ### -Now that your staging area is set up the way you want it, you can commit your changes. Remember that anything that is still unstaged — any files you have created or modified that you haven’t run `git add` on since you edited them — won’t go into this commit. They will stay as modified files on your disk. -In this case, the last time you ran `git status`, you saw that everything was staged, so you’re ready to commit your changes. The simplest way to commit is to type `git commit`: +بعد اكمال تجهيز الملفات التي ترغب بإضافتها إلى النسخة snapshot الجديدة، يمكنك تنفيذ أمر commit ليتم اعتماد التعديلات التي أجريتها في سجل git. تذكر أنّ أي ملف لم يتم تجهيزه - سواء لم تقم بإضافته باستخدام الأمر git add بعد إنشاءه أو التعديل عليه - لن يدخل في هذه الإعتمادية، وستبقى على أنها ملفات تم تعديلها في مجلد العمل. أبسط طريقة لاعتماد التعديلات هي القيام بأمر `git commit` كالتالي: $ git commit -Doing so launches your editor of choice. (This is set by your shell’s `$EDITOR` environment variable — usually vim or emacs, although you can configure it with whatever you want using the `git config --global core.editor` command as you saw in Chapter 1). +تنفيذ هذا الأمر سيطلب منا إدخال رسالة عملية commit - عادة ما يتم فتح محرر النصوص المشار إليه بمتغير البيئة `$EDITOR`. يمكنك تهيئته عن طريق الأمر `git config --global core.editor` كما شاهدنا في الفصل الأول. -The editor displays the following text (this example is a Vim screen): +يقوم محرر النصوص بعرض هذه الشاشة (مثالنا باستخدام VIM): # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. @@ -311,22 +309,22 @@ The editor displays the following text (this example is a Vim screen): ~ ".git/COMMIT_EDITMSG" 10L, 283C -You can see that the default commit message contains the latest output of the `git status` command commented out and one empty line on top. You can remove these comments and type your commit message, or you can leave them there to help you remember what you’re committing. (For an even more explicit reminder of what you’ve modified, you can pass the `-v` option to `git commit`. Doing so also puts the diff of your change in the editor so you can see exactly what you did.) When you exit the editor, Git creates your commit with that commit message (with the comments and diff stripped out). +يمكنك ملاحظة أن رسالة عملية commit تحوي على خرج آخر عملية `git status` على شكل تعليقات بالإضافة إلى سطر فارغ في بداية الملف. يمكنك إزالة هذه التعليقات، أو يمكنك تركها لمساعدتك بتذكر ما قمت باعتماد تعديلاته. يمكنك الحصول على معلومات أكثر تفصلياً إذا قمت بتمرير الخيار `-v` إلى الأمر `git commit`. حيث يقوم ذلك بإضافة خرج أمر `git diff` إلى رسالة commit على شكل تعليقات أيضاً. عند إغلاق المحرر يقوم git بإنشاء commit ويتجاهل التعليقات. -Alternatively, you can type your commit message inline with the `commit` command by specifying it after a -m flag, like this: +علماً أنّه يمكنك كتابة رسالة الاعتمادية مباشرة من خلال تمرير الخيار `-m` إلى الأمر `git commit` على الشكل التالي: $ git commit -m "Story 182: Fix benchmarks for speed" [master]: created 463dc4f: "Fix benchmarks for speed" 2 files changed, 3 insertions(+), 0 deletions(-) create mode 100644 README -Now you’ve created your first commit! You can see that the commit has given you some output about itself: which branch you committed to (master), what SHA-1 checksum the commit has (`463dc4f`), how many files were changed, and statistics about lines added and removed in the commit. +مبروك، لقد قمت بعمل أول commit لك! يعطيك خرج العملية معلومات عنها: في أي فرع branch تم الإعتماد (هنا master)، ما قيمة هاش SHA-1 الخاصة بالعملية ( هنا `463dc4f`)، عدد الملفات التي تغيّرت، بالإضافة إلى إحصاءات حول الأسطر التي أضيفت وأزيلت في هذه العملية. -Remember that the commit records the snapshot you set up in your staging area. Anything you didn’t stage is still sitting there modified; you can do another commit to add it to your history. Every time you perform a commit, you’re recording a snapshot of your project that you can revert to or compare to later. +تذكر أنّ عملية commit تأخذ صورة عن الملفات في قائمة staged. أي شيء لم تقم بإضافته إلى هذه القائمة ما زال في مجلد العمل بحالة "معدل" modified؛ يمكنك القيام بإضافتهم من خلال عملية commit جديدة إلى التأريخ في git. نستنتج أنّه في كل عملية commit يقوم git بأخذ "صورة" snapshot عن المشروع يمكننا العودة لها لاحقاً أو مقارنتها أو غير ذلك.. -### Skipping the Staging Area ### +### تجاوز منطقة التجهيز Staging Area ### -Although it can be amazingly useful for crafting commits exactly how you want them, the staging area is sometimes a bit more complex than you need in your workflow. If you want to skip the staging area, Git provides a simple shortcut. Providing the `-a` option to the `git commit` command makes Git automatically stage every file that is already tracked before doing the commit, letting you skip the `git add` part: +منطقة التجهيز تكون أحياناً معقدة أكثر مما تحتاج في عملك إلا أنّها مفيدة لعمل commits تماماً كما تودهم أن يكونوا. إذا أردت تجاوز منطقة التجهيز، يوفر git اختصاراً بسيطاً لذلك. باستخدام الأمر `git commit -a` يقوم git بإضافة الملفات المتتبعة إلى منطقة التجهيز بشكل تلقائي، كأنك قمت بعمل `git add`: $ git status # On branch master @@ -339,13 +337,13 @@ Although it can be amazingly useful for crafting commits exactly how you want th [master 83e38c7] added new benchmarks 1 files changed, 5 insertions(+), 0 deletions(-) -Notice how you don’t have to run `git add` on the benchmarks.rb file in this case before you commit. +لاحظ بأنك لاتحتاج إلى تنفيذ الأمر `git add` على ملف benchmark.rb قبل القيام بعملية commit. -### Removing Files ### +### إزالة الملفات ### -To remove a file from Git, you have to remove it from your tracked files (more accurately, remove it from your staging area) and then commit. The `git rm` command does that and also removes the file from your working directory so you don’t see it as an untracked file next time around. +لحذف ملف من git، يجب عليك إزالته من قائمة الملفات المتتبعة (وبشكل أدق، إزالته من منطقة التجهيز) ومن ثم القيام بعملية commit. الأمر `git rm` يقوم بعمل ذلك كما يقوم بحذف الملف من مجلد العمل الخاص بك لذا لن تراه بعد الآن في قائمة الملفات غير المتتبعة في المرة المقبلة. -If you simply remove the file from your working directory, it shows up under the “Changes not staged for commit” (that is, _unstaged_) area of your `git status` output: +إذا قمت بإزالة الملف من مجلد العمل، يظهر تحت بند "تعديلات غير مجهزة للاعتماد" (أي _unstaged_) من خرج الأمر `git status`: $ rm grit.gemspec $ git status @@ -357,7 +355,7 @@ If you simply remove the file from your working directory, it shows up under the # deleted: grit.gemspec # -Then, if you run `git rm`, it stages the file’s removal: +فإذا قمت بتنفيذ أمر `git rm` يقوم بتجهيز عملية الحذف ليتم اعتمادها: $ git rm grit.gemspec rm 'grit.gemspec' @@ -370,31 +368,31 @@ Then, if you run `git rm`, it stages the file’s removal: # 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. +وفي المرة المقبلة التي ستقوم فيها بعمل commit، سيتم إزالة الملف من قائمة التتبع. إذا قمت مسبقاً بتعديل الملف وإضفته إلى الفهرس، يجب عليه تنفيذ عملية الحذف قسرياً وذلك بإضافة الخيار `-f`. يتم اتباع هذه الطريقة بغية حماية البيانات من أية عمليات حذف "عرضية" لملفات لم يتم تسجيلها ضمن git ولايمكن استعادتها بعد ذلك. -Another useful thing you may want to do is to keep the file in your working tree but remove it from your staging area. In other words, you may want to keep the file on your hard drive but not have Git track it anymore. This is particularly useful if you forgot to add something to your `.gitignore` file and accidentally added it, like a large log file or a bunch of `.a` compiled files. To do this, use the `--cached` option: +أما إذا أردت إزالة الملف من منطقة التجهيز مع الحفاظ عليه في مجلد العمل (أي إزالته من تتبع git مع بقاءه على وسيطة التخزين) - وهو شيء مفيد إذا قمت بنسيان إضافة شيء ما إلى ملف `.gitignore` وأضفته عن طريق الخطأ ؛ كملف log كبير مثلاً - استخدم الخيار `--cached` مع الأمر `git rm` كالتالي: $ git rm --cached readme.txt -You can pass files, directories, and file-glob patterns to the `git rm` command. That means you can do things such as +يمكنك تمرير أسماء ملفات، مجلدات، وأنماط glob للأمر `git rm`. وهذا يعني بأنه يمكننا عمل أشياء كالتالي: $ git rm log/\*.log -Note the backslash (`\`) in front of the `*`. This is necessary because Git does its own filename expansion in addition to your shell’s filename expansion. This command removes all files that have the `.log` extension in the `log/` directory. Or, you can do something like this: +لاحظ الشرطة العكسية (`\`) قبل رمز النجمة `*`. إنّها ضرورية لأن git يقوم بعمل توسعة الأسماء الخاصة به بالإضافة إلى التوسعة الخاصة بسطر الأوامر. هذا الأمر يقوم بحذف كافة الملفات التي تملك اللاحقة `.log` في مجلد `/log`. أو يمكنك عمل شيء كالتالي: $ git rm \*~ -This command removes all files that end with `~`. +وهذا الأمر يقوم بحذف كافة الملفات المنتهية بالمحرف `~`. -### Moving Files ### +### نقل الملفات ### -Unlike many other VCS systems, Git doesn’t explicitly track file movement. If you rename a file in Git, no metadata is stored in Git that tells it you renamed the file. However, Git is pretty smart about figuring that out after the fact — we’ll deal with detecting file movement a bit later. +على خلاف أغلب أنظمة إدارة الإصدارات VCS الأخرى، لا يقوم git بتعقب حركة الملفات بشكل صريح. إذا قمت بإعادة تسمية ملف ضمن git، لايتم تسجيل أي بيانات وصفية metadata في git تقوم بأنك قمت بإعادة تسمية الملف. لكن، git ذكي جداً في استعياب ذلك - وسنقوم بمناقشة الأمر بعد قليل. -Thus it’s a bit confusing that Git has a `mv` command. If you want to rename a file in Git, you can run something like +إذا أردت القيام بإعادة تسمية ملف يمكنك استخدام أمر `mv` في git كالتالي: $ git mv file_from file_to -and it works fine. In fact, if you run something like this and look at the status, you’ll see that Git considers it a renamed file: +إذا قمنا بتنفيذ الأمر والنظر إلى خرج أمر `git status`: $ git mv README.txt README $ git status @@ -407,23 +405,23 @@ and it works fine. In fact, if you run something like this and look at the statu # renamed: README.txt -> README # -However, this is equivalent to running something like this: +وهو مكافئ للقيام بتنفيذ الأوامر التالي على التسلسل: $ mv README.txt README $ git rm README.txt $ git add README -Git figures out that it’s a rename implicitly, so it doesn’t matter if you rename a file that way or with the `mv` command. The only real difference is that `mv` is one command instead of three — it’s a convenience function. More important, you can use any tool you like to rename a file, and address the add/rm later, before you commit. +يدرك git بأنك قمت بعملية إعادة تسمية، لذا فالإختلاف الوحيد بين الطريقتين هو أنّ `git mv` عبارة عن أمر واحد، وليس ثلاثة أوامر. يمكن الاستفادة من هذه الخاصة باستخدام أية أدوات للقيام بعمليات إعادة التسمية، واستخدام add/rm قبل القيام بعملية commit. -## Viewing the Commit History ## +## مراجعة تأريخ عمليات commit ## -After you have created several commits, or if you have cloned a repository with an existing commit history, you’ll probably want to look back to see what has happened. The most basic and powerful tool to do this is the `git log` command. +بعد قيامك بعدد من عمليات الاعتماد commit، أو استنساخ repository بسجل تأريخ، ربما ستود إلقاء نظرة على ما جرى. أبسط وأقوى أداة لعمل ذلك هي الأمر `git log`. -These examples use a very simple project called simplegit that I often use for demonstrations. To get the project, run +هذه الأمثلة تستخدم مشروع بسيط جداً يدعى simplegit أقوم باستخدامه في عمليات العرض بأغلب الأحيان. للحصول على المشروع قم باستنساخه عن موقع github كالتالي: git clone git://github.com/schacon/simplegit-progit.git -When you run `git log` in this project, you should get output that looks something like this: +عندما تقوم بعمل `git log` ضمن المشروع، سيظهر لديك خرج مشابه للتالي: $ git log commit ca82a6dff817ec66f44342007202690a93763949 @@ -444,11 +442,11 @@ When you run `git log` in this project, you should get output that looks somethi first commit -By default, with no arguments, `git log` lists the commits made in that repository in reverse chronological order. That is, the most recent commits show up first. As you can see, this command lists each commit with its SHA-1 checksum, the author’s name and e-mail, the date written, and the commit message. +بتنفيذ الأمر بدون بارمترات، يقوم git بعرض عمليات commit في repository بترتيب زمني معكوس - من الأحدث إلى الأقدم. كما يقوم بعرض بجانب كل commit هاش SHA-1 checksum الخاص بها، اسم وبريد الكاتب الإلكتروني، تاريخ الاعتماد، ورسالة الاعتماد. -A huge number and variety of options to the `git log` command are available to show you exactly what you’re looking for. Here, we’ll show you some of the most-used options. +يمكن إرفاق الأمر `git log` بعدد كبير من الخيارات للحصول على المعلومات التي نريدها بالضبط.. تجد في الأسفل مثالاً عن أكثر الخيارات استخداماً. -One of the more helpful options is `-p`, which shows the diff introduced in each commit. You can also use `-2`, which limits the output to only the last two entries: +أحد أهم الخيارات هو `-p`، والذي يقوم بإظهار الفوارق المستحدثة بين عمليات commit المختلفة. يمكن أيضاً استخدام الخيار `-2` ليحد خرج النتيجة إلى آخر عمليتين: $ git log –p -2 commit ca82a6dff817ec66f44342007202690a93763949 @@ -488,8 +486,7 @@ One of the more helpful options is `-p`, which shows the diff introduced in each -end \ No newline at end of file -This option displays the same information but with a diff directly following each entry. This is very helpful for code review or to quickly browse what happened during a series of commits that a collaborator has added. -You can also use a series of summarizing options with `git log`. For example, if you want to see some abbreviated stats for each commit, you can use the `--stat` option: +هذا الخيار يعرض نفس المعلومات بالإضافة خرج diff بعده مباشرة. فهو مهم جداً من أجل مراجعة الكود واستعراض ما الذي تغير بشكل سريع ضمن سلسلة من عمليات commit. يمكنك أيضاً استخدام خيارات للتلخيص مع أمر `git log`. على سبيل المثال، إذا أردت رؤية بعض الإحصاءات المختصرة لكل commit، يمكنك استخدام الخيار `stat`: $ git log --stat commit ca82a6dff817ec66f44342007202690a93763949 @@ -521,43 +518,43 @@ You can also use a series of summarizing options with `git log`. For example, if lib/simplegit.rb | 25 +++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 0 deletions(-) -As you can see, the `--stat` option prints below each commit entry a list of modified files, how many files were changed, and how many lines in those files were added and removed. It also puts a summary of the information at the end. -Another really useful option is `--pretty`. This option changes the log output to formats other than the default. A few prebuilt options are available for you to use. The oneline option prints each commit on a single line, which is useful if you’re looking at a lot of commits. In addition, the `short`, `full`, and `fuller` options show the output in roughly the same format but with less or more information, respectively: +كما ترى باستخدام الخيار `--stat` يتم عرض قائمة من الملفات المعدلة، عدد الملفات التي تغيرت، وعدد الأسطر التي أضيفت أو أزيلت. كما يضع ملخصاً للمعلومات في النهاية. +يوجد خيار مفيد آخر وهو `--pretty`. هذا الخيار يغير خرج السل إلى صيغ غير الافتراضية. يوجد بعضها مركب مسبقاً. مثلاً `oneline` يقوم بطباعة كل commit على سطر لوحدها، وهذا أمر مفيد في حال كنت تنظر إلى العديد من عمليات commit. بالإضافة إلى `short`، `full` و `fuller` والتي تعرض خرجاً تقريباً بنفس الصيغة مع معلومات أكثر أو أقل: $ git log --pretty=oneline ca82a6dff817ec66f44342007202690a93763949 changed the version number 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code a11bef06a3f659402fe7563abf99ad00de2209e6 first commit -The most interesting option is `format`, which allows you to specify your own log output format. This is especially useful when you’re generating output for machine parsing — because you specify the format explicitly, you know it won’t change with updates to Git: +أكثر الخيارات أهمية هو `format`، والذي يسمح لك بتحديد صيغة الخرج بشكل صريح بما يتناسب مع إعرابها آلياً - حيث أنك تعرف أنّه لن يتغير عند التحديث إلى git: $ git log --pretty=format:"%h - %an, %ar : %s" ca82a6d - Scott Chacon, 11 months ago : changed the version number 085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code a11bef0 - Scott Chacon, 11 months ago : first commit -Table 2-1 lists some of the more useful options that format takes. - - Option Description of Output - %H Commit hash - %h Abbreviated commit hash - %T Tree hash - %t Abbreviated tree hash - %P Parent hashes - %p Abbreviated parent hashes - %an Author name - %ae Author e-mail - %ad Author date (format respects the –date= option) - %ar Author date, relative - %cn Committer name - %ce Committer email - %cd Committer date - %cr Committer date, relative - %s Subject - -You may be wondering what the difference is between _author_ and _committer_. The author is the person who originally wrote the work, whereas the committer is the person who last applied the work. So, if you send in a patch to a project and one of the core members applies the patch, both of you get credit — you as the author and the core member as the committer. We’ll cover this distinction a bit more in Chapter 5. - -The oneline and format options are particularly useful with another `log` option called `--graph`. This option adds a nice little ASCII graph showing your branch and merge history, which we can see our copy of the Grit project repository: +الجدول 2-1 يعرض بعض الخيارات المفيدة التي يمكن إضافتها إلى الصيغة. + + الخيار وصف الخرج + %H Commit هاش + %h الهاش الاعتمادي المختصر + %T هاش الشجرة + %t هاش الشجرة المختصر + %P هاشات الوالد + %p هاشات الوالد المختصرة + %an اسم الكاتب + %ae بريد الكاتب الإلكتروني + %ad تاريخ الكاتب (يراعي الصيغة –date= option) + %ar تاريخ الكاتب - نسبياً + %cn اسم منفذ الاعتماد + %ce بريد منفذ الاعتماد الإلكتروني + %cd تاريخ منفذ الاعتماد + %cr تاريخ منفذ الاعتماد - نسبياً + %s العنوان + +قد تتسائل عن الاختلاف بين _الكاتب_ AUTHOR و _منفذ الاعتماد_ COMMITTER. الكاتب هو الشخص الذي كتب العمل بداية، بينما منفذ الاعتماد هو آخر شخص طبق العمل. لذا، إذا أرسلت باتشاً إلى مشروع وأحد المطورين الرئيسين قام بتطبيق الباتش، تأخذان كلاكما الاعتمادية - أنت ككاتب وهو كمنفذ اعتماد. + +وتكون هذه الخيارات مفيدة أكثر بالترافق مع الخيار `--graph`. حيث يضيف هذا الأمر غراف ASCII بسيط يوضح تأريخ الأفرع و الدمج، لاحظ التالي: $ git log --pretty=format:"%h %s" --graph * 2d3acf9 ignore errors from SIGCHLD on trap @@ -571,43 +568,43 @@ The oneline and format options are particularly useful with another `log` option * d6016bc require time for xmlschema * 11d191e Merge branch 'defunkt' into local -Those are only some simple output-formatting options to `git log` — there are many more. Table 2-2 lists the options we’ve covered so far and some other common formatting options that may be useful, along with how they change the output of the log command. +يوجد مجموعة من الخيارات البسيطة مع أمر `git log`. يوضح الجدول 2-2 قائمة من الخيارات التي قمنا بتغطيتها حتى الآن وبعض صيغ التنسيق الشائعة والتي قد تكون مفيدة، وبجانبها شرح مبسط عن التغيير الذي تجريه على الخرج. - Option Description - -p Show the patch introduced with each commit. - --stat Show statistics for files modified in each commit. + الخيار الوصف + -p يظهر الباتش المدخل مع كل عملية commit. + --stat يظهر إحصاءات حول التعديلات التي حصلت على الملفات مع كل عملية commit. --shortstat Display only the changed/insertions/deletions line from the --stat command. - --name-only Show the list of files modified after the commit information. - --name-status Show the list of files affected with added/modified/deleted information as well. - --abbrev-commit Show only the first few characters of the SHA-1 checksum instead of all 40. + --name-only يظهر قائمة الملفات المعدلة. + --name-status يظهر قائمة الملفات المعدلة عن طريق الإضافة والحذف وغير ذلك. + --abbrev-commit يظهر أول مجموعة من هاش SHA-1 بدلاً عن كامل الأحرف 40. --relative-date Display the date in a relative format (for example, “2 weeks ago”) instead of using the full date format. - --graph Display an ASCII graph of the branch and merge history beside the log output. + --graph عرض غراف ASCII مع الخرج يظهر عمليات التفريع و الدمج. --pretty Show commits in an alternate format. Options include oneline, short, full, fuller, and format (where you specify your own format). -### Limiting Log Output ### +### تحديد خرج السجل ### -In addition to output-formatting options, git log takes a number of useful limiting options — that is, options that let you show only a subset of commits. You’ve seen one such option already — the `-2` option, which show only the last two commits. In fact, you can do `-`, where `n` is any integer to show the last `n` commits. In reality, you’re unlikely to use that often, because Git by default pipes all output through a pager so you see only one page of log output at a time. +بالإضافة تحديد شكل الخرج، يسمح git بأخذ مجموعة جزئية فقط من الخرج. وقد قمت بمشاهدة ذلك مسبقاً - الخيار `-2` المستخدم لعرض آخر عمليتي commit. في الواقع يمكنك استخدام `-` حيث `n` هي عدد صحيح لعرض آخر `n` عملية commit. في الحقيقة، لن تستخدمها على الغالب، لأن git يقوم بتمرير كامل الخرج لبرنامج تصفح لتتمكن من تصفح عمليات commit صفحة صفحة. -However, the time-limiting options such as `--since` and `--until` are very useful. For example, this command gets the list of commits made in the last two weeks: +من الخيارات الهامة جداً، المحددات الزمنية مثل `--since` و `--until`. على سبيل المثال، هذا الأمر يعطيك قائمة بعمليات commit التي حصلت في آخر أسبوعين: $ git log --since=2.weeks -This command works with lots of formats — you can specify a specific date (“2008-01-15”) or a relative date such as “2 years 1 day 3 minutes ago”. +ويعمل هذا الأمر مع أنواع كثيرة من الصيغ - يمكنك تحديد تاريخ محدد ("2008-01-15") أو تاريخ نسبي مثل "2 years 1 day 3 minutes ago". -You can also filter the list to commits that match some search criteria. The `--author` option allows you to filter on a specific author, and the `--grep` option lets you search for keywords in the commit messages. (Note that if you want to specify both author and grep options, you have to add `--all-match` or the command will match commits with either.) +يكطمط أيضاً تصفية قائمة عمليات commit من خلال محددات البحث. مثلاً خيار `--author` يقوم بتصفية النتائج وفق كاتب محدد، و `--grep` يقوم بالفلترة عن طريق كلمة مفتاحية. (لاحظ أنّه إذا قمت بإضافة خياراي author و grep، يجب عليك إضافة الخيار `--all-match` أو سيقوم git بعمل مطابقة مع أحدهما فقط). -The last really useful option to pass to `git log` as a filter is a path. If you specify a directory or file name, you can limit the log output to commits that introduced a change to those files. This is always the last option and is generally preceded by double dashes (`--`) to separate the paths from the options. +آخر الخيارات الهامة التي يمكن تمريرها إلى الأمر `git log` كمصناف هي المسار. إذا قمت بتحديد مجلد أو اسم ملف، يمكنك تحديد الخرج إلى عمليات commit التي آثرت في هذا المسار. ودائماً ما يكون آخر خيار يوضع في `log` ويسبق بداشين double dashes (`--`) ليفصل المسارات عن الخيارات. -In Table 2-3 we’ll list these and a few other common options for your reference. +في الجدول 2-3 - نعرض الخيارات التي يمكن إضافتها مع log. - Option Description - -(n) Show only the last n commits - --since, --after Limit the commits to those made after the specified date. - --until, --before Limit the commits to those made before the specified date. - --author Only show commits in which the author entry matches the specified string. - --committer Only show commits in which the committer entry matches the specified string. + خيار وصف + -(n) يظهر آن n عملية commit. + --since, --after تحديد عمليات commit بعد التاريخ الذي يتلوها. + --until, --before تحديد عمليات commit حتى التاريخ الذي يتلوها. + --author فقط أظهر عمليات commit التابعة لهذا الكاتب. + --committer فقط أظهر عمليات commit التابعة لهذا المعتمد. -For example, if you want to see which commits modifying test files in the Git source code history were committed by Junio Hamano and were not merges in the month of October 2008, you can run something like this: +على سبيل المثال، إذا أردت رؤية أي عمليات commit عدلت ملفات الاختبار في تأريخ الكود المصدري والتي قام Junio Hamano بعملها ولم يتم دمجها في شهر أوكتوبر 2008، يمكن كتابة هذا الأمر: $ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \ --before="2008-11-01" --no-merges -- t/ @@ -618,7 +615,7 @@ For example, if you want to see which commits modifying test files in the Git so 51a94af - Fix "checkout --track -b newbranch" on detac b0ad11e - pull: allow "git pull origin $something:$cur -Of the nearly 20,000 commits in the Git source code history, this command shows the 6 that match those criteria. +من بين 20 ألف عملية commit تقريباً في تأريخ git الخاص بهذا الكود المصدري، أظهر الأمر فقط عمليات الاعتماد الستة المطابقة لمحددات البحث. ### Using a GUI to Visualize History ### diff --git a/az/01-introduction/01-chapter1.markdown b/az/01-introduction/01-chapter1.markdown index e45515bdd..d2cea2626 100644 --- a/az/01-introduction/01-chapter1.markdown +++ b/az/01-introduction/01-chapter1.markdown @@ -1,43 +1,43 @@ # Başlanğıc # -Bu bölmə size git haqqında başlıca məlumatları çattırmağı hədəfləyir. We will begin at the beginning by explaining some background on version control tools, then move on to how to get Git running on your system and finally how to get it setup to start working with. At the end of this chapter you should understand why Git is around, why you should use it and you should be all setup to do so. +Bu bölmə size git haqqında başlıca məlumatları çattırmağı hədəfləyir. İşə başlamazdan əvvəl version nəzarət vasitəsinin bəzi fon məlumatlarını açıqlayaraq başlayacağıq, daha sonra Git quraşdırılmanının necə ediləcəyini, ən son olaraq da vasitənin konfiqurasiya və istifadəsini açıqlayacağıq. Bu hissənin sonunda Git'in varlıq səbəbini və niyə onu istifadə etməniz lazım olduğunu anlayacaq, Git'i istifadə etmeye başlamaq üçün quraşdırma bitirmiş olacaqsınız. -## About Version Control ## +## Versiya Nəzarət Haqqında ## -What is version control, and why should you care? Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later. Even though the examples in this book show software source code as the files under version control, in reality any type of file on a computer can be placed under version control. +Versiya nəzarəti nədir və nə işə yarayar? Versiya nəzarəti, Bir ya da daha çox fayl üzərində edilən dəyişiklikləri yazan və daha sonra müəyyən bir distributivə geri dönə bilmənizi təmin edən bir sistemdir. Bu kitabdakı nümunələrdə proqram qaynaq kod fayllarının versiya idarəsini edəcəksiniz, nə var ki, əslində versiyası idarəsini demək olar ki hər növdən fayl üçün istifadə edə bilərsiniz. -If you are a graphic or web designer and want to keep every version of an image or layout (which you certainly would), it is very wise to use a Version Control System (VCS). A VCS allows you to: revert files back to a previous state, revert the entire project back to a previous state, compare changes over time, see who last modified something that might be causing a problem, who introduced an issue and when, and more. Using a VCS also means that if you screw things up or lose files, you can generally recover easily. In addition, you get all this for very little overhead. +Bir grafik və ya web dizayn tək və bir vizual və ya dizaynın dəyişik versiyalarını qorumaq istəyirsinizsə (ki ehtimalla bunu etmək istəyərsiniz), bir Versiya Nəzarət Sistemi (VNS) istifadə etməniz çox ağıllıca olacaq. VNS, faylların və ya bütün layihənin keçmişdəki müəyyən bir versiyaya daxil olmağa, zaman içində edilən dəyişiklikləri müqayisə etməyinizi, problemə səbəb olan şeydə ən son kimin dəyişiklik etdiyini, müəyyən bir səhvi kimin, nə vaxt sistemə daxil etdiyini və daha başqa bir çox şeyi görə bilməyinizi təmin edər. Digər tərəfdən, VNS istifadə etmək, bir səhv etdikdə və ya bəzi faylları səhvən sildiyiniz də vəziyyəti asanlıqla kompensasiya etmənizə köməkçi olar. Üstəlik, bütün bunlar sizə əhəmiyyətli bir əlavə yük də gətirməz. -### Local Version Control Systems ### +### Lokal Sürüm Nəzarət Sistemləri ### -Many people’s version-control method of choice is to copy files into another directory (perhaps a time-stamped directory, if they’re clever). This approach is very common because it is so simple, but it is also incredibly error prone. It is easy to forget which directory you’re in and accidentally write to the wrong file or copy over files you don’t mean to. +Əksəriyyəti faylları bir qovluğa (ağılları başlarındaysa tarix və zaman məlumatını də daxil olmaqla bir qovluğa) kopiyalayaraq versiyas nəzarətini etməyi seçər. Bu yanaşma çox məşhurdur, çünki çox asandır; amma eyni zamanda səhvlərə də ala bildiyinə açıqdır. Hansı qovluqda olduğunuzu unudub səhv fayla yaza ya da istəmədiyiniz faylların üstünə kopiyalama edə bilərsiniz. -To deal with this issue, programmers long ago developed local VCSs that had a simple database that kept all the changes to files under revision control (see Figure 1-1). +Bu problemlə baş edə bilmək üçün, proqramçılar uzun zaman əvvəl, fayllardakı bütün dəyişiklikləri versiya nəzarətinə alan sadə bir veri bazasına sahib olan lokal VNS'leri inkişaf etdirdilər (bax Göstərici 1-1). Insert 18333fig0101.png -Figure 1-1. Local version control diagram. +Göstərici 1-1. Lokal Sürüm Nəzarət diaqramı. -One of the more popular VCS tools was a system called rcs, which is still distributed with many computers today. Even the popular Mac OS X operating system includes the rcs command when you install the Developer Tools. This tool basically works by keeping patch sets (that is, the differences between files) from one change to another in a special format on disk; it can then re-create what any file looked like at any point in time by adding up all the patches. +Ən məşhur VNS vasitələrindən biri, bu gün hələ çox kompüterə yüklenmiş olaraq yayılan, RCS adında bir sistem idi. Məşhur Mac OS X əməliyyat sistemi belə, Developer Tools'u yüklediğinizde, RCS əmrini qurmaqdadır. Bu vasitə, iki versiyası arasındakı yamaqları (yəni, fayllar arasındakı fərqləri) xüsusi bir şəkildə diskə yazar; daha sonra, bu yamaqları bir-birinə əlavə, bir faylın müəyyən bir distributivdəki görünüşünü yenidən meydana gətirər. -### Centralized Version Control Systems ### +### Mərkəzi Versiya Nəzarət Sistemləri ### -The next major issue that people encounter is that they need to collaborate with developers on other systems. To deal with this problem, Centralized Version Control Systems (CVCSs) were developed. These systems, such as CVS, Subversion, and Perforce, have a single server that contains all the versioned files, and a number of clients that check out files from that central place. For many years, this has been the standard for version control (see Figure 1-2). +İnsanların qarşılaşdığı ikinci böyük problem, başqa sistemlərdəki proqramçılar ilə birlikdə iş ehtiyacından irəli gəlir. Bu problemlə başa çıxa bilmək üçün, Mərkəzi Versiya Nəzarət Sistemləri (MVNS) inkişaf etdirilmişdir. Bu sistemlər, məsələn CVS, Subversion və Perforce, versiyası idarəsinə alınan bütün faylları tutan bir server və bu serverdən faylları seçərək alan (check out) alıcını meydana gələr. Bu üsul, illərcə, versiyası idarəsində standart üsul olaraq qəbul gördü (bax Göstərici 1-2). Insert 18333fig0102.png -Figure 1-2. Centralized version control diagram. +Göstərici 1-2. Mərkəzi Versiya Nəzarət diaqramı. -This setup offers many advantages, especially over local VCSs. For example, everyone knows to a certain degree what everyone else on the project is doing. Administrators have fine-grained control over who can do what; and it’s far easier to administer a CVCS than it is to deal with local databases on every client. +Bu üsulun, xüsusilə lokal VNS lere görə, çox sayda üstünlüyü vardır. Məsələn, bir projedeki hər kəs, digərlərinin nə etdiyindən müəyyən ölçüdə xəbərdardır. Sistem idarəçiləri kimin hansı səlahiyyətlərə sahib olacağını olduqca detallı şəkildə təşkil; üstəlik bir MVNS'yi idarə, hər alıcını ayrı-ayrı heyəti olan yerli bazalarını idarə görə çox daha asandır. -However, this setup also has some serious downsides. The most obvious is the single point of failure that the centralized server represents. If that server goes down for an hour, then during that hour nobody can collaborate at all or save versioned changes to anything they’re working on. If the hard disk the central database is on becomes corrupted, and proper backups haven’t been kept, you lose absolutely everything—the entire history of the project except whatever single snapshots people happen to have on their local machines. Local VCS systems suffer from this same problem—whenever you have the entire history of the project in a single place, you risk losing everything. +Nə var ki, bu üsulun də ciddi bəzi çətinlikləri vardır. Ən aşkar çətinlik, mərkəzi serverin işləməməsi vəziyyətində ortaya çıxacaq qırılma nöqtəsi problemidir. Server bir saatlığına çökəcək olsa, o bir saat boyunca istifadəçilərin işlərini sistemə köçürmələri ya da çalışdıqları şeylərin sürümlenmiş surətlərini saxlamaq mümkün olmayacaq. Mərkəzi bazanın sabit diski pozulacaq olsa, ehtiyyat da olması lazım olduğu kimi edilməmişsə, əlinizdəki hər şeyi -projenin, istifadəçilərin kompüterlərində qalan lokal yaddaş kopiyaları (snapshot) xaricindəki bütün tarihçesini- itirərsiniz. Yerli VNS'ler də bu problemdən çəkir -projenin bütün tarixçəsini tək bir yerdə tutduğunuz müddətcə hər şeyi itirmə riskiniz var. -### Distributed Version Control Systems ### +### Paylanmış Versiya Nəzarət Sistemləri ### -This is where Distributed Version Control Systems (DVCSs) step in. In a DVCS (such as Git, Mercurial, Bazaar or Darcs), clients don’t just check out the latest snapshot of the files: they fully mirror the repository. Thus if any server dies, and these systems were collaborating via it, any of the client repositories can be copied back up to the server to restore it. Every checkout is really a full backup of all the data (see Figure 1-3). +Bu nöqtədə Paylanmış Versiya Nəzarət Sistemləri (PVNS) dövrəyə girər. Bir PVNS'de (Git, Mercurial, Bazaar ya da Darcs nümunələrində olduğu kimi), müştərilər (istifadəçilər) faylların yalnız ən son yaddaş surətlərini almaqla qalmazlar: proqram hovuzunu (repository) tamamilə yansılalar (kopyalarlar).Beləcə, serverlərdən biri çöksə, və o server üzərindən ortaq iş icra edən sistemlər varsa, alıcını birinin proqram hovuzu serverə geri yüklənərək sistem qurtarıla bilər. Hər seçmə (checkout) əməliyyatı əsasında bütün məlumatın yedeklenmesiyle nəticələnər(bax Göstərici 1-3). Insert 18333fig0103.png -Figure 1-3. Distributed version control diagram. +Göstərici 1-3. Paylanmış Versiya Nəzarət diaqramı. -Furthermore, many of these systems deal pretty well with having several remote repositories they can work with, so you can collaborate with different groups of people in different ways simultaneously within the same project. This allows you to set up several types of workflows that aren’t possible in centralized systems, such as hierarchical models. +Dahası, bu sistemlerden çoğu birden çok uzak uçbirimdeki yazılım havuzuyla rahatlıkla çalışır, böylece, aynı proje için aynı anda farklı insan topluluklarıyla farklı biçimlerde ortak çalışmalar yürütebilirsiniz. Bu, birden çok iş akışı ile çalışabilmenizi sağlar, ki bu merkezi sistemlerde (hiyerarşik modeller gibi) mümkün değildir. ## A Short History of Git ## @@ -161,9 +161,9 @@ Or if you’re on a Debian-based distribution like Ubuntu, try apt-get: ### Installing on Mac ### -There are two easy ways to install Git on a Mac. The easiest is to use the graphical Git installer, which you can download from the Google Code page (see Figure 1-7): +There are two easy ways to install Git on a Mac. The easiest is to use the graphical Git installer, which you can download from the SourceForge page (see Figure 1-7): - http://code.google.com/p/git-osx-installer + http://sourceforge.net/projects/git-osx-installer/ Insert 18333fig0107.png Figure 1-7. Git OS X installer. diff --git a/az/02-git-basics/01-chapter2.markdown b/az/02-git-basics/01-chapter2.markdown index 4e177b56a..7f405674a 100644 --- a/az/02-git-basics/01-chapter2.markdown +++ b/az/02-git-basics/01-chapter2.markdown @@ -55,7 +55,7 @@ The main tool you use to determine which files are in which state is the `git st $ git status # On branch master - nothing to commit (working directory clean) + nothing to commit, working directory clean This means you have a clean working directory — in other words, there are no tracked and modified files. 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. diff --git a/az/04-git-server/01-chapter4.markdown b/az/04-git-server/01-chapter4.markdown index 1e4df37b1..c51b6a74d 100644 --- a/az/04-git-server/01-chapter4.markdown +++ b/az/04-git-server/01-chapter4.markdown @@ -738,7 +738,7 @@ GitHub is also a commercial company that charges for accounts that maintain priv ### Setting Up a User Account ### -The first thing you need to do is set up a free user account. If you visit the Pricing and Signup page at `http://github.com/plans` and click the "Sign Up" button on the Free account (see figure 4-2), you’re taken to the signup page. +The first thing you need to do is set up a free user account. If you visit the "Plans and pricing" page at `https://github.com/pricing` and click the "Sign Up" button on the Free account (see figure 4-2), you’re taken to the signup page. Insert 18333fig0402.png Figure 4-2. The GitHub plan page. diff --git a/az/06-git-tools/01-chapter6.markdown b/az/06-git-tools/01-chapter6.markdown index 550699d2d..ccf9797c0 100644 --- a/az/06-git-tools/01-chapter6.markdown +++ b/az/06-git-tools/01-chapter6.markdown @@ -59,7 +59,7 @@ A lot of people become concerned at some point that they will, by random happens If you do happen to commit an object that hashes to the same SHA-1 value as a previous object in your repository, Git will see the previous object already in your Git database and assume it was already written. If you try to check out that object again at some point, you’ll always get the data of the first object. -However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160 bits. The number of randomly hashed objects needed to ensure a 50% probability of a single collision is about 2^80 (the formula for determining collision probability is `p = (n(n-1)/2) * (1/2^160))`. 2^80 is 1.2 x 10^24 or 1 million billion billion. That’s 1,200 times the number of grains of sand on the earth. +However, you should be aware of how ridiculously unlikely this scenario is. The SHA-1 digest is 20 bytes or 160 bits. The number of randomly hashed objects needed to ensure a 50% probability of a single collision is about 2^80 (the formula for determining collision probability is `p = (n(n-1)/2) * (1/2^160)`). 2^80 is 1.2 x 10^24 or 1 million billion billion. That’s 1,200 times the number of grains of sand on the earth. Here’s an example to give you an idea of what it would take to get a SHA-1 collision. If all 6.5 billion humans on Earth were programming, and every second, each one was producing code that was the equivalent of the entire Linux kernel history (1 million Git objects) and pushing it into one enormous Git repository, it would take 5 years until that repository contained enough objects to have a 50% probability of a single SHA-1 object collision. A higher probability exists that every member of your programming team will be attacked and killed by wolves in unrelated incidents on the same night. @@ -440,7 +440,7 @@ Your working directory is clean: $ git status # On branch master - nothing to commit (working directory clean) + nothing to commit, working directory clean At this point, you can easily switch branches and do work elsewhere; your changes are stored on your stack. To see which stashes you’ve stored, you can use `git stash list`: @@ -501,7 +501,7 @@ Again, if you don’t specify a stash, Git assumes the most recent stash: You may want to create an alias and effectively add a `stash-unapply` command to your git. For example: $ git config --global alias.stash-unapply '!git stash show -p | git apply -R' - $ git stash + $ git stash apply $ #... work work work $ git stash-unapply @@ -1095,7 +1095,7 @@ Now you have the root of the Rack project in your `rack_branch` branch and your $ ls README -You want to pull the Rack project into your `master` project as a subdirectory. You can do that in Git with `git read-tree`. You’ll learn more about `read-tree` and its friends in Chapter 9, but for now know that it reads the root tree of one branch into your current staging area and working directory. You just switched back to your `master` branch, and you pull the `rack` branch into the `rack` subdirectory of your `master` branch of your main project: +You want to pull the Rack project into your `master` project as a subdirectory. You can do that in Git with `git read-tree`. You’ll learn more about `read-tree` and its friends in Chapter 9, but for now know that it reads the root tree of one branch into your current staging area and working directory. You just switched back to your `master` branch, and you pull the `rack_branch` branch into the `rack` subdirectory of your `master` branch of your main project: $ git read-tree --prefix=rack/ -u rack_branch diff --git a/az/07-customizing-git/01-chapter7.markdown b/az/07-customizing-git/01-chapter7.markdown index 41f5dd33f..c2bb85fc1 100644 --- a/az/07-customizing-git/01-chapter7.markdown +++ b/az/07-customizing-git/01-chapter7.markdown @@ -142,7 +142,7 @@ If you want to try this out, P4Merge works on all major platforms, so you should You can download P4Merge here: - http://www.perforce.com/perforce/downloads/component.html + http://www.perforce.com/product/components/perforce-visual-merge-and-diff-tools To begin, you’ll set up external wrapper scripts to run your commands. I’ll use the Mac path for the executable; in other systems, it will be where your `p4merge` binary is installed. Set up a merge wrapper script named `extMerge` that calls your binary with all the arguments provided: diff --git a/az/08-git-and-other-scms/01-chapter8.markdown b/az/08-git-and-other-scms/01-chapter8.markdown index 2465ffaa5..e21879ba3 100644 --- a/az/08-git-and-other-scms/01-chapter8.markdown +++ b/az/08-git-and-other-scms/01-chapter8.markdown @@ -20,7 +20,7 @@ Don’t rewrite your history and try to push again, and don’t push to a parall ### Setting Up ### -To demonstrate this functionality, you need a typical SVN repository that you have write access to. If you want to copy these examples, you’ll have to make a writeable copy of my test repository. In order to do that easily, you can use a tool called `svnsync` that comes with more recent versions of Subversion — it should be distributed with at least 1.4. For these tests, I created a new Subversion repository on Google code that was a partial copy of the `protobuf` project, which is a tool that encodes structured data for network transmission. +To demonstrate this functionality, you need a typical SVN repository that you have write access to. If you want to copy these examples, you’ll have to make a writeable copy of my test repository. In order to do that easily, you can use a tool called `svnsync` that comes with more recent versions of Subversion — it should be distributed with at least 1.4. For these tests, I created a new Subversion repository on SourceForge that was a partial copy of the `protobuf` project, which is a tool that encodes structured data for network transmission. To follow along, you first need to create a new local Subversion repository: diff --git a/be/01-introduction/01-chapter1.markdown b/be/01-introduction/01-chapter1.markdown index 93b2bc5ee..604f912e2 100644 --- a/be/01-introduction/01-chapter1.markdown +++ b/be/01-introduction/01-chapter1.markdown @@ -161,9 +161,9 @@ Insert 18333fig0106.png ### Усталёўка на Mac ### -Ёсць два лёгкіх пуці ўсталёкі Git на Mac. Самы лёгкі - выкарыстаць графічны ўсталёўшчык, які вы можаце спампаваць са старонкі Google Code(гл. Малюнак 1-7): +Ёсць два лёгкіх пуці ўсталёкі Git на Mac. Самы лёгкі - выкарыстаць графічны ўсталёўшчык, які вы можаце спампаваць са старонкі SourceForge(гл. Малюнак 1-7): - http://code.google.com/p/git-osx-installer + http://sourceforge.net/projects/git-osx-installer/ Insert 18333fig0107.png Малюнак 1-7. Усталёўчшык Git на OS X. diff --git a/be/02-git-basics/01-chapter2.markdown b/be/02-git-basics/01-chapter2.markdown index 4767c095a..d1f61ded5 100644 --- a/be/02-git-basics/01-chapter2.markdown +++ b/be/02-git-basics/01-chapter2.markdown @@ -55,7 +55,7 @@ Insert 18333fig0201.png $ git status # On branch master - nothing to commit (working directory clean) + nothing to commit, working directory clean Гэта значыць, што ў вас чысты працоўны каталог, іншымі словамі - адсутнічаюць мадыфікаваныя адсочваемыя файлы. Git таксама не знайшоў якія-небудзь неадсочваемыя файлы, у зваротным выпадку яны былі б пералічаны тут. У канцы каманда паказвае вам на якой ветцы вы знаходзіцеся. This means you have a clean working directory — in other words, there are no tracked and modified files. 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. diff --git a/ca/01-introduction/01-chapter1.markdown b/ca/01-introduction/01-chapter1.markdown index 726af3fb5..1944283d7 100644 --- a/ca/01-introduction/01-chapter1.markdown +++ b/ca/01-introduction/01-chapter1.markdown @@ -4,11 +4,11 @@ Aquest capítol tracta com iniciar-se amb Git. Començarem explicant alguns conc ## Control de Versions ## -What is version control, and why should you care? Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later. For the examples in this book you will use software source code as the files being version controlled, though in reality you can do this with nearly any type of file on a computer. +Que es el control de version i per què t'hauria d'importar? El control de versions es un sitema que registra els canvis a un arxiu o conjunt d'arxius de manera que despres pot recuperar cualsevol de les versions. Tot i que els exemples de control de versions del llibre son codi font, potfer servir gairebe quansevol mena de arxiu per del teu ordinador. -If you are a graphic or web designer and want to keep every version of an image or layout (which you would most certainly want to), a Version Control System (VCS) is a very wise thing to use. It allows you to revert files back to a previous state, revert the entire project back to a previous state, compare changes over time, see who last modified something that might be causing a problem, who introduced an issue and when, and more. Using a VCS also generally means that if you screw things up or lose files, you can easily recover. In addition, you get all this for very little overhead. +Si ets un disenyador gràfic o de pagines web i vols guardar cada escuna de les versions d'una imatge o disenys (que segur que vols) un sitema de control de versions (Version Control System -VCS-) sera una eina acurada. Et permetrà torna al estat anterior dels fitxers, tornar a un punt anterior de tot el projecte, comparà canvis en el proces, saber qui es el darrer a modificat coses que potser estant donant problemes, qui a introduit un tema i quant, i encara més coses. Fer servir VCS vol dir que si la pífias o pot arreglar, generalment. i tot aixo amb pocs costos. -### Local Version Control Systems ### +### Sitemas de control de versions locals ### Many people’s version-control method of choice is to copy files into another directory (perhaps a time-stamped directory, if they’re clever). This approach is very common because it is so simple, but it is also incredibly error prone. It is easy to forget which directory you’re in and accidentally write to the wrong file or copy over files you don’t mean to. @@ -161,9 +161,9 @@ Or if you’re on a Debian-based distribution like Ubuntu, try apt-get: ### Installing on Mac ### -There are two easy ways to install Git on a Mac. The easiest is to use the graphical Git installer, which you can download from the Google Code page (see Figure 1-7): +There are two easy ways to install Git on a Mac. The easiest is to use the graphical Git installer, which you can download from the SourceForge page (see Figure 1-7): - http://code.google.com/p/git-osx-installer + http://sourceforge.net/projects/git-osx-installer/ Insert 18333fig0107.png Figure 1-7. Git OS X installer. diff --git a/cs/01-introduction/01-chapter1.markdown b/cs/01-introduction/01-chapter1.markdown index 44fdd2521..6a29be757 100644 --- a/cs/01-introduction/01-chapter1.markdown +++ b/cs/01-introduction/01-chapter1.markdown @@ -6,7 +6,7 @@ Tato kapitola vám ve stručnosti představí systém Git. Začneme od samého z 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. +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 anglického 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. ### Lokální systémy správy verzí ### @@ -32,16 +32,16 @@ Avšak i tato koncepce má závažné nedostatky. Tímto nejkřiklavějším je ### Distribuované systémy správy verzí ### -V tomto místě přicházejí ke slovu tzv. distribuované systémy správy verzí (DVCS z angl. Distributed Version Control System). V systémech DVCS (např. Git, Mercurial, Bazaar nebo Darcs) uživatelé pouze nestahují nejnovější verzi souborů (tzv. snímek, anglicky snapshot), ale uchovávají kompletní kopii repozitáře (repository). Pokud v takové situaci dojde ke kolapsu serveru, lze jej obnovit zkopírováním repozitáře od libovolného uživatele. Každá lokální kopie (checkout) je plnohodnotnou zálohou všech dat (viz obrázek 1-3). +V tomto místě přicházejí ke slovu tzv. distribuované systémy správy verzí (DVCS z angl. Distributed Version Control System). V systémech DVCS (např. Git, Mercurial, Bazaar nebo Darcs) uživatelé nestahují pouze nejnovější verzi souborů (tzv. snímek, anglicky snapshot), ale uchovávají kompletní kopii repozitáře (repository). Pokud v takové situaci dojde ke kolapsu serveru, lze jej obnovit zkopírováním repozitáře od libovolného uživatele. Každá lokální kopie (checkout) je plnohodnotnou zálohou všech dat (viz obrázek 1-3). 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 celkem 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ž jsou na něm postavené. 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ší. @@ -120,13 +120,13 @@ Nachází-li se konkrétní verze souboru v adresáři Git, je považována za z ## Instalace systému Git ## -Je načase začít systém Git aktivně používat. Instalaci můžete provést celou řadou způsobů — obvyklá je instalace ze zdrojových souborů nebo instalace existujícího balíčku, určeného pro vaši platformu. +Je načase začít systém Git aktivně používat. Instalaci můžete provést celou řadou způsobů. Většinou se využívá buď instalace ze zdrojových souborů, nebo instalace z existujícího balíčku, určeného pro vaši platformu. ### Instalace ze zdrojových souborů ### -Pokud je to možné, je nejvhodnější instalovat Git ze zdrojových souborů. Tak je zaručeno, že vždy získáte aktuální verzi. Každá další verze systému se snaží přidat nová vylepšení uživatelského rozhraní. Použití poslední verze je tedy zpravidla tou nejlepší cestou, samozřejmě pokud vám nedělá problémy kompilace softwaru ze zdrojových souborů. +Pokud je to možné, je nejvhodnější instalovat Git ze zdrojových souborů. Tak je zaručeno, že vždy získáte aktuální verzi. Každá další verze systému se snaží přidat nová vylepšení uživatelského rozhraní. Použití poslední verze je tedy zpravidla tou nejlepší cestou, samozřejmě pokud vám nedělá problémy kompilace softwaru ze zdrojových souborů. Skutečností také je, že mnoho linuxových distribucí obsahuje velmi staré balíčky. Takže pokud nepoužíváte velmi čerstvou distribuci, nebo pokud záměrně používáte starší verzi, bývá instalace ze zdrojových souborů nejlepší volbou. -Před instalcí samotného Gitu musí váš systém obsahovat následující knihovny, na nichž je Git závislý: curl, zlib, openssl, expat, a libiconv. Pokud používáte yum (např. Fedora) nebo apt-get (např. distribuce založené na Debianu), můžete k instalaci použít jeden z následujících příkazů: +Před instalací samotného Gitu musí váš systém obsahovat následující knihovny, na nichž je Git závislý: curl, zlib, openssl, expat, a libiconv. Pokud používáte systém s nástrojem yum (například u distribuce Fedora) nebo apt-get (například distribuce odvozené od Debianu), můžete k instalaci použít jeden z následujících příkazů: $ yum install curl-devel expat-devel gettext-devel \ openssl-devel zlib-devel @@ -138,7 +138,7 @@ Po doinstalování všech potřebných závislostí můžete pokračovat stažen http://git-scm.com/download -Poté přistupte ke kompilaci a instalaci: +Poté spusťte kompilaci a instalaci: $ tar -zxf git-1.7.2.2.tar.gz $ cd git-1.7.2.2 @@ -151,26 +151,26 @@ Po dokončení instalace můžete rovněž vyhledat aktualizace systému Git pro ### Instalace v Linuxu ### -Chcete-li nainstalovat Git v Linuxu pomocí binárního instalátoru, většinou tak můžete učinit pomocí základního nástroje pro správu balíčků, který byl součástí vaší distribuce. Ve Fedoře můžete použít nástroj yum: +Chcete-li nainstalovat Git v Linuxu pomocí binárního instalátoru, většinou tak můžete učinit pomocí základního nástroje pro správu balíčků, který je součástí vaší distribuce. Ve Fedoře můžete použít nástroj yum: - $ yum install git-core + $ yum install git -V distribuci založené na Debianu (např. Ubuntu) zkuste použít program apt-get: +V distribuci založené na Debianu (jako je například Ubuntu) zkuste použít program apt-get: $ apt-get install git ### Instalace v systému Mac ### -Existují dva jednoduché způsoby, jak nainstalovat Git v systému Mac. Tím nejjednodušším je použít grafický instalátor Git, který si můžete stáhnout ze stránky Google Code (viz obrázek 1-7): +Existují dva jednoduché způsoby, jak nainstalovat Git v systému Mac. Tím nejjednodušším je použít grafický instalátor Git, který si můžete stáhnout ze stránky SourceForge (viz obrázek 1-7): - http://code.google.com/p/git-osx-installer + http://sourceforge.net/projects/git-osx-installer/ Insert 18333fig0107.png Obrázek 1-7. Instalátor Git pro OS X Jiným obvyklým způsobem je instalace systému Git prostřednictvím systému MacPorts (`http://www.macports.org`). Máte-li systém MacPorts nainstalován, nainstalujte Git příkazem: - $ sudo port install git-core +svn +doc +bash_completion +gitweb + $ sudo port install git +svn +doc +bash_completion +gitweb Není nutné přidávat všechny doplňky, ale pokud budete někdy používat Git s repozitáři systému Subversion, budete pravděpodobně chtít nainstalovat i doplněk +svn (viz kapitola 8). @@ -178,7 +178,7 @@ Není nutné přidávat všechny doplňky, ale pokud budete někdy používat Gi Instalace systému Git v OS Windows je velice nenáročná. Postup instalace projektu msysGit patří k těm nejjednodušším. Ze stránky GitHub stáhněte instalační soubor exe a spusťte ho: - http://msysgit.github.com/ + http://msysgit.github.io Po dokončení instalace budete mít k dispozici jak verzi pro příkazový řádek (včetně SSH klienta, který se vám bude hodit později), tak standardní grafické uživatelské rozhraní. @@ -188,40 +188,40 @@ Poznámka k používání pod Windows: Git byste měli používat z dodaného sh Nyní, když máte Git nainstalovaný, můžete provést některá uživatelská nastavení systému. Nastavení stačí provést pouze jednou — zůstanou zachována i po případných aktualizacích. -Nastavení konfiguračních proměnných systému, které ovlivňují jak vzhled systému Git, tak ostatní aspekty jeho práce, umožňuje příkaz git config. Tyto proměnné mohou být uloženy na třech různých místech: +Nastavení konfiguračních proměnných systému, které ovlivňují jak vzhled systému Git, tak ostatní aspekty jeho práce, umožňuje příkaz `git config`. Tyto proměnné mohou být uloženy na třech různých místech: -* Soubor `/etc/gitconfig` obsahuje údaje o všech uživatelích systému a jejich repozitářích. Pokud příkazu `git config` zadáme parametr `--system` bude číst a zapisovat jen do tohoto souboru. +* Soubor `/etc/gitconfig` obsahuje údaje pro všechny uživatele systému a pro všechny jejich repozitáře. Pokud příkazu `git config` zadáme parametr `--system` bude číst a zapisovat jen do tohoto souboru. * Soubor `~/.gitconfig` je vázán na uživatelský účet. Čtení a zápis do tohoto souboru zajistíte zadáním parametru `--global`. -* Konfigurační soubor v adresáři Git (tedy `.git/config`) jakéhokoliv užívaného repozitáře přísluší tomuto konkrétnímu repozitáři. Každá úroveň je nadřazená hodnotám úrovně předchozí, takže hodnoty v `.git/config` přebíjejí hodnotami v `/etc/gitconfig`. +* Konfigurační soubor v adresáři Git (tedy `.git/config`) jakéhokoliv užívaného repozitáře přísluší tomuto konkrétnímu repozitáři. Každá úroveň je nadřazená hodnotám úrovně předchozí, takže hodnoty v `.git/config` převládnou nad hodnotami v `/etc/gitconfig`. -Ve Windows používá Git soubor `.gitconfig`, který je umístěný v adresáři `$HOME` (v prostředí Windows je to `%USERPROFILE%`), což je u většiny uživatelů `C:\Documents and Settings\$USER` nebo `C:\Users\$USER` (kde `$USER` se v prostředí Windows označuje `%USERNAME%`). I ve Windows se hledá soubor `/etc/gitconfig`, který je ale umístěn relativně v kořeni Msys, tedy vůči místu, do kterého jste se po spuštění instalačního programu rozhodli Git nainstalovat. +Ve Windows Git hledá soubor `.gitconfig` v adresáři `$HOME` (v proměnných prostředí Windows je to `%USERPROFILE%`), což je u většiny uživatelů `C:\Documents and Settings\$USER` nebo `C:\Users\$USER` (`$USER` se ve Windows zapisuje odkazem na proměnnou prostředí `%USERNAME%`). I ve Windows se hledá soubor `/etc/gitconfig`, který je ale umístěn relativně v kořeni MSys, tedy vůči místu, do kterého jste se po spuštění instalačního programu rozhodli Git nainstalovat. -### Totožnost uživatele ### +### Vaše totožnost ### -První věcí, kterou byste měli po nainstalování systému Git udělat, je nastavení uživatelského jména (user name) a e-mailové adresy. Tyto údaje se totiž později využívají při všech revizích v systému Git a jsou nezměnitelnou složkou každé revize, kterou zapíšete: +První věcí, kterou byste měli po nainstalování systému Git udělat, je nastavení vašeho uživatelského jména (user name) a e-mailové adresy. Je to důležité, protože tuto informaci Git používá pro každý zápis revize a uvedené údaje stanou trvalou složkou záznamů o revizi, které budou putovat po okolí: $ git config --global user.name "John Doe" $ git config --global user.email johndoe@example.com -Použijete-li parametr `--global`, pak také toto nastavení stačí provést pouze jednou. Git bude používat tyto údaje pro všechny operace, které v systému uděláte. Pokud chcete pro konkrétní projekty změnit uživatelské jméno nebo e-mailovou adresu, můžete příkaz spustit bez parametru `--global`. V takovém případě je nutné, abyste se nacházeli v adresáři daného projektu. +Použijete-li parametr `--global`, pak také toto nastavení stačí provést pouze jednou. Git bude používat tyto údaje pro všechny operace, které v systému uděláte. Pokud chcete pro konkrétní projekt uživatelské jméno nebo e-mailovou adresu změnit (přebít), můžete příkaz spustit bez parametru `--global`. V takovém případě je nutné, abyste se nacházeli v adresáři daného projektu. -### Nastavení editoru ### +### Váš editor ### -Nyní, když jste zadali své osobní údaje, můžete nastavit výchozí textový editor, který bude Git využívat pro psaní zpráv. Pokud toto nastavení nezměníte, bude Git používat výchozí editor vašeho systému, jímž je většinou Vi nebo Vim. Chcete-li používat jiný textový editor (např. Emacs), můžete použít následující příkaz: +Nyní, když jste zadali své osobní údaje, můžete nastavit výchozí textový editor, který se použije, když po vás Git bude chtít napsat nějakou zprávu. Pokud toto nastavení nezměníte, bude Git používat výchozí editor vašeho systému, jímž je většinou Vi nebo Vim. Chcete-li používat jiný textový editor, například Emacs, můžete použít následující příkaz: $ git config --global core.editor emacs -### Nastavení nástroje diff ### +### Váš nástroj diff ### -Další proměnnou, jejíž nastavení můžete považovat za užitečné, je výchozí nástroj diff, jenž bude Git používat k řešení konfliktů při slučování. Řekněme, že jste se rozhodli používat vimdiff: +Další užitečnou volbou, jejíž nastavení můžete chtít upravit, je výchozí nástroj pro zjišťování rozdílů (diff), který Git používá k řešení konfliktů při slučování (merge). Řekněme, že jste se rozhodli používat vimdiff: $ git config --global merge.tool vimdiff Jako platné nástroje slučování Git akceptuje: kdiff3, tkdiff, meld, xxdiff, emerge, vimdiff, gvimdiff, ecmerge a opendiff. Nastavit můžete ale i jiné uživatelské nástroje — více informací o této možnosti naleznete v kapitole 7. -### Kontrola provedeného nastavení ### +### Kontrola vašeho nastavení ### -Chcete-li zkontrolovat provedené nastavení, použijte příkaz `git config --list`. Git vypíše všechna aktuálně dostupná nastavení: +Chcete-li zkontrolovat vaše nastavení, použijte příkaz `git config --list`. Git vypíše všechna aktuálně dostupná nastavení: $ git config --list user.name=Scott Chacon @@ -232,14 +232,14 @@ Chcete-li zkontrolovat provedené nastavení, použijte příkaz `git config --l color.diff=auto ... -Některé klíče se mohou objevit vícekrát, protože Git načítá stejný klíč z různých souborů (např. `/etc/gitconfig` a `~/.gitconfig`). V takovém případě použije Git poslední hodnotu pro každý unikátní klíč, který vidí. +Některé klíče se mohou objevit vícekrát, protože Git načítá stejný klíč z různých souborů (například `/etc/gitconfig` a `~/.gitconfig`). V takovém případě použije Git poslední hodnotu pro každý unikátní klíč, který vidí. -Můžete také zkontrolovat, jakou hodnotu Git uchovává pro konkrétní položku. Zadejte příkaz `git config {key}`: +Můžete také zkontrolovat, jakou hodnotu Git uchovává pro konkrétní klíč zadáním `git config {klíč}`: $ git config user.name Scott Chacon -## Kde hledat pomoc ## +## Získání nápovědy ## Budete-li někdy při používání systému Git potřebovat pomoc, existují tři způsoby, jak vyvolat nápovědu z manuálové stránky (manpage) pro jakýkoli z příkazů systému Git: @@ -247,12 +247,12 @@ Budete-li někdy při používání systému Git potřebovat pomoc, existují t $ git --help $ man git- -Například manpage nápovědu pro příkaz config vyvoláte zadáním: +Například manpage nápovědu pro příkaz `config` vyvoláte zadáním: $ git help config Tyto příkazy jsou užitečné, neboť je můžete spustit kdykoli, dokonce i offline. -Pokud nenajdete pomoc na manuálové stránce ani v této knize a uvítali byste osobní pomoc, můžete zkusit kanál `#git` nebo `#github` na serveru Freenode IRC (irc.freenode.net). Na těchto kanálech se většinou pohybují stovky lidí, kteří mají se systémem Git bohaté zkušenosti a často ochotně pomohou. +Pokud nestačí ani manuálová stránka ani tato kniha a uvítali byste osobní pomoc, můžete zkusit kanál `#git` nebo `#github` na serveru Freenode IRC (irc.freenode.net). Na těchto kanálech se většinou pohybují stovky lidí, kteří mají se systémem Git bohaté zkušenosti a často ochotně pomohou. (Nutno ovšem podotknout, že se na těchto kanálech mluví anglicky – pozn. překl.) ## Shrnutí ## diff --git a/cs/02-git-basics/01-chapter2.markdown b/cs/02-git-basics/01-chapter2.markdown index b8b37c4c0..c301bbb54 100644 --- a/cs/02-git-basics/01-chapter2.markdown +++ b/cs/02-git-basics/01-chapter2.markdown @@ -1,10 +1,10 @@ # Základy práce se systémem Git # -Pokud jste ochotni přečíst si o systému Git jen jednu kapitolu, měla by to být právě tahle. Tato kapitola popíše všechny základní příkazy, jejichž prováděním strávíte drtivou většinu času při práci se systémem Git. Po přečtení kapitoly byste měli být schopni nakonfigurovat a inicializovat repozitář, spustit a ukončit sledování souborů, připravovat soubory a zapisovat revize. Ukážeme také, jak nastavit Git, aby ignoroval určité soubory a masky souborů, jak rychle a jednoduše vrátit nežádoucí změny, jak procházet historii projektu a zobrazit změny mezi jednotlivými revizemi a jak posílat soubory do vzdálených repozitářů a stahovat z nich. +Pokud jste ochotni přečíst si o systému Git jen jednu kapitolu, měla by to být právě tahle. Tato kapitola popíše všechny základní příkazy, jejichž prováděním strávíte při práci se systémem Git drtivou většinu času. Po přečtení kapitoly byste měli být schopni nakonfigurovat a inicializovat repozitář, spustit a ukončit sledování souborů, připravovat soubory a zapisovat revize. Ukážeme si také, jak nastavit Git, aby ignoroval určité soubory a masky souborů, jak rychle a jednoduše vrátit nežádoucí změny, jak procházet historii projektu a zobrazit změny mezi jednotlivými revizemi a jak posílat soubory do vzdálených repozitářů a naopak z nich soubory zase stahovat. ## Získání repozitáře Git ## -Projekt v systému Git lze získat dvěma základními způsoby. První vezme existující projekt nebo adresář a importuje ho do systému Git. Druhý naklonuje existující repozitář Git z jiného serveru. +Projekt v systému Git lze získat dvěma základními způsoby. První způsob spočívá v tom, že vezmeme existující projekt nebo adresář a importujeme ho do systému Git. Druhý způsob spočívá v naklonování již existujícího repozitáře Git z jiného serveru. ### Inicializace repozitáře v existujícím adresáři ### @@ -12,9 +12,9 @@ Chcete-li zahájit sledování existujícího projektu v systému Git, přejdět $ git init -Příkaz vytvoří nový podadresář s názvem `.git`, který bude obsahovat všechny soubory nezbytné pro repozitář, tzv. kostru repozitáře Git. V tomto okamžiku ještě není nic z vašeho projektu sledováno. (Více informací o tom, jaké soubory obsahuje právě vytvořený adresář `.git`, naleznete v kapitole 9.) +Příkaz vytvoří nový podadresář s názvem `.git`, který bude obsahovat všechny soubory nezbytné pro repozitář, tzv. kostru repozitáře Git. V tomto okamžiku se z vašeho projektu ještě nic nesleduje. (Více informací o tom, jaké soubory obsahuje právě vytvořený adresář `.git`, naleznete v *kapitole 9*.) -Chcete-li spustit verzování existujících souborů (na rozdíl od prázdného adresáře), měli byste pravděpodobně zahájit sledování (tracking) těchto souborů a provést první revizi (commit). Můžete tak učinit pomocí několika příkazů `git add`, jimiž určíte soubory, které chcete sledovat, a provedete revizi: +Chcete-li spustit verzování existujících souborů (a ne jen prázdného adresáře), měli byste pravděpodobně zahájit sledování (tracking) těchto souborů a provést první revizi (commit). Můžete tak učinit pomocí několika příkazů `git add`, jimiž určíte soubory, které chcete sledovat, a provedete revizi: $ git add *.c $ git add README @@ -24,27 +24,27 @@ K tomu, co přesně tyto příkazy provedou, se dostaneme za okamžik. V této c ### Klonování existujícího repozitáře ### -Chcete-li vytvořit kopii existujícího repozitáře Git (například u projektu, do nějž chcete začít přispívat), pak příkazem, který hledáte, je `git clone`. Pokud jste zvyklí pracovat s jinými systémy VCS, např. se systémem Subversion, jistě jste si všimli, že příkaz zní `clone`, a nikoli `checkout`. Souvisí to s jedním podstatným rozdílem: Git stáhne kopii téměř všech dat na serveru. Po spuštění příkazu `git clone` budou k historii projektu staženy všechny verze všech souborů. Pokud by někdy poté došlo k poruše disku serveru, lze použít libovolný z těchto klonů na kterémkoli klientovi a obnovit pomocí něj server zpět do stavu, v němž byl v okamžiku klonování (může dojít ke ztrátě některých zásuvných modulů na straně serveru apod., ale všechna verzovaná dat budou obnovena – další podrobnosti v kapitole 4). +Chcete-li vytvořit kopii existujícího repozitáře Git (například u projektu, do nějž chcete začít přispívat), pak příkazem, který hledáte, je `git clone`. Pokud jste zvyklí pracovat s jinými systémy pro správu verzí, jako je například Subversion, jistě jste si všimli, že příkaz zní `clone`, a nikoli `checkout`. Souvisí to s jedním podstatným rozdílem: Git získá kopii téměř všech dat na serveru. Po spuštění příkazu `git clone` budou k historii projektu staženy všechny verze všech souborů. Pokud by někdy poté došlo k poruše disku serveru, lze použít libovolný z těchto klonů na kterémkoli klientovi a obnovit pomocí něj server zpět do stavu, v němž byl v okamžiku klonování (může dojít ke ztrátě některých zásuvných modulů na straně serveru a podobných věcí, ale všechna verzovaná data budou obnovena. Další podrobnosti naleznete v *kapitole 4*). Repozitář naklonujete příkazem `git clone [url]`. Pokud například chcete naklonovat knihovnu Ruby Git nazvanou Grit, můžete to provést následovně: $ git clone git://github.com/schacon/grit.git -Tímto příkazem vytvoříte adresář s názvem `grit`, inicializujete v něm adresář `.git`, stáhnete všechna data pro tento repozitář a systém rovněž stáhne pracovní kopii nejnovější verze. Přejdete-li do nového adresáře `grit`, uvidíte v něm soubory projektu připravené ke zpracování nebo jinému použití. Pokud chcete naklonovat repozitář do adresáře pojmenovaného jinak než grit, můžete název zadat jako další parametr na příkazovém řádku: +Tímto příkazem se vytvoří adresář s názvem `grit`, inicializuje se v něm adresář `.git`, stáhnou se všechna data pro tento repozitář a vytvoří se pracovní kopie nejnovější verze. Přejdete-li do nového adresáře `grit`, uvidíte v něm soubory projektu připravené ke zpracování nebo jinému použití. Pokud chcete naklonovat repozitář do adresáře pojmenovaného jinak než grit, můžete název zadat jako další parametr na příkazovém řádku: $ git clone git://github.com/schacon/grit.git mygrit -Tento příkaz učiní totéž co příkaz předchozí, jen cílový adresář se bude jmenovat `mygrit`. +Tento příkaz učiní totéž co příkaz předchozí, ale cílový adresář se bude jmenovat `mygrit`. -Git nabízí celou řadu různých přenosových protokolů. Předchozí příklad využívá protokol `git://`, můžete se ale setkat také s protokolem `http(s)://` nebo `user@server:/path.git`, který používá přenosový protokol SSH. V kapitole 4 budou představeny všechny dostupné parametry pro nastavení serveru pro přístup do repozitáře Git, včetně jejich předností a nevýhod. +Git nabízí celou řadu různých přenosových protokolů. Předchozí příklad využívá protokol `git://`, můžete se ale setkat také s protokolem `http(s)://` nebo `user@server:/path.git`, který používá přenosový protokol SSH. V *kapitole 4* budou představeny všechny dostupné možnosti, které mohou být pro přístup do repozitáře Git na serveru nastaveny, včetně jejich předností a nevýhod. ## Nahrávání změn do repozitáře ## -Nyní máte vytvořen repozitář Git a checkout nebo pracovní kopii souborů k projektu. Řekněme, že potřebujete udělat pár změn a zapsat snímky těchto změn do svého repozitáře pokaždé, kdy se projekt dostane do stavu, v němž ho chcete nahrát. +Nyní máte vytvořen opravdový gitový repozitář a pracovní kopii souborů k projektu (checkout). Řekněme, že potřebujete udělat pár změn a zapsat snímky těchto změn do svého repozitáře pokaždé, kdy se projekt dostane do stavu, který chcete zaznamenat. -Nezapomeňte, že každý soubor ve vašem pracovním adresáři může být ve dvou různých stavech: sledován a nesledován. Za sledované jsou označovány soubory, které byly součástí posledního snímku. Mohou být ve stavu změněno (modified), nezměněno (unmodified) nebo připraveno k zapsání (staged). Nesledované soubory jsou všechny ostatní, tedy veškeré soubory ve vašem pracovním adresáři, které nebyly obsaženy ve vašem posledním snímku a nejsou v oblasti připravených změn. Po úvodním klonování repozitáře budou všechny vaše soubory sledované a nezměněné, protože jste právě provedli jejich checkout a dosud jste neudělali žádné změny. +Nezapomeňte, že každý soubor ve vašem pracovním adresáři může být ve dvou různých stavech: *sledován* (tracked) a *nesledován* (untracked). Za *sledované* jsou označovány soubory, které byly součástí posledního snímku. Mohou být ve stavu *změněn* (modified), *nezměněn* (unmodified) nebo *připraven k zapsání* (staged). *Nesledované* soubory jsou všechny ostatní, tedy veškeré soubory ve vašem pracovním adresáři, které nebyly obsaženy ve vašem posledním snímku a nejsou v oblasti připravených změn. Po úvodním klonování repozitáře budou všechny vaše soubory sledované a nezměněné, protože jste právě provedli jejich checkout a dosud jste neudělali žádné změny. -Jakmile začnete soubory upravovat, Git je bude považovat za „změněné“, protože jste v nich od poslední revize provedli změny. Poté všechny tyto změněné soubory připravíte k zapsání a následně všechny připravené změny zapíšete. Cyklus může začít od začátku. Pracovní cyklus je znázorněn na obrázku 2-1. +Jakmile začnete soubory upravovat, Git je bude považovat za změněné, protože jste v nich od poslední revize provedli změny. Poté všechny tyto změněné soubory *připravíte k zapsání* (stage) a následně všechny připravené změny zapíšete (commit). A celý cyklus se opakuje. Pracovní cyklus je znázorněn na obrázku 2-1. Insert 18333fig0201.png Obrázek 2-1. Cyklus stavů vašich souborů @@ -54,23 +54,24 @@ Obrázek 2-1. Cyklus stavů vašich souborů Hlavním nástrojem na zjišťování stavu jednotlivých souborů je příkaz `git status`. Spustíte-li tento příkaz bezprostředně po klonování, objeví se zhruba následující: $ git status - # On branch master - nothing to commit (working directory clean) + On branch master + nothing to commit, working directory clean -To znamená, že žádné soubory nejsou připraveny k zapsání a pracovní adresář je čistý. Jinými slovy žádné sledované soubory nebyly změněny. Git také neví o žádných nesledovaných souborech, jinak by byly ve výčtu uvedeny. Příkaz vám dále sděluje, na jaké větvi (branch) se nacházíte. Pro tuto chvíli nebudeme situaci komplikovat a výchozí bude vždy hlavní větev (`master` branch). Větve a reference budou podrobně popsány v následující kapitole. +To znamená, že žádné soubory nejsou připraveny k zapsání a pracovní adresář je čistý. Jinými slovy, žádné sledované soubory nebyly změněny. Git také neví o žádných nesledovaných souborech, jinak by byly ve výčtu uvedeny. Příkaz vám dále sděluje, na jaké větvi (branch) se nacházíte. Pro tuto chvíli nebudeme situaci komplikovat a výchozí bude vždy hlavní větev (`master` branch). Větve a reference budou podrobně popsány v následující kapitole. -Řekněme, že nyní přidáte do projektu nový soubor, například soubor `README`. Pokud soubor neexistoval dříve a vy spustíte příkaz `git status`, bude nesledovaný soubor uveden takto: +Řekněme, že nyní přidáte do projektu nový soubor, například soubor `README`. Pokud soubor dříve neexistoval a vy spustíte příkaz `git status`, bude nesledovaný soubor uveden takto: $ 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) -Vidíte, že nový soubor `README` není sledován, protože je ve výpisu stavů uveden v části „Untracked files“. Není-li soubor sledován, obecně to znamená, že Git ví o souboru, který nebyl v předchozím snímku (v předchozí revizi), a nezařadí ho ani do dalších snímků, dokud mu k tomu nedáte výslovný příkaz. Díky tomu se nemůže stát, že budou do revizí nedopatřením zahrnuty vygenerované binární soubory nebo jiné soubory, které si nepřejete zahrnout. Vy si ale přejete soubor README zahrnout, a proto spusťme jeho sledování. +Vidíte, že nový soubor `README` není sledován, protože je ve výpisu stavů uveden v části „Untracked files“. Není-li soubor sledován, obecně to znamená, že Git ví o souboru, který nebyl v předchozím snímku (v předchozí revizi), a nezařadí ho ani do dalších snímků, dokud mu k tomu nedáte výslovný příkaz. Díky tomu se nemůže stát, že budou do revizí nedopatřením zahrnuty vygenerované binární soubory nebo jiné soubory, které si nepřejete zahrnout. Vy si ale přejete soubor README zahrnout, a proto ho začněme sledovat. ### Sledování nových souborů ### @@ -81,87 +82,89 @@ K zahájení sledování nových souborů se používá příkaz `git add`. Chce Když nyní znovu provedete příkaz k výpisu stavů (git status), uvidíte, že je nyní soubor `README` sledován a připraven k zapsání: $ 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 + Můžeme říci, že je připraven k zapsání, protože je uveden v části „Changes to be committed“, tedy „Změny k zapsání“. Pokud v tomto okamžiku zapíšete revizi, v historickém snímku bude verze souboru z okamžiku, kdy jste spustili příkaz `git add`. Možná si vzpomínáte, že když jste před časem spustili příkaz `git init`, provedli jste potom příkaz `git add (soubory)`. Příkaz jste zadávali kvůli zahájení sledování souborů ve vašem adresáři. Příkaz `git add` je doplněn uvedením cesty buď k souboru, nebo k adresáři. Pokud se jedná o adresář, příkaz přidá rekurzivně všechny soubory v tomto adresáři. -### Připravení změněných souborů ### +### Příprava změněných souborů k zapsání ### -Nyní provedeme změny v souboru, který už byl sledován. Pokud změníte už dříve sledovaný soubor s názvem `benchmarks.rb` a poté znovu spustíte příkaz `status`, zobrazí se výpis podobného obsahu: +Nyní provedeme změny v souboru, který už byl sledován. Pokud změníte už dříve sledovaný soubor s názvem `benchmarks.rb` a poté znovu spustíte příkaz `status`, zobrazí se něco takového: $ 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 -Soubor `benchmarks.rb` je uveden v části „Changes not staged for commit“ (Změněno, ale neaktualizováno). Znamená to, že soubor, který je sledován, byl v pracovním adresáři změněn, avšak ještě nebyl připraven k zapsání. Chcete-li ho připravit, spusťte příkaz `git add` (jedná se o univerzální příkaz – používá se k zahájení sledování nových souborů, k připravení souborů a k dalším operacím, jako např. k označení souborů, které kolidovaly při sloučení, za vyřešené). Spusťme nyní příkaz `git add` k připravení souboru `benchmarks.rb` k zapsání a následně znovu příkaz `git status`: + +Soubor `benchmarks.rb` je uveden v části „Changes not staged for commit“ (změny, které nejsou připraveny k zapsání). Znamená to, že soubor, který je sledován, byl v pracovním adresáři změněn, avšak ještě nebyl připraven k zapsání (staged). Chcete-li ho připravit k zapsání, spusťte příkaz `git add` (jedná se o víceúčelový příkaz – používá se k zahájení sledování nových souborů i k dalším operacím, jako je například označení vyřešených případů kolize souborů při slučování). Spusťme nyní příkaz `git add`, abychom soubor `benchmarks.rb` připravili k zapsání, a potom znovu zadejme příkaz `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) -Oba soubory jsou nyní připraveny k zapsání a budou zahrnuty do příští revize. Nyní předpokládejme, že jste si vzpomněli na jednu malou změnu, kterou chcete ještě před zapsáním revize provést v souboru `benchmarks.rb`. Soubor znovu otevřete a provedete změnu. Soubor je připraven k zapsání. Spusťme však ještě jednou příkaz `git status`: + new file: README + modified: benchmarks.rb + + +Oba soubory jsou nyní připraveny k zapsání a budou zahrnuty do příští revize. Nyní předpokládejme, že jste si vzpomněli na jednu malou změnu, kterou chcete ještě před zapsáním revize provést v souboru `benchmarks.rb`. Soubor znovu otevřete, provedete změnu a chcete jej zapsat. Spusťme však ještě jednou příkaz `git status`: $ 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) -Co to má být? Soubor `benchmarks.rb` je nyní uveden jak v části připraveno k zapsání (Changes to be committed), tak v části nepřipraveno k zapsání (Changes not staged for commit). Jak je tohle možné? Věc se má tak, že Git po spuštění příkazu `git add` připraví soubor přesně tak, jak je. Pokud nyní revizi zapíšete, bude obsahovat soubor `benchmarks.rb` tak, jak vypadal když jste naposledy spustili příkaz `git add`, nikoli v té podobě, kterou měl v pracovním adresáři v okamžiku, když jste spustili příkaz `git commit`. Pokud upravíte soubor po provedení příkazu `git add`, je třeba spustit `git add` ještě jednou, aby byla připravena aktuální verze souboru: + modified: benchmarks.rb + + +Co to má být? Soubor `benchmarks.rb` je nyní uveden jak v části připraveno k zapsání (Changes to be committed), tak v části nepřipraveno k zapsání (Changes not staged for commit). Jak je tohle možné? Věc se má tak, že Git po spuštění příkazu `git add` připraví soubor k zapsání přesně ve tvaru, v jakém se nachází v daném okamžiku. Pokud nyní revizi zapíšete, bude obsahovat soubor `benchmarks.rb` tak, jak vypadal, když jste naposledy spustili příkaz `git add`, nikoli v té podobě, kterou měl v pracovním adresáři v okamžiku, když jste spustili příkaz `git commit`. Pokud upravíte soubor po provedení příkazu `git add`, je třeba spustit `git add` ještě jednou, aby byla připravena aktuální verze souboru: $ 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 + ### Ignorované soubory ### -Často se ve vašem adresáři vyskytne skupina souborů, u nichž nebudete chtít, aby je Git automaticky přidával nebo aby je vůbec uváděl jako nesledované. Jedná se většinou o automaticky vygenerované soubory, jako soubory log nebo soubory vytvořené sestavovacím systémem. V takovém případě můžete vytvořit soubor `.gitignore`, který specifikuje ignorované soubory. Tady je malý příklad souboru `.gitignore`: +Ve vašem adresáři se často vyskytne skupina souborů, u nichž nebudete chtít, aby je Git automaticky přidával nebo aby je vůbec uváděl jako nesledované. Jedná se většinou o automaticky vygenerované soubory, jako soubory log nebo soubory vytvořené při překladu. V takových případech můžete vytvořit soubor `.gitignore` se seznamem masek pro ignorované soubory. Tady je malý příklad souboru `.gitignore`: $ cat .gitignore *.[oa] *~ -První řádek říká systému Git, že má ignorovat všechny soubory končící na `.o` nebo `.a` – objektové a archivní soubory, které mohou být výsledkem vytváření kódu. Druhý řádek systému Git říká, aby ignoroval všechny soubory končící vlnovkou (`~`), již mnoho textových editorů (např. Emacs) používá k označení dočasných souborů. Můžete rovněž přidat adresář `log`, `tmp` nebo `pid`, automaticky vygenerovanou dokumentaci apod. Nastavit soubor `.gitignore`, ještě než se pustíte do práce, bývá většinou dobrý nápad. Alespoň se vám nestane, že byste nedopatřením zapsali také soubory, o které v repozitáři Git nestojíte. +První řádek říká systému Git, že má ignorovat všechny soubory končící na `.o` nebo `.a` – *objekty* a *archivní* soubory, které mohou být výsledkem překladu. Druhý řádek systému Git říká, aby ignoroval všechny soubory končící vlnovkou (`~`), kterou mnoho textových editorů (např. Emacs) používá k označení dočasných souborů. Můžete rovněž přidat adresář `log`, `tmp` nebo `pid`, automaticky vygenerovanou dokumentaci a podobné. Vytvoření a naplnění souboru `.gitignore` ještě dříve než se pustíte do práce bývá většinou dobrý nápad. Alespoň se vám nestane, že byste nedopatřením zapsali také soubory, o které v repozitáři Git nestojíte. -Toto jsou pravidla pro masky, které můžete použít v souboru `.gitignore`: +Pravidla pro masky, které můžete použít v souboru `.gitignore`, jsou následující: * Prázdné řádky nebo řádky začínající znakem `#` budou ignorovány. -* Standardní masku souborů. +* Standardní masky souborů (glob patterns). * Chcete-li označit adresář, můžete masku zakončit lomítkem (`/`). * Pokud řádek začíná vykřičníkem (`!`), maska na něm je negována. @@ -180,25 +183,30 @@ Tady je další příklad souboru `.gitignore`: build/ # ignoruj doc/notes.txt, ale nikoli doc/server/arch.txt doc/*.txt + # ignoruj všechny .txt soubory v adresáři doc/ + doc/**/*.txt + +Část masky `**/` je v Gitu dostupná od verze 1.8.2. ### Zobrazení připravených a nepřipravených změn ### -Je-li pro vaše potřeby příkaz `git status` příliš neurčitý – chcete přesně vědět, co jste změnili, nejen které soubory – můžete použít příkaz `git diff`. Podrobněji se budeme příkazu `git diff` věnovat později. Vy ho však nejspíš budete nejčastěji využívat k zodpovězení těchto dvou otázek: Co jste změnili, ale ještě nepřipravili k zapsání? A co jste připravili a nyní může být zapsáno? Zatímco příkaz `git status` vám tyto otázky zodpoví velmi obecně, příkaz `git diff` přesně zobrazí přidané a odstraněné řádky – tedy samotná záplata. +Je-li pro vaše potřeby příkaz `git status` příliš neurčitý – chcete přesně vědět, co jste změnili, nejen které soubory – můžete použít příkaz `git diff`. Podrobněji se budeme příkazu `git diff` věnovat později. Vy ho však nejspíš budete nejčastěji využívat k zodpovězení těchto dvou otázek: Co jste změnili, ale ještě nepřipravili k zapsání? A co jste připravili a nyní může být zapsáno? Zatímco příkaz `git status` vám tyto otázky zodpoví velmi obecně, příkaz `git diff` přesně zobrazí přidané a odstraněné řádky – tedy samotnou záplatu. Řekněme, že znovu upravíte a připravíte soubor `README` a poté bez připravení upravíte soubor `benchmarks.rb`. Po spuštění příkazu `status` se zobrazí zhruba toto: $ 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 + Chcete-li vidět, co jste změnili, avšak ještě nepřipravili k zapsání, zadejte příkaz `git diff` bez dalších parametrů: @@ -221,7 +229,7 @@ Chcete-li vidět, co jste změnili, avšak ještě nepřipravili k zapsání, za Tento příkaz srovná obsah vašeho pracovního adresáře a oblasti připravených změn. Výsledek vám ukáže provedené změny, které jste dosud nepřipravili k zapsání. -Chcete-li vidět, co jste připravili a co bude součástí příští revize, použijte příkaz `git diff --cached`. (Ve verzích Git 1.6.1 a novějších můžete použít také příkaz `git diff --staged`, který se možná snáze pamatuje.) Tento příkaz srovná připravené změny s poslední revizí: +Chcete-li vidět, co jste připravili a co bude součástí příští revize, použijte příkaz `git diff --cached`. (Ve verzích Git 1.6.1 a novějších můžete použít také příkaz `git diff --staged`, který se možná snáze pamatuje.) Tento příkaz srovná připravené změny (staged changes) s poslední revizí: $ git diff --cached diff --git a/README b/README @@ -236,23 +244,25 @@ Chcete-li vidět, co jste připravili a co bude součástí příští revize, p + +Grit is a Ruby library for extracting information from a Git repository -K tomu je třeba poznamenat, že příkaz `git diff` sám o sobě nezobrazí všechny změny provedené od poslední revize, ale jen změny, které zatím nejsou připraveny. To může být občas matoucí, protože pokud jste připravili všechny provedené změny, výstup příkazu `git diff` bude prázdný. +K tomu je třeba poznamenat, že příkaz `git diff` sám o sobě nezobrazí všechny změny provedené od poslední revize, ale jen změny, které zatím nejsou připraveny. To může být občas matoucí, protože pokud jste připravili všechny provedené změny, bude výstup příkazu `git diff` prázdný. V dalším příkladu ukážeme situaci, kdy jste připravili soubor `benchmarks.rb` a poté ho znovu upravili. Příkaz `git diff` můžete nyní použít k zobrazení změn v souboru, které byly připraveny, a změn, které nejsou připraveny: $ 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 + Příkaz `git diff` nyní můžete použít k zobrazení změn, které dosud nejsou připraveny: @@ -288,12 +298,12 @@ A příkaz `git diff --cached` ukáže změny, které už připraveny jsou: ### Zapisování změn ### -Nyní, když jste seznam připravených změn nastavili podle svých představ, můžete začít zapisovat změny. Nezapomeňte, že všechno, co dosud nebylo připraveno k zapsání – všechny soubory, které jste vytvořili nebo změnili a na které jste po úpravách nepoužili příkaz `git add` – nebudou do revize zahrnuty. Zůstanou na vašem disku ve stavu „změněno“. -Když jsme v našem případě naposledy spustili příkaz `git status`, viděli jste, že všechny soubory byly připraveny k zapsání. Nyní může proběhnout samotné zapsání změn. Nejjednodušším způsobem zapsání je zadat příkaz `git commit`: +Nyní, když jste seznam připravených změn nastavili podle svých představ, můžete začít zapisovat změny. Nezapomeňte, že všechno, co dosud nebylo připraveno k zapsání – všechny soubory, které jste vytvořili nebo změnili a na které jste po úpravách nepoužili příkaz `git add` –, nebudou do revize zahrnuty. Zůstanou na vašem disku jako změněné soubory. +Když jste v našem případě naposledy spustili příkaz `git status`, viděli jste, že všechny soubory byly připraveny k zapsání. Takže jste připraveni k samotnému zapsání změn. Nejjednodušší způsob zapsání změn spočívá v použití příkazu `git commit`: $ git commit -Po zadání příkazu se otevře zvolený editor. (Ten je nastaven proměnnou prostředí `$EDITOR` vašeho shellu. Většinou se bude jednat o editor vim nebo emacs, ale pomocí příkazu `git config --global core.editor` můžete nastavit i jakýkoli jiný – viz kapitola 1.) +Po zadání příkazu se otevře vámi zvolený editor. (Ten je nastaven proměnnou prostředí `$EDITOR` vašeho shellu. Většinou se bude jednat o editor vim nebo emacs, ale pomocí příkazu `git config --global core.editor` můžete nastavit i jakýkoli jiný – viz *kapitola 1*.) Editor zobrazí následující text (tento příklad je z editoru Vim): @@ -301,75 +311,76 @@ Editor zobrazí následující text (tento příklad je z editoru Vim): # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Changes to be committed: - # (use "git reset HEAD ..." to unstage) - # # new file: README # modified: benchmarks.rb + # ~ ~ ~ ".git/COMMIT_EDITMSG" 10L, 283C -Jak vidíte, výchozí zpráva k revizi (commit message) obsahuje zakomentovaný aktuální výstup příkazu `git status` a nahoře jeden prázdný řádek. Tyto komentáře můžete odstranit a napsat vlastní zprávu k revizi, nebo je můžete v souboru ponechat, abyste si lépe vzpomněli, co bylo obsahem dané revize. (Chcete-li zařadit ještě podrobnější informace o tom, co jste měnili, můžete k příkazu `git commit` přidat parametr `-v`. V editoru se pak zobrazí také výstup „diff“ ke konkrétním změnám a vy přesně uvidíte, co bylo změněno.) Jakmile editor zavřete, Git vytvoří revizi se zprávou, kterou jste napsali (s odstraněnými komentáři a rozdíly). +Jak vidíte, výchozí zpráva k revizi (commit message) obsahuje zakomentovaný aktuální výstup příkazu `git status` a nahoře jeden prázdný řádek. Tyto komentáře můžete odstranit a napsat vlastní zprávu k revizi, nebo je můžete v souboru ponechat, abyste si lépe vzpomněli, co bylo obsahem dané revize. (Chcete-li zařadit ještě podrobnější informace o tom, co jste měnili, můžete k příkazu `git commit` přidat parametr `-v`. V editoru se pak zobrazí také výstup rozdílů (diff) ke konkrétním změnám a vy přesně uvidíte, co bylo změněno.) Jakmile editor zavřete, Git vytvoří revizi se zprávou, kterou jste napsali (s odstraněnými komentáři a rozdíly). Zprávu k revizi můžete rovněž napsat do řádku k příkazu `commit`. Jako zprávu ji označíte tak, že před ni vložíte příznak `-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] Story 182: Fix benchmarks for speed + 2 files changed, 3 insertions(+) create mode 100644 README -Nyní jste vytvořili svou první revizi! Vidíte, že se po zapsání revize zobrazil výpis s informacemi: do jaké větve jste revizi zapsali (hlavní, `master`), jaký kontrolní součet SHA-1 revize dostala (`463dc4f`), kolik souborů bylo změněno a statistiku přidaných a odstraněných řádků revize. +Nyní jste vytvořili svou první revizi! Vidíte, že se po zapsání revize zobrazil výpis s informacemi: do jaké větve jste revizi zapsali (`master`), jaký je kontrolní součet SHA-1 revize (`463dc4f`), kolik souborů bylo změněno a statistiku přidaných a odstraněných řádků revize. -Nezapomeňte, že revize zaznamená snímek projektu, jak je obsažen v oblasti připravených změn. Vše, co jste nepřipravili k zapsání, zůstane ve stavu „změněno“ na vašem disku. Chcete-li i tyto soubory přidat do své historie, zapište další revizi. Pokaždé, když zapíšete revizi, nahrajete snímek svého projektu, k němuž se můžete později vrátit nebo ho můžete použít k srovnání. +Nezapomeňte, že revize zaznamená snímek projektu, jak je obsažen v oblasti připravených změn. Vše, co jste nepřipravili k zapsání, zůstane ve stavu změněno na vašem disku. Chcete-li i tyto soubory přidat do své historie, zapište další revizi. Pokaždé, když zapíšete revizi, nahrajete snímek svého projektu, k němuž se můžete později vrátit nebo ho můžete použít k srovnání. ### Přeskočení oblasti připravených změn ### -Přestože může být oblast připravených změn opravdu užitečným nástrojem pro přesné vytváření revizí, je někdy při daném pracovním postupu zbytečným mezikrokem. Chcete-li oblast připravených změn úplně přeskočit, nabízí Git jednoduchou zkratku. Přidáte-li k příkazu `git commit` parametr `-a`, Git do revize automaticky zahrne každý soubor, který je sledován. Zcela tak odpadá potřeba zadávat příkaz `git add`: +Přestože může být oblast připravených změn opravdu užitečným nástrojem pro přesné vytváření revizí, je někdy při daném pracovním postupu zbytečným mezikrokem. Chcete-li oblast připravených změn úplně přeskočit, nabízí Git jednoduchou zkratku. Přidáte-li k příkazu `git commit` parametr `-a`, Git do revize automaticky zahrne každý soubor, který je sledován. Odpadá potřeba zadávat příkaz `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(+) -Tímto způsobem není nutné provádět před zapsáním revize příkaz `git add` pro soubor `benchmarks.rb`. +Povšimněte si, že kvůli souboru `benchmarks.rb` v tomto případě nemusíte před zapsáním revize provádět příkaz `git add`. ### Odstraňování souborů ### Chcete-li odstranit soubor ze systému Git, musíte ho odstranit ze sledovaných souborů (přesněji řečeno odstranit z oblasti připravených změn) a zapsat revizi. Odstranění provedete příkazem `git rm`, který odstraní soubor zároveň z vašeho pracovního adresáře, a proto ho už příště neuvidíte mezi nesledovanými soubory. -Pokud soubor jednoduše odstraníte z pracovního adresáře, zobrazí se ve výpisu `git status` v části „Changes not staged for commit“ (tedy nepřipraveno): +Pokud soubor jednoduše odstraníte z pracovního adresáře, zobrazí se ve výpisu `git status` v části „Changes not staged for commit“ (tedy *nepřipraveno*): $ 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") Pokud nyní provedete příkaz `git rm`, bude k zapsání připraveno odstranění souboru: $ 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) -Po příštím zapsání revize soubor zmizí a nebude sledován. Pokud už jste soubor upravili a přidali do indexu, musíte odstranění provést pomocí parametru `-f`. Jedná se o bezpečnostní funkci, jež má zabránit nechtěnému odstranění dat, která ještě nebyla nahrána do snímku, a nemohou proto být ze systému Git obnovena. + deleted: grit.gemspec + + +Po příštím zapsání revize soubor zmizí a přestane být sledován. Pokud už jste soubor upravili a přidali do indexu, musíte odstranění provést pomocí parametru `-f`. Jedná se o bezpečnostní funkci, jež má zabránit nechtěnému odstranění dat, která ještě nebyla nahrána do snímku, a nemohou proto být ze systému Git obnovena. Další užitečnou možností, která se vám může hodit, je zachování souboru v pracovním stromě a odstranění z oblasti připravených změn. Soubor tak ponecháte na svém pevném disku, ale ukončíte jeho sledování systémem Git. To může být užitečné zejména v situaci, kdy něco zapomenete přidat do souboru `.gitignore`, a omylem to tak zahrnete do revize, např. velký log soubor nebo pár zkompilovaných souborů s příponou `.a`. V takovém případě použijte parametr `--cached`: @@ -387,7 +398,7 @@ Tento příkaz odstraní všechny soubory, které končí vlnovkou (`~`). ### Přesouvání souborů ### -Na rozdíl od ostatních systémů VCS nesleduje Git explicitně přesouvání souborů. Pokud přejmenujete v systému Git soubor, neuloží se žádná metadata s informací, že jste soubor přejmenovali. Git však používá jinou fintu, aby zjistil, že byl soubor přejmenován. Na ni se podíváme později. +Na rozdíl od ostatních systémů pro správu verzí nesleduje Git explicitně přesouvání souborů. Pokud soubor v systému Git přejmenujete, neuloží se žádná metadata s informací, že jste soubor přejmenovali. Git však používá jinou fintu, aby zjistil, že byl soubor přejmenován. Na ni se podíváme později. Může se zdát zvláštní, že Git přesto používá příkaz `mv`. Chcete-li v systému Git přejmenovat soubor, můžete spustit třeba příkaz @@ -395,22 +406,20 @@ Může se zdát zvláštní, že Git přesto používá příkaz `mv`. Chcete-li a vše funguje na výbornou. A skutečně, pokud takový příkaz provedete a podíváte se na stav souboru, uvidíte, že ho Git považuje za přejmenovaný (renamed): - $ git mv README.txt README + $ git mv README README.txt $ 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 -> README.txt + Výsledek je však stejný, jako byste provedli následující: - $ mv README.txt README - $ git rm README.txt - $ git add README + $ mv README README.txt + $ git rm README + $ git add README.txt Git implicitně zjistí, že se jedná o přejmenování, a proto nehraje roli, zda přejmenujete soubor tímto způsobem, nebo pomocí příkazu `mv`. Jediným skutečným rozdílem je, že `mv` je jediný příkaz, zatímco u druhého způsobu potřebujete příkazy tři — příkaz `mv` je pouze zjednodušením. Důležitější je, že můžete použít jakýkoli způsob přejmenování a příkaz add/rm provést později, před zapsáním revize. @@ -422,7 +431,7 @@ Následující příklady ukazují velmi jednoduchý projekt pojmenovaný `simpl git clone git://github.com/schacon/simplegit-progit.git -Po zadání příkazu `git log` v tomto projektu byste měli dostat výstup, který vypadá zhruba následovně: +Po zadání příkazu `git log` v tomto projektu byste měli dostat výstup, který vypadá zhruba takto: $ git log commit ca82a6dff817ec66f44342007202690a93763949 @@ -443,11 +452,11 @@ Po zadání příkazu `git log` v tomto projektu byste měli dostat výstup, kte first commit -Ve výchozím nastavení a bez dalších parametrů vypíše příkaz `git log` revize provedené v daném repozitáři v obráceném chronologickém pořadí. Nejnovější revize tak budou uvedeny nahoře. Jak vidíte, tento příkaz vypíše všechny revize s jejich kontrolním součtem SHA-1, jménem a e-mailem autora, datem zápisu a zprávou k revizi. +Ve výchozím nastavení a bez dalších parametrů vypíše příkaz `git log` revize provedené v daném repozitáři v obráceném chronologickém pořadí. Nejnovější revize tak budou uvedeny nahoře. Jak vidíte, tento příkaz vypíše všechny revize s jejich kontrolním součtem SHA-1, jménem a e-mailem autora, datem zápisu a zprávou o revizi. -K příkazu `git log` je k dispozici velké množství nejrůznějších parametrů, díky nimž můžete najít přesně to, co hledáte. Vyjmenujme některé z nejčastěji používaných parametrů. +K příkazu `git log` je k dispozici velké množství nejrůznějších parametrů, díky nimž můžete zobrazit přesně to, co potřebujete. Ukážeme si některé z nejpoužívanějších možností. -Jedním z nejužitečnějších je parametr `-p`, který zobrazí rozdíly diff provedené v každé revizi. Můžete také použít parametr `-2`, který omezí výpis pouze na dva poslední záznamy: +Jedním z nejužitečnějších je parametr `-p`, který zobrazí rozdíly (diff) provedené v každé revizi. Můžete také použít parametr `-2`, který omezí výpis pouze na dva poslední záznamy: $ git log -p -2 commit ca82a6dff817ec66f44342007202690a93763949 @@ -460,11 +469,13 @@ Jedním z nejužitečnějších je parametr `-p`, který zobrazí rozdíly diff 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 @@ -488,6 +499,27 @@ Jedním z nejužitečnějších je parametr `-p`, který zobrazí rozdíly diff \ No newline at end of file Tento parametr zobrazí tytéž informace, ale za každým záznamem následuje informace o rozdílech. Tato funkce je velmi užitečná při kontrole kódu nebo k rychlému zjištění, co bylo obsahem série revizí, které přidal váš spolupracovník. + +Někdy se změny kontrolují snadněji na úrovni slov než na úrovni řádků. Git nabízí parametr `--word-diff`, který můžeme přidat za příkaz `git log -p`. Místo obvyklé detekce rozdílů po řádcích získáme rozdíly po slovech. Zjišťování rozdílů po slovech je u zdrojového kódu celkem k ničemu, ale pokud porovnáváme velké textové soubory -- jako například knihy nebo vaši disertační práci --, pak se tato možnost hodí. Tady máme příklad: + + $ 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" + +Jak vidíte, výstup neobsahuje žádné přidané a odstraněné řádky, jak tomu bývá u běžného zobrazení rozdílů (diff). Místo toho se změny zobrazují uvnitř textu. Přidaná slova jsou uzavřena mezi značkami `{+ +}` a odstraněná jsou uzavřena v `[- -]`. Možná byste také rádi zredukovali obvyklé třířádkové okolí změny na pouhý jeden řádek, protože chcete znát okolí slova a ne okolí řádku. Můžeme toho dosáhnout zadáním parametru `-U1`, jako ve výše uvedeném příkladu. + Ve spojení s příkazem `git log` můžete použít také celou řadu shrnujících parametrů. Pokud například chcete zobrazit některé stručné statistiky pro každou revizi, použijte parametr `--stat`: $ git log --stat @@ -498,7 +530,7 @@ Ve spojení s příkazem `git log` můžete použít také celou řadu shrnujíc 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 @@ -507,7 +539,7 @@ Ve spojení s příkazem `git log` můžete použít také celou řadu shrnujíc 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 @@ -518,7 +550,7 @@ Ve spojení s příkazem `git log` můžete použít také celou řadu shrnujíc README | 6 ++++++ Rakefile | 23 +++++++++++++++++++++++ lib/simplegit.rb | 25 +++++++++++++++++++++++++ - 3 files changed, 54 insertions(+), 0 deletions(-) + 3 files changed, 54 insertions(+) Jak vidíte, parametr `--stat` vypíše pod každým záznamem revize seznam změněných souborů, kolik souborů bylo změněno (changed) a kolik řádků bylo v těchto souborech vloženo (insertions) a smazáno (deletions). Zároveň vloží na konec výpisu shrnutí těchto informací. Další opravdu užitečnou možností je parametr `--pretty`. Tento parametr změní výstup logu na jiný než výchozí formát. K dispozici máte několik přednastavených možností. Parametr `oneline` vypíše všechny revize na jednom řádku. Tuto možnost oceníte při velkém množství revizí. Dále se nabízejí parametry `short`, `full` a `fuller` (zkrácený, plný, úplný). Zobrazují výstup přibližně ve stejném formátu, avšak s více či méně podrobnými informacemi: @@ -537,13 +569,18 @@ Nejzajímavějším parametrem je pak `format`, který umožňuje definovat vlas Tabulka 2-1 uvádí některé užitečné parametry, které format akceptuje. + + Parametr Popis výstupu %H Otisk (hash) revize %h Zkrácený otisk revize %T Otisk stromu %t Zkrácený otisk stromu - %P Nadřazené otisky - %p Zkrácené nadřazené otisky + %P Otisky rodičovských revizí + %p Zkrácené otisky rodičovských revizí %an Jméno autora %ae E-mail autora %ad Datum autora (formát je možné nastavit parametrem --date) @@ -554,7 +591,7 @@ Tabulka 2-1 uvádí některé užitečné parametry, které format akceptuje. %cr Datum autora revize, relativní %s Předmět -Možná se ptáte, jaký je rozdíl mezi autorem a autorem revize. Autor je osoba, která práci původně napsala, zatímco autor revize je osoba, která práci zapsala do repozitáře. Pokud tedy pošlete záplatu k projektu a některý z ústředních členů (core members) ji použije, do výpisu se dostanete oba – vy jako autor a core member jako autor revize. K tomuto rozlišení se blíže dostaneme v kapitole 5. +Možná se ptáte, jaký je rozdíl mezi *autorem* a *autorem revize*. *Autor* (author) je osoba, která práci původně napsala, zatímco *autor revize* (committer) je osoba, která práci zapsala do repozitáře. Pokud tedy pošlete záplatu k projektu a některý z ústředních členů (core members) ji použije, do výpisu se dostanete oba – vy jako autor a core member jako autor revize. K tomuto rozlišení se blíže dostaneme v *kapitole 5*. Parametry `oneline` a `format` jsou zvlášť užitečné ve spojení s další možností `log`u – parametrem `--graph`. Tento parametr vloží pěkný malý ASCII graf, znázorňující historii vaší větve a slučování, kterou si ukážeme na naší kopii repozitáře projektu Grit: @@ -572,8 +609,14 @@ Parametry `oneline` a `format` jsou zvlášť užitečné ve spojení s další To je jen několik základních parametrů k formátování výstupu pro příkaz `git log`, celkově jich je mnohem více. Tabulka 2-2 uvádí parametry, které jsme už zmínili, a některé další běžné parametry formátování, které mohou být užitečné. Pravý sloupec popisuje, jak který parametr změní výstup `log`u. + + Parametr Popis -p Zobrazí záplatu vytvořenou s každou revizí. + --word-diff Zobrazí záplatu ve tvaru rozdílu po slovech. --stat Zobrazí statistiku pro změněné soubory v každé revizi. --shortstat Zobrazí pouze řádek změněno/vloženo/smazáno z příkazu --stat. --name-only Za informacemi o revizi zobrazí seznam změněných souborů. @@ -581,7 +624,7 @@ To je jen několik základních parametrů k formátování výstupu pro příka --abbrev-commit Zobrazí pouze prvních několik znaků kontrolního součtu SHA-1 místo všech 40. --relative-date Zobrazí datum v relativním formátu (např. "2 weeks ago", tj. před 2 týdny) místo formátu s úplným datem. --graph Zobrazí vedle výstupu logu ASCII graf k historii větve a slučování. - --pretty Zobrazí revize v alternativním formátu. Parametry příkazu jsou oneline, short, full, fuller a format (lze zadat vlastní formát). + --pretty Zobrazí revize v alternativním formátu. Parametry příkazu jsou oneline, short, full, fuller a format (ve kterém uvedete svůj vlastní formát). --oneline Užitečná zkratka pro `--pretty=oneline --abbrev-commit`. ### Omezení výstupu logu ### @@ -594,12 +637,19 @@ Velmi užitečné jsou naproti tomu časově omezující parametry, jako `--sinc Tento příkaz pracuje s velkým množstvím formátů. Můžete zadat konkrétní datum („2008-01-15“) nebo relativní datum, např. „2 years 1 day 3 minutes ago“ (před 2 roky, 1 dnem a 3 minutami). -Z výpisu rovněž můžete filtrovat pouze revize, které odpovídají určitým kritériím. Parametr `--author` umožňuje filtrovat výpisy podle konkrétního autora, pomocí parametru `--grep` můžete ve zprávách k revizím vyhledávat klíčová slova. Chcete-li hledat současný výskyt parametrů author i grep, musíte přidat výraz `--all-match`, jinak se bude hledat kterýkoli z nich. +Z výpisu rovněž můžete filtrovat pouze revize, které odpovídají určitým kritériím. Parametr `--author` umožňuje filtrovat výpisy podle konkrétního autora, pomocí parametru `--grep` můžete ve zprávách k revizím vyhledávat klíčová slova. (Všimněte si, že pokud použijete současně parametry author a grep, bude příkaz vyhledávat záznamy splňující obojí.) + +Pokud chcete zadat více parametrů grep, musíte přidat výraz `--all-match`, jinak se bude hledat kterýkoli z nich. Posledním opravdu užitečným parametrem, který lze přidat k příkazu `git log` , je zadání cesty. Jestliže zadáte název adresáře nebo souboru, výstup logu tím omezíte na revize, které provedly změnu v těchto souborech. Cesta je vždy posledním parametrem a většinou jí předcházejí dvě pomlčky (`--`) , jimiž je oddělena od ostatních parametrů. Tabulka 2-3 uvádí pro přehlednost zmíněné parametry a několik málo dalších. Tabulka 2.2 + + Parametr Popis -(n) Zobrazí pouze posledních n revizí. --since, --after Omezí výpis na revize provedené po zadaném datu. @@ -607,10 +657,55 @@ Tabulka 2-3 uvádí pro přehlednost zmíněné parametry a několik málo dalš --author Zobrazí pouze revize, v nichž autor odpovídá zadanému řetězci. --committer Zobrazí pouze revize, v nichž autor revize odpovídá zadanému řetězci. -Pokud chcete například zjistit, které revize upravující testovací soubory byly v historii zdrojového kódu Git zapsány v říjnu 2008 Juniem Hamanem a nebyly sloučením, můžete zadat následující příkaz: - $ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \ - --before="2008-11-01" --no-merges -- t/ +### Omezení výstupního logu na určité datum nebo čas ### + +Pokud chcete zjistit, které revize (commit) v repozitáři se zdrojovým kódem Git (git://git.kernel.org/pub/scm/git/git.git) mají datum zápisu (CommitDate) 2014-04-29 -- relativně k vašemu lokálnímu časovému pásmu (takovému, jaké je nastaveno na vašem počítači), použijte příkaz + + $ git log --after="2014-04-29 00:00:00" --before="2014-04-29 23:59:59" \ + --pretty=fuller + +Protože se výstup bude lišit podle časového pásma v místě spuštění, doporučuje se v argumentech `--after` a `--before` vždy používat absolutní čas (například ve formátu ISO 8601, který obsahuje i informaci o časovém pásmu). Činíme tak proto, aby každý, kdo stejný příkaz spustí, obdržel stejné, opakovatelné výsledky. + +Pokud chceme získat zápisy z určitého časového okamžiku (například z 29. dubna 2013 v 17:07:22 středoevropského času), můžeme použít příkaz + + $ git log --after="2013-04-29T17:07:22+0200" \ + --before="2013-04-29T17:07:22+0200" --pretty=fuller + + commit de7c201a10857e5d424dbd8db880a6f24ba250f9 + Author: Ramkumar Ramachandra + AuthorDate: Mon Apr 29 18:19:37 2013 +0530 + Commit: Junio C Hamano + CommitDate: Mon Apr 29 08:07:22 2013 -0700 + + git-completion.bash: lexical sorting for diff.statGraphWidth + + df44483a (diff --stat: add config option to limit graph width, + 2012-03-01) added the option diff.startGraphWidth to the list of + configuration variables in git-completion.bash, but failed to notice + that the list is sorted alphabetically. Move it to its rightful place + in the list. + + Signed-off-by: Ramkumar Ramachandra + Signed-off-by: Junio C Hamano + +Výše uvedené časy (`AuthorDate`, `CommitDate`) se zobrazují v základním tvaru (`--date=default`), který zobrazuje informaci o časovém pásmu autora nebo přispěvatele. + +K dalším užitečným formátům patří `--date=iso` (ISO 8601), `--date=rfc` (RFC 2822), `--date=raw` (sekundy od počátku (epoch; 1970-01-01 UTC)), `--date=local` (časy ve vašem lokálním časovém pásmu) a také `--date=relative` (jako například "2 hours ago", tj. před dvěma hodinami). + +Pokud použijete příkaz `git log` bez určení času, uvažuje se čas odpovídající okamžiku spuštění na vašem počítači (používá stejný posun vůči UTC). + +Pokud například na vašem počítači spustíte `git log` v 09:00 a vaše časové pásmo je vůči greenwichskému času posunuto o tři hodiny vpřed, pak se výsledek následujících dvou příkazů shoduje: + + $ git log --after=2008-06-01 --before=2008-07-01 + $ git log --after="2008-06-01T09:00:00+0300" \ + --before="2008-07-01T09:00:00+0300" + +A poslední příklad. Pokud chcete zjistit, které revize upravující testovací soubory ve zdrojovém kódu Git zapsal Junio Hamano v říjnu 2008 (relativě k časové zóně New Yorku) a které přitom nebyly sloučením (merge), můžete zadat následující příkaz: + + $ git log --pretty="%h - %s" --author=gitster \ + --after="2008-10-01T00:00:00-0400" \ + --before="2008-10-31T23:59:59-0400" --no-merges -- t/ 5610e3b - Fix testcase failure when extended attribute acd3b9e - Enhance hold_lock_file_for_{update,append}() f563754 - demonstrate breakage of detached checkout wi @@ -618,7 +713,7 @@ Pokud chcete například zjistit, které revize upravující testovací soubory 51a94af - Fix "checkout --track -b newbranch" on detac b0ad11e - pull: allow "git pull origin $something:$cur -Z téměř 20 000 revizí v historii zdrojového kódu Git zobrazí tento příkaz 6 záznamů, které odpovídají zadaným kritériím. +Z více než 36 tisíc revizí v historii zdrojového kódu Git zobrazí tento příkaz 6 záznamů, které odpovídají zadaným kritériím. ### Grafické uživatelské rozhraní pro procházení historie ### @@ -631,11 +726,11 @@ V horní polovině okna vidíte historii revizí, doplněnou názorným hierarch ## Rušení změn ## -Kdykoli si můžete přát zrušit nějakou provedenou změnu. Podívejme se proto, jaké základní nástroje se nám tu nabízejí. Ale buďte opatrní! Ne všechny zrušené změny se dají vrátit. Je to jedna z mála oblastí v systému Git, kdy při neuváženém postupu riskujete, že přijdete o část své práce. +Kdykoli se může stát, že byste nějakou úpravu chtěli vrátit do původního stavu.. Podívejme se proto, jaké základní nástroje se nám tu nabízejí. Ale buďte opatrní! Ne všechny zrušené změny se dají vrátit. Je to jedna z mála oblastí v systému Git, kdy při neuváženém postupu riskujete, že přijdete o část své práce. ### Změna poslední revize ### -Jedním z nejčastějších rušení úprav je situace, kdy zapíšete revizi příliš brzy a ještě jste např. zapomněli přidat některé soubory nebo byste rádi změnili zprávu k revizi. Chcete-li opravit poslední revizi, můžete spustit příkaz commit s parametrem `--amend`: +Jedním z nejčastějších důvodů pro rušení úprav je situace, kdy zapíšete revizi příliš brzy a ještě jste například zapomněli přidat některé soubory, nebo byste rádi změnili zprávu k revizi. Chcete-li opravit poslední revizi, můžete spustit příkaz commit s parametrem `--amend`: $ git commit --amend @@ -649,39 +744,40 @@ Pokud například zapíšete revizi a potom si uvědomíte, že jste zapomněli $ git add forgotten_file $ git commit --amend -Tyto tři příkazy vytvoří jedinou revizi – třetí příkaz nahradí výsledky prvního. +Provedení uvedených tří příkazů zůstane jediná revize – druhý příkaz `commit` nahradí výsledky prvního. -### Návrat souboru z oblasti připravených změn ### +### Odstranění souboru z oblasti připravených změn ### -Následující dvě části popisují, jak vrátit změny provedené v oblasti připravených změn a v pracovním adresáři. Je příjemné, že příkaz, jímž se zjišťuje stav těchto dvou oblastí, zároveň připomíná, jak v nich zrušit nežádoucí změny. Řekněme například, že jste změnili dva soubory a chcete je zapsat jako dvě oddělené změny, jenže omylem jste zadali příkaz `git add *` a oba soubory jste tím připravili k zapsání. Jak lze tyto dva soubory vrátit z oblasti připravených změn? Připomene vám to příkaz `git status`: +Následující dvě části popisují, jak se poprat s oblastí připravených změn a se změnami v pracovním adresáři. Je příjemné, že příkaz, jímž se zjišťuje stav těchto dvou oblastí, zároveň připomíná, jak v nich nežádoucí změny zrušit. Řekněme například, že jste změnili dva soubory a chcete je zapsat jako dvě oddělené změny. Jenže omylem jste zadali příkaz `git add *` a oba soubory jste tím připravili k zapsání. Jak lze tyto dva soubory vrátit z oblasti připravených změn? Připomene vám to příkaz `git status`: $ 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 + Přímo pod nadpisem „Changes to be committed“ (Změny k zapsání) se říká: pro návrat z oblasti připravených změn použijte příkaz `git reset HEAD ...` Budeme se tedy řídit touto radou a vrátíme soubor `benchmarks.rb` z oblasti připravených změn: $ 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 + Příkaz je sice trochu zvláštní, ale funguje. Soubor `benchmarks.rb` má stav „změněn“, ale už se nenachází v oblasti připravených změn. @@ -689,44 +785,44 @@ Příkaz je sice trochu zvláštní, ale funguje. Soubor `benchmarks.rb` má sta A co když zjistíte, že nechcete zachovat změny, které jste provedli v souboru `benchmarks.rb`? Jak je můžete snadno zrušit a vrátit soubor zpět do podoby při poslední revizi (nebo při prvním klonování nebo v jakémkoli okamžiku, kdy jste ho zaznamenali v pracovním adresáři)? Příkaz `git status` vám naštěstí řekne, co dělat. U posledního příkladu vypadá oblast připravených změn takto: - # 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 + Výpis vám sděluje, jak zahodit změny (discard changes), které jste provedli (přinejmenším tak činí novější verze systému Git, od verze 1.6.1; pokud máte starší verzi, doporučujeme ji aktualizovat, čímž získáte některé z těchto vylepšených funkcí). Uděláme, co nám výpis radí: $ 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 -Jak vidíte, změny byly zahozeny. Všimněte si také, že se jedná o nebezpečný příkaz. Veškeré změny, které jste v souboru provedli, jsou ztraceny, soubor jste právě překopírovali jiným souborem. Nikdy tento příkaz nepoužívejte, pokud si nejste zcela jisti, že už daný soubor nebudete potřebovat. Pokud potřebujete pouze odstranit soubor z cesty, podívejte se na odkládání a větvení v následující kapitole. Tyto postupy většinou bývají vhodnější. -Vše, co je zapsáno v systému Git, lze téměř vždy obnovit. Obnovit lze dokonce i revize na odstraněných větvích nebo revize, které byly přepsány revizí `--amend` (o obnovování dat viz kapitola 9). Pokud však dojde ke ztrátě dat, která dosud nebyla součástí žádné revize, bude tato ztráta patrně nevratná. +Jak vidíte, změny byly zahozeny. Všimněte si také, že se jedná o nebezpečný příkaz. Veškeré změny, které jste v souboru provedli, jsou ztraceny, soubor jste právě překopírovali jiným souborem. Nikdy tento příkaz nepoužívejte, pokud si nejste zcela jisti, že už daný soubor nebudete potřebovat. Pokud potřebujete pouze odstranit soubor z cesty, podívejte se na odkládání (stashing) a větvení v následující kapitole. Tyto postupy většinou bývají vhodnější. + +Zapamatujte si, že vše, co je zapsáno v systému Git, lze téměř vždy obnovit. Obnovit lze dokonce i revize na odstraněných větvích nebo revize, které byly přepsány revizí `--amend` (o obnovování dat viz *kapitola 9*). Pokud však dojde ke ztrátě dat, která dosud nebyla součástí žádné revize, bude tato ztráta patrně nevratná. ## Práce se vzdálenými repozitáři ## -Abyste mohli spolupracovat na projektech v systému Git, je třeba vědět, jak manipulovat se vzdálenými repozitáři (remote repositories). Vzdálené repozitáře jsou verze vašeho projektu umístěné na internetu nebo kdekoli v síti. Vzdálených repozitářů můžete mít hned několik, každý pro vás přitom bude buď pouze ke čtení (read-only) nebo ke čtení a zápisu (read write). Spolupráce s ostatními uživateli zahrnuje také manipulaci s těmito vzdálenými repozitáři. Chcete-li svou práci sdílet, je nutné ji posílat do repozitářů a také ji z nich stahovat. -Při manipulaci se vzdálenými repozitáři je nutné vědět, jak lze přidat vzdálený repozitář, jak odstranit repozitář, který už není platný, jak spravovat různé vzdálené větve, jak je definovat jako sledované či nesledované apod. V této části se zaměříme právě na správu vzdálených repozitářů. +Abyste mohli spolupracovat na projektech v systému Git, je třeba vědět, jak manipulovat se vzdálenými repozitáři (remote repositories). Vzdálené repozitáře jsou verze vašeho projektu umístěné na Internetu nebo kdekoli v síti. Vzdálených repozitářů můžete mít hned několik, každý pro vás přitom bude buď pouze ke čtení (read-only) nebo ke čtení a zápisu (read write). Spolupráce s ostatními uživateli zahrnuje také správu těchto vzdálených repozitářů. Při sdílení práce musíte do těchto repozitářů data odesílat (push) a zase je z nich stahovat (pull). +Při správě vzdálených repozitářů musíte vědět, jak lze přidat vzdálený repozitář, jak odstranit vzdálený repozitář, který už není platný, jak spravovat různé vzdálené větve, jak je definovat jako sledované či nesledované a další věci. V této části se zaměříme právě na správu vzdálených repozitářů. ### Zobrazení vzdálených serverů ### -Chcete-li zjistit, jaké vzdálené servery máte nakonfigurovány, můžete použít příkaz `git remote`. Systém vypíše zkrácené názvy všech identifikátorů vzdálených repozitářů, jež máte zadány. Pokud byl váš repozitář vytvořen klonováním, měli byste vidět přinejmenším server origin. Origin je výchozí název, který Git dává serveru, z nějž jste repozitář klonovali. +Chcete-li zjistit, jaké vzdálené servery máte nakonfigurovány, můžete použít příkaz `git remote`. Systém vypíše krátké názvy, přes které se se vzdálenými repozitáři manipuluje, a které jste dříve určili. Pokud byl váš repozitář vytvořen klonováním, měli byste vidět přinejmenším server *origin*. Jde o výchozí název, který Git dává serveru, z nějž jste repozitář klonovali. $ 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 @@ -737,7 +833,7 @@ Můžete rovněž zadat parametr `-v`, jenž zobrazí adresu URL, kterou má Git origin git://github.com/schacon/ticgit.git (fetch) origin git://github.com/schacon/ticgit.git (push) -Pokud máte více než jeden vzdálený repozitář, příkaz je vypíše všechny. Například můj repozitář Grit vypadá takto: +Pokud používáte více než jeden vzdálený repozitář, příkaz je vypíše všechny. Například můj repozitář Grit vypadá takto: $ cd grit $ git remote -v @@ -747,11 +843,11 @@ Pokud máte více než jeden vzdálený repozitář, příkaz je vypíše všech koke git://github.com/koke/grit.git origin git@github.com:mojombo/grit.git -To znamená, že můžeme velmi snadno stáhnout příspěvky od kteréhokoli z těchto uživatelů. Nezapomeňte však, že pouze vzdálený server origin je SSH URL, a je tedy jediným repozitářem, kam lze posílat soubory (důvod objasníme v kapitole 4). +To znamená, že mohu velmi snadno stáhnout příspěvky od kteréhokoli z těchto uživatelů. Ale všimněte si, že pouze vzdálený server origin je SSH URL, a je tedy jediným repozitářem, kam lze soubory odesílat (push; důvod objasníme v *kapitole 4*). ### Přidávání vzdálených repozitářů ### -V předchozích částech už jsem se letmo dotkl přidávání vzdálených repozitářů. V této části se dostávám k tomu, jak přesně při přidávání postupovat. Chcete-li přidat nový vzdálený repozitář Git ve formě zkráceného názvu, na nějž lze snadno odkazovat, spusťte příkaz `git remote add [zkrácený název] [url]`: +V předchozích částech už jsem se letmo dotkl přidávání vzdálených repozitářů. V této části se dostávám k tomu, jak přesně při přidávání postupovat. Chcete-li přidat nový vzdálený repozitář Git a zadat zkrácený název, přes který se můžete snadno odkazovat, spusťte příkaz `git remote add [zkrácený název] [url]`: $ git remote origin @@ -771,7 +867,7 @@ V předchozích částech už jsem se letmo dotkl přidávání vzdálených rep * [new branch] master -> pb/master * [new branch] ticgit -> pb/ticgit -Paulova hlavní větev (master branch) je lokálně dostupná jako `pb/master`. Můžete ji začlenit do některé ze svých větví nebo tu můžete provést checkout lokální větve, jestliže si ji chcete prohlédnout. +Paulova hlavní větev (master branch) je teď lokálně dostupná jako `pb/master`. Můžete ji začlenit (merge) do některé ze svých větví, nebo ji můžete zpřístupnit jako lokální větev (check out), jestliže si ji chcete prohlédnout. ### Vyzvedávání a stahování ze vzdálených repozitářů ### @@ -779,19 +875,19 @@ Jak jste právě viděli, data ze vzdálených projektů můžete získat pomoc $ git fetch [název vzdáleného repozitáře] -Příkaz zamíří do vzdáleného projektu a stáhne z něj všechna data, která ještě nevlastníte. Poté byste měli mít reference na všechny větve tohoto vzdáleného projektu. Nyní je můžete kdykoli slučovat nebo prohlížet. (Podrobněji se budeme větvím a jejich použití věnovat v kapitole 3.) +Příkaz zamíří do vzdáleného projektu a stáhne z něj všechna data, která ještě nemáte u sebe. Poté byste měli mít k dispozici odkazy na všechny větve tohoto vzdáleného projektu. Od toho okamžiku je můžete kdykoli slučovat nebo prohlížet. (Podrobněji se budeme větvím a jejich použití věnovat v *kapitole 3*.) -Pokud jste naklonovali repozitář, příkaz automaticky přiřadí tento vzdálený repozitář pod název „origin“. Příkaz `git fetch origin` tak vyzvedne veškerou novou práci, která byla na server poslána (push) od okamžiku, kdy jste odsud klonovali (popř. odsud naposledy vyzvedávali práci). Měli bychom zmínit, že příkaz `fetch` stáhne data do vašeho lokálního repozitáře, v žádném případě ale data automaticky nesloučí s vaší prací ani jinak nezmění nic z toho, na čem právě pracujete. Data ručně sloučíte se svou prací, až to uznáte za vhodné. +Pokud jste naklonovali repozitář, příkaz automaticky přidá tento vzdálený repozitář pod názvem *origin*. Takže příkaz `git fetch origin` vyzvedne veškerou novou práci, která byla na uvedený server poslána (push) od okamžiku, kdy jste odtud klonovali (nebo kdy jste odtud naposledy vyzvedávali práci). Měli bychom zmínit, že příkaz `fetch` stáhne data do vašeho lokálního repozitáře. V žádném případě ale data automaticky nesloučí s vaší prací ani jinak nezmění nic z toho, na čem právě pracujete. Sloučení s vaší prací musíte udělat ručně, až to uznáte za vhodné. -Pokud máte větev nastavenou ke sledování vzdálené větve (více informací naleznete v následující části a v kapitole 3), můžete použít příkaz `git pull`, který automaticky vyzvedne a poté začlení vzdálenou větev do vaší aktuální větve. Tento postup pro vás může být snazší a pohodlnější. Standardně přitom příkaz `git clone` automaticky nastaví vaši lokální hlavní větev, aby sledovala vzdálenou hlavní větev na serveru, z nějž jste klonovali (za předpokladu, že má vzdálený server hlavní větev). Příkaz `git pull` většinou vyzvedne data ze serveru, z nějž jste původně klonovali, a automaticky se pokusí začlenit je do kódu, na němž právě pracujete. +Pokud máte větev nastavenou ke sledování vzdálené větve (více informací naleznete v následující části a v *kapitole 3*), můžete použít příkaz `git pull`, který automaticky vyzvedne (fetch) a poté začlení (merge) vzdálenou větev do vaší aktuální větve. Tento postup pro vás může být snazší a pohodlnější. Standardně přitom příkaz `git clone` automaticky nastaví vaši lokální hlavní větev, aby sledovala vzdálenou hlavní větev na serveru, z kterého jste klonovali (za předpokladu, že má vzdálený server hlavní větev). Příkaz `git pull` většinou vyzvedne data ze serveru, z něhož jste původně klonovali, a automaticky se pokusí začlenit je do kódu, na němž právě pracujete. -### Posílání do vzdálených repozitářů ### +### Odesílání do vzdálených repozitářů ### -Pokud se váš projekt nachází ve fázi, kdy ho chcete sdílet s ostatními, můžete ho odeslat (push) na vzdálený server. Příkaz pro tuto akci je jednoduchý: `git push [název vzdáleného repozitáře] [název větve]`. Pokud chcete poslat svou hlavní větev na server `origin` (i tady platí, že proces klonování vám nastaví názvy `master` i `origin` automaticky), můžete k odeslání své práce na server použít tento příkaz: +Pokud se váš projekt nachází ve stavu, kdy ho chcete sdílet s ostatními, můžete ho odeslat (push) na vzdálený server. Příkaz pro tuto akci je jednoduchý: `git push [název vzdáleného repozitáře] [název větve]`. Pokud chcete poslat svou hlavní větev na server `origin` (i tady platí, že proces klonování vám nastaví názvy `master` i `origin` automaticky), můžete k odeslání své práce na server použít tento příkaz: $ git push origin master -Tento příkaz bude funkční, pouze pokud jste klonovali ze serveru, k němuž máte oprávnění pro zápis, a pokud sem od vašeho klonování nikdo neposílal svou práci. Pokud spolu s vámi provádí současně klonování ještě někdo další a ten poté svou práci odešle na server, vaše později odesílaná práce bude oprávněně odmítnuta. Nejprve musíte stáhnout práci ostatních a začlenit ji do své, teprve potom vám server umožní odeslání. Více informací o odesílání na vzdálené servery najdete v kapitole 3. +Tento příkaz bude funkční, pouze pokud jste klonovali ze serveru, k němuž máte oprávnění pro zápis, a pokud sem od vašeho klonování nikdo neposílal svou práci. Pokud spolu s vámi provádí současně klonování ještě někdo další a ten poté svou práci odešle na server, vaše později odesílaná práce bude oprávněně odmítnuta. Nejprve musíte stáhnout práci ostatních a začlenit ji do své, teprve potom vám server umožní odeslání. Více informací o odesílání na vzdálené servery najdete v *kapitole 3*. ### Prohlížení vzdálených repozitářů ### @@ -806,9 +902,9 @@ Jestliže chcete získat více informací o konkrétním vzdáleném repozitář master ticgit -Bude obsahovat adresu URL vzdáleného repozitáře a informace ke sledování větví. Příkaz vám mimo jiné sděluje, že pokud se nacházíte na hlavní větvi (branch master) a spustíte příkaz `git pull`, automaticky začlení (merge) práci do hlavní větve na vzdáleném serveru, jakmile vyzvedne všechny vzdálené reference. Součástí výpisu jsou také všechny vzdálené reference, které příkaz stáhl. +Bude obsahovat adresu URL vzdáleného repozitáře a informace ke sledování větví. Příkaz vám mimo jiné sděluje, že pokud se nacházíte na hlavní větvi (branch `master`) a spustíte příkaz `git pull`, pak se po vyzvednutí všech vzdálených referencí (fetch) práce z hlavní větve na vzdáleném serveru automaticky začlení (merge). Součástí výpisu jsou také všechny vzdálené reference, které příkaz stáhl. -Toto je jednoduchý příklad, s nímž se můžete setkat. Pokud však Git používáte na pokročilé bázi, příkaz `git remote show` vám patrně zobrazí podstatně více informací: +S uvedeným jednoduchým případem se pravděpodobně setkáte. Pokud však Git používáte na intenzivněji, může vám příkaz `git remote show` zobrazit mnohem více informací: $ git remote show origin * remote origin @@ -832,11 +928,11 @@ Toto je jednoduchý příklad, s nímž se můžete setkat. Pokud však Git pou Local branch pushed with 'git push' master:master -Tento příkaz vám ukáže, která větev bude automaticky odeslána, pokud spustíte příkaz `git push` na určitých větvích. Příkaz vám také oznámí, které vzdálené větve na serveru ještě nemáte, které vzdálené větve máte, jež už byly ze serveru odstraněny, a několik větví, které budou automaticky sloučeny, jestliže spustíte příkaz `git pull`. +Tento příkaz ukazuje, která větev bude automaticky odeslána, pokud spustíte příkaz `git push` na určitých větvích. Příkaz vám také oznámí, které vzdálené větve na serveru ještě nemáte, které vzdálené větve máte, ale ze serveru už byly odstraněny, a několik větví, které budou automaticky sloučeny, jestliže spustíte příkaz `git pull`. -### Přesouvání a přejmenovávání vzdálených repozitářů ### +### Odstraňování a přejmenovávání vzdálených repozitářů ### -Chcete-li přejmenovat vzdálený repozitář, můžete v novějších verzích systému Git spustit příkaz `git remote rename`. Příkazem lze změnit zkrácený název vzdáleného repozitáře. Pokud například chcete přejmenovat repozitář z `pb` na `paul`, můžete tak učinit pomocí příkazu `git remote rename`: +Chcete-li změnit zkrácené jméno vzdáleného repozitáře, můžete v novějších verzích systému Git spustit příkaz `git remote rename`. Pokud například chcete přejmenovat repozitář z `pb` na `paul`, můžete tak učinit příkazem `git remote rename`: $ git remote rename pb paul $ git remote @@ -845,7 +941,7 @@ Chcete-li přejmenovat vzdálený repozitář, můžete v novějších verzích Za zmínku stojí, že tímto příkazem změníte zároveň i názvy vzdálených větví. Z původní reference `pb/master` se tak nyní stává `paul/master`. -Chcete-li, ať už z jakéhokoli důvodu, odstranit referenci (např. jste přesunuli server nebo už nepoužíváte dané zrcadlo, popř. přispěvatel přestal přispívat), můžete využít příkaz `git remote rm`: +Chcete-li, ať už z jakéhokoli důvodu, odstranit referenci (přesunuli jste například server nebo už nepoužíváte dané zrcadlo, nebo třeba přispěvatel přestal přispívat), můžete využít příkaz `git remote rm`: $ git remote rm paul $ git remote @@ -853,7 +949,7 @@ Chcete-li, ať už z jakéhokoli důvodu, odstranit referenci (např. jste přes ## Značky ## -Stejně jako většina systémů VCS nabízí i Git možnost označovat v historii určitá místa, jež považujete za důležitá. Tato funkce se nejčastěji používá k označení jednotlivých vydání (např. `v1.0`). V této části vysvětlíme, jak pořídíte výpis všech dostupných značek, jak lze vytvářet značky nové a jaké typy značek se vám nabízejí. +Stejně jako většina systémů VCS nabízí i Git možnost označovat v historii určitá místa, jež považujete za důležitá. Tato funkce se nejčastěji používá k označení jednotlivých vydání (například `v1.0`). V této části vysvětlíme, jak pořídíte výpis všech dostupných značek, jak lze vytvářet značky nové a jaké typy značek se vám nabízejí. ### Výpis značek ### @@ -897,6 +993,7 @@ Informace značky se zobrazí spolu s revizí, kterou značka označuje, po zad Date: Mon Feb 9 14:45:11 2009 -0800 my version 1.4 + commit 15027957951b64cf874c3557a0f3547bd83b3ff6 Merge: 4a447f7... a6b4c97... Author: Scott Chacon @@ -1030,7 +1127,7 @@ Můžete se podívat, že jste revizi označil: ### Sdílení značek ### -Příkaz `git push` nepřenáší značky na vzdálené servery automaticky. Pokud jste vytvořili značku, budete ji muset na sdílený server poslat ručně. Tento proces je stejný jako sdílení vzdálených větví. Spusťte příkaz `git push origin [název značky]`. +Příkaz `git push` nepřenáší značky na vzdálené servery automaticky. Pokud jste vytvořili značku, budete ji muset na sdílený server poslat explicitně. Tento proces je stejný jako sdílení vzdálených větví. Spusťte příkaz `git push origin [název značky]`. $ git push origin v1.5 Counting objects: 50, done. @@ -1058,17 +1155,17 @@ Pokud nyní někdo bude klonovat nebo stahovat z vašeho repozitáře, stáhne r ## Tipy a triky ## -Než ukončíme tuto kapitolu o základech práce se systémem Git, přidáme ještě pár tipů a triků, které vám mohou usnadnit či zpříjemnit práci. Mnoho uživatelů pracuje se systémem Git, aniž by tyto triky znali a používali. V dalších částech knihy se už o nich nebudeme zmiňovat ani nebudeme předpokládat, že je používáte. Přesto pro vás mohou být užitečné. +Než ukončíme tuto kapitolu věnovanou základům práce se systémem Git, přidáme ještě pár tipů a triků, které vám mohou usnadnit či zpříjemnit práci. Mnoho uživatelů pracuje se systémem Git, aniž by tyto triky znali a používali. V dalších částech knihy se už o nich nebudeme zmiňovat ani nebudeme předpokládat, že je používáte. Přesto pro vás mohou být užitečné. ### Automatické dokončování ### -Jestliže používáte shell Bash, nabízí vám Git možnost zapnout si skript automatického dokončování. Stáhněte si zdrojový kód Git a podívejte se do adresáře `contrib/completion`. Měli byste tam najít soubor s názvem `git-completion.bash`. Zkopírujte tento soubor do svého domovského adresáře a přidejte ho do souboru `.bashrc`: +Jestliže používáte shell Bash, nabízí vám Git možnost zapnout si skript pro automatické dokončování. Stáhněte si jej ze zdrojových textů systému Git z https://github.com/git/git/blob/master/contrib/completion/git-completion.bash. Soubor nakopírujte tento do vašeho domovského adresáře a do souboru `.bashrc` přidejte: - source ~/.git-completion.bash + source ~/git-completion.bash -Chcete-li nastavit Git tak, aby měl automaticky dokončování pro shell Bash pro všechny uživatele, zkopírujte tento skript do adresáře `/opt/local/etc/bash_completion.d` v systémech Mac nebo do adresáře `/etc/bash_completion.d/` v systémech Linux. Toto je adresář skriptů, z nějž Bash automaticky načítá pro shellové dokončování. +Chcete-li nastavit Git tak, aby měl automaticky dokončování pro shell Bash pro všechny uživatele, zkopírujte u systému Mac tento skript do adresáře `/opt/local/etc/bash_completion.d`, nebo u systémů Linux do adresáře `/etc/bash_completion.d/`. Jde o adresář skriptů, ze kterého si Bash automaticky načítá podporu pro shellové dokončování. -Pokud používáte Git Bash v systému Windows (Git Bash je výchozím programem při instalaci systému Git v OS Windows pomocí msysGit), mělo by být automatické dokončování přednastaveno. +Pokud používáte Git Bash v systému Windows (Git Bash je pro instalaci msysGit pod Windows výchozím programem), mělo by být automatické dokončování přednastaveno. Při zadávání příkazu Git stiskněte klávesu Tab a měla by se objevit nabídka, z níž můžete zvolit příslušné dokončení: @@ -1077,7 +1174,7 @@ Při zadávání příkazu Git stiskněte klávesu Tab a měla by se objevit nab Pokud zadáte – stejně jako v našem příkladu nahoře – `git co` a dvakrát stisknete klávesu Tab, systém vám navrhne „commit“ a „config“. Doplníte-li ještě `m`, skript automaticky dokončí příkaz na `git commit`. -Automatické dokončování pravděpodobně více využijete v případě parametrů. Pokud například zadáváte příkaz `git log` a nemůžete si vzpomenout na některý z parametrů, můžete zadat jeho začátek a stisknout klávesu Tab, aby vám systém navrhl možná dokončení. +Automatické dokončování pravděpodobně více využijete v případě parametrů. Pokud například zadáváte příkaz `git log` a nemůžete si vzpomenout na některý z parametrů, můžete zadat jeho začátek, stisknout klávesu Tab a podívat se, co by to mohlo přesně být: $ git log --s --shortstat --since= --src-prefix= --stat --summary diff --git a/cs/03-git-branching/01-chapter3.markdown b/cs/03-git-branching/01-chapter3.markdown index 808bcb086..95f3afe98 100644 --- a/cs/03-git-branching/01-chapter3.markdown +++ b/cs/03-git-branching/01-chapter3.markdown @@ -1,23 +1,23 @@ # Větve v systému Git # -Téměř každý systém VCS podporuje do určité míry větvení. Větvení znamená, že se můžete odloučit od hlavní linie vývoje a pokračovat v práci, aniž byste tuto hlavní linii zanášeli. V mnoha VCS nástrojích se může jednat o poněkud náročný proces, který často vyžaduje vytvoření nové kopie adresáře se zdrojovým kódem. To může – zvláště u velkých projektů – trvat poměrně dlouho. +Téměř každý systém pro správu verzí podporuje do určité míry větvení. Větvení znamená, že se můžete odloučit od hlavní linie vývoje a pokračovat v práci, aniž byste hlavní linii zanášeli smetím. V mnoha VCS nástrojích se může jednat o poněkud náročný proces, který často vyžaduje vytvoření nové kopie adresáře se zdrojovým kódem. To může – zvláště u velkých projektů – trvat poměrně dlouho. -Někteří lidé mluví o modelu větvení v systému Git jako o jeho exkluzivní funkci. Není sporu o tom, že je Git díky tomuto modelu v komunitě VCS poměrně jedinečný. V čem je jeho větvení ojedinělé? Větvení je v systému Git neuvěřitelně lehké a operace s ním související probíhají téměř okamžitě. Stejně rychlé je i přepínání mezi jednotlivými větvemi. Na rozdíl od ostatních systémů VCS Git podporuje způsob práce s bohatým větvením a častým slučováním, a to i několikrát za den. Pokud tuto funkci pochopíte a zvládnete její ovládání, dostanete do ruky výkonný a unikátní nástroj, který doslova změní váš pohled na vývoj. +Někteří lidé mluví o modelu větvení v systému Git jako o převratné vlastnosti. Není sporu o tom, že je Git díky tomu ve skupině systémů pro správu verzí poměrně jedinečný. V čem je jeho větvení tak zvláštní? Větvení je v systému Git neuvěřitelně snadné a operace s ním související probíhají téměř okamžitě. A stejně rychlé je i přepínání mezi jednotlivými větvemi. Na rozdíl od ostatních systémů pro správu verzí vybízí Git ke způsobu práce s bohatým větvením a častým slučováním, a to i několikrát za den. Pokud tuto funkci pochopíte a zvládnete její ovládání, dostanete do ruky výkonný a unikátní nástroj, který doslova změní váš pohled na vývoj. ## Co je to větev ## Abychom skutečně pochopili, jak funguje v systému Git větvení, budeme se muset vrátit o krok zpět a podívat se, jak Git ukládá data. Jak si možná vzpomínáte z kapitoly 1, Git neukládá data jako sérii změn nebo rozdílů, ale jako sérii snímků. -Zapíšete-li v systému Git revizi, Git uloží objekt revize, obsahující ukazatel na snímek obsahu, který jste určili k zapsání, metadata o autorovi a zprávě a nula nebo více ukazatelů na revizi nebo revize, které byly přímými rodiči této revize – žádné rodiče nemá první revize, jednoho rodiče má běžná revize a několik rodičů mají revize, které vznikly sloučením ze dvou či více větví. +Zapíšete-li v systému Git revizi, Git uloží objekt revize, obsahující ukazatel na snímek obsahu, který jste určili k zapsání, metadata o autorovi a zprávě a nula nebo více ukazatelů na revizi nebo revize, které byly přímými rodiči této revize: žádné rodiče nemá první revize, jednoho rodiče má běžná revize a několik rodičů mají revize, které vznikly sloučením ze dvou či více větví. -Pro ilustraci předpokládejme, že máte adresář se třemi soubory, které připravíte k zapsání a následně zapíšete. S připravením souborů k zapsání proběhne u každého z nich kontrolní součet (o otisku SHA-1 jsme se zmínili v kapitole 1), daná verze souborů se uloží v repozitáři Git (Git na ně odkazuje jako na bloby) a přidá jejich kontrolní součet do oblasti připravených změn: +Pro ilustraci předpokládejme, že máte adresář se třemi soubory, které připravíte k zapsání a následně zapíšete. Při přípravě souborů k zapsání je pro každý z nich vypočítán kontrolní součet (o otisku SHA-1 jsme se zmínili v kapitole 1), daná verze souborů se uloží v repozitáři Git (Git na ně odkazuje jako na bloby) a přidá jejich kontrolní součet do oblasti připravených změn: $ git add README test.rb LICENSE $ git commit -m 'initial commit of my project' Vytvoříte-li revizi příkazem `git commit`, provede Git kontrolní součet každého adresáře (v tomto případě pouze kořenového adresáře projektu) a uloží tyto objekty stromu v repozitáři Git. Poté vytvoří objekt revize s metadaty a ukazatelem na kořenový strom projektu, aby mohl v případě potřeby tento snímek obnovit. -Váš repozitář Git nyní obsahuje pět objektů: jeden blob pro obsah každého ze tří vašich souborů, jeden strom, který zaznamenává obsah adresáře a udává, které názvy souborů jsou uloženy jako který blob, a jednu revizi s ukazatelem na kořenový strom a se všemi metadaty revize. Data ve vašem repozitáři Git se dají schematicky znázornit jako na obrázku 3-1. +Váš gitovský repozitář nyní obsahuje pět objektů: jeden blob pro obsah každého ze tří vašich souborů, jeden strom, který zaznamenává obsah adresáře a udává, které názvy souborů jsou uloženy jako který blob, a jeden objekt revize s ukazatelem na kořenový strom a se všemi metadaty revize. Data ve vašem repozitáři Git se dají schematicky znázornit jako na obrázku 3-1. Insert 18333fig0301.png Obrázek 3-1. Repozitář s daty jedné revize @@ -41,7 +41,7 @@ Tento příkaz vytvoří nový ukazatel na stejné revizi, na níž se právě n Insert 18333fig0304.png Obrázek 3-4. Několik větví ukazujících do historie dat revizí -Jak Git pozná, na jaké větvi se právě nacházíte? Používá speciální ukazatel zvaný HEAD. Nenechte se mást, tento HEAD je velmi odlišný od všech koncepcí v ostatních systémech VCS, na něž jste možná zvyklí, jako Subversion nebo CVS. V systému Git se jedná o ukazatel na lokální větev, na níž se právě nacházíte. V našem případě jste však stále ještě na hlavní větvi. Příkazem git branch jste pouze vytvořili novou větev, zatím jste na ni nepřepnuli (viz obrázek 3-5). +Jak Git pozná, na jaké větvi se právě nacházíte? Používá speciální ukazatel zvaný HEAD. Nenechte se mást, tento HEAD je velmi odlišný od všech koncepcí v ostatních systémech pro správu verzí, na něž jste možná zvyklí, jako Subversion nebo CVS. V systému Git se jedná o ukazatel na lokální větev, na níž se právě nacházíte. V našem případě jste však stále ještě na hlavní větvi. Příkazem `git branch` jste pouze vytvořili novou větev, zatím jste na ni nepřepnuli (viz obrázek 3-5). Insert 18333fig0305.png Obrázek 3-5. Soubor HEAD ukazující na větev, na níž se nacházíte. @@ -86,11 +86,11 @@ Nyní se historie vašeho projektu rozdělila (viz obrázek 3-9). Vytvořili jst Insert 18333fig0309.png Obrázek 3-9. Historie větví se rozdělila. -Vzhledem k tomu, že větev v systému Git tvoří jeden jednoduchý soubor, obsahující 40 znaků kontrolního součtu SHA-1 revize, na niž ukazuje, je snadné větve vytvářet i odstraňovat. Vytvořit novou větev je právě tak snadné a rychlé jako zapsat 41 bytů do souboru (40 znaků a jeden nový řádek). +Vzhledem k tomu, že větev v systému Git tvoří jeden jednoduchý soubor, obsahující 40 znaků kontrolního součtu SHA-1 revize, na niž ukazuje, je snadné větve vytvářet i odstraňovat. Vytvořit novou větev je právě tak snadné a rychlé jako zapsat 41 bytů do souboru (40 znaků a jeden znak pro nový řádek). Tato metoda se výrazně liší od způsobu, jakým probíhá větvení v ostatních nástrojích VCS, kde je nutné zkopírovat všechny soubory projektu do jiného adresáře. To může zabrat – podle velikosti projektu – několik sekund i minut, zatímco v systému Git probíhá tento proces vždy okamžitě. A protože při zapisování revize zaznamenáváme její rodiče, probíhá vyhledávání příslušné základny pro sloučení automaticky a je většinou velmi snadné. Tyto funkce slouží k tomu, aby se vývojáři nebáli vytvářet a používat nové větve. -Podívejme se, jaké výhody jim z toho plynou. +Podívejme se, proč byste to měli dělat také tak. ## Základy větvení a slučování ## @@ -100,7 +100,7 @@ Vytvořme si jednoduchý příklad větvení a slučování s pracovním postupe 2. Vytvoříte větev pro novou část stránek, v níž budete pracovat. 3. Vytvoříte práci v této větvi. -V tomto okamžiku vám zavolají, že se vyskytla jiná kritická chyba, která vyžaduje hotfix. Uděláte následující: +V tomto okamžiku vám zavolají, že se vyskytla jiná kritická chyba, která vyžaduje rychlou opravu (hotfix). Uděláte následující: 1. Vrátíte se zpět na produkční větev. 2. Vytvoříte větev pro přidání hotfixu. @@ -117,7 +117,7 @@ Obrázek 3-10. Krátká a jednoduchá historie revizí Rozhodli jste se, že budete pracovat na chybě č. 53, ať už vaše společnost používá jakýkoli systém sledování chyb. Přesněji řečeno, Git není začleněn do žádného konkrétního systému sledování chyb, ale protože je chyba č. 53 významná a chcete na ní pracovat, vytvoříte si pro ni novou větev. Abyste vytvořili novou větev a rovnou na ni přepnuli, můžete spustit příkaz `git checkout` s přepínačem `-b`: $ git checkout -b iss53 - Switched to a new branch "iss53" + Switched to a new branch 'iss53' Tímto způsobem jste spojili dva příkazy: @@ -129,43 +129,43 @@ Obrázek 3-11 ukazuje výsledek. Insert 18333fig0311.png Obrázek 3-11. Vytvoření nového ukazatele na větev -Pracujete na webových stránkách a zapíšete několik revizí. S každou novou revizí se větev `iss53` posune vpřed, protože jste provedli její checkout (to znamená, že jste na ni přepnuli a ukazuje na ni soubor HEAD – viz obrázek 3-12): +Pracujete na webových stránkách a zapíšete několik revizí. S každou novou revizí se větev `iss53` posune vpřed, protože jste provedli její checkout (to znamená, že na ni přepnuli ukazuje HEAD – viz obrázek 3-12): $ vim index.html - $ git commit -a -m 'added a new footer [issue 53]' + $ git commit -a -m 'add a new footer [issue 53]' Insert 18333fig0312.png Obrázek 3-12. Větev iss53 se s vaší prací posouvá vpřed. V tomto okamžiku vám zavolají, že se na webových stránkách vyskytl problém, který musíte okamžitě vyřešit. Jelikož pracujete v systému Git, nemusíte svou opravu vytvářet uprostřed změn, které jste provedli v části `iss53`, ani nemusíte dělat zbytečnou práci, abyste všechny tyto změny vrátili, než budete moci začít pracovat na opravě produkční verze stránek. Jediné, co teď musíte udělat, je přepnout zpět na hlavní větev. -Než tak učiníte, zkontrolujte, zda nemáte v pracovním adresáři nebo v oblasti připravených změn nezapsané změny, které kolidují s větví, jejíž checkout provádíte. V takovém případě by vám Git přepnutí větví nedovolil. Při přepínání větví je ideální, pokud máte čistý pracovní stav. Existují způsoby, jak toho docílit (jmenovitě odložení a doplnění revize), těm se však budeme věnovat až později. Pro tuto chvíli jste zapsali všechny provedené změny a můžete přepnout zpět na hlavní větev. +Než tak učiníte, zkontrolujte, zda nemáte v pracovním adresáři nebo v oblasti připravených změn nezapsané změny, které kolidují s větví, jejíž checkout provádíte. V takovém případě by vám Git přepnutí větví nedovolil. Při přepínání větví je ideální, pokud máte čistý pracovní stav. Existují způsoby, jak to obejít (jmenovitě odložení (stashing) a doplnění revize (commit amending)), těm se však budeme věnovat až později. Pro tuto chvíli jste zapsali všechny provedené změny a můžete přepnout zpět na hlavní větev. $ git checkout master - Switched to branch "master" + Switched to branch 'master' -V tomto okamžiku vypadá váš pracovní adresář přesně tak, jak vypadal, než jste začali pracovat na chybě č. 53, a vy se nyní můžete soustředit na rychlou opravu. Na paměti byste však stále měli mít následující: Git vždy vrátí pracovní adresář do stejného stavu, jak vypadal snímek revize, na niž ukazuje větev, jejíž checkout nyní provádíte. Automaticky budou přidány, odstraněny a upraveny soubory tak, aby byla vaše pracovní kopie totožná se stavem větve v okamžiku, kdy jste na ni zapsali poslední revizi. +V tomto okamžiku vypadá váš pracovní adresář přesně tak, jak vypadal, než jste začali pracovat na chybě č. 53, a vy se nyní můžete soustředit na rychlou opravu. Tento důležitý bod si zapamatujte: Git vždy vrátí pracovní adresář do stejného stavu, jak vypadal snímek revize, na niž ukazuje větev, jejíž checkout nyní provádíte. Automaticky budou přidány, odstraněny a upraveny soubory tak, aby byla vaše pracovní kopie totožná se stavem větve v okamžiku, kdy jste na ni zapsali poslední revizi. Nyní přichází na řadu hotfix. Vytvořme větev s hotfixem, v níž budeme pracovat, dokud nebude oprava hotová (viz obrázek 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(-) + $ git commit -a -m 'fix the broken email address' + [hotfix 3a0874c] fix the broken email address + 1 files changed, 1 deletion(-) Insert 18333fig0313.png Obrázek 3-13. Větev „hotfix“ začleněná zpět v místě hlavní větve -Můžete provádět testování, ujistit se, že hotfix splňuje všechny požadavky, a pak můžete větev začlenit (merge) zpět do hlavní větve, aby byla připravena do produkce. Učiníte tak příkazem `git merge`: +Můžete spustit testy, abyste se ujistili, že hotfix splňuje všechny požadavky, a pak můžete větev začlenit (merge) zpět do hlavní větve, aby byla připravena do produkce. Učiníte tak příkazem `git merge`: $ 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(-) Při sloučení jste si možná všimli spojení „Fast forward“ (rychle vpřed). Jelikož revize, na niž ukazovala větev, do níž jste začleňovali, byla v přímé linii s revizí, na níž jste se nacházeli, Git přesunul ukazatel vpřed. Jinými slovy: pokud se pokoušíte sloučit jednu revizi s revizí druhou, k níž lze dospět následováním historie první revize, Git proces zjednoduší a přesune ukazatel vpřed, protože neexistuje žádná rozdílná práce, kterou by bylo třeba sloučit. Tomuto postupu se říká „rychle vpřed“. @@ -177,21 +177,21 @@ Obrázek 3-14. Hlavní větev ukazuje po sloučení na stejné místo jako věte Poté, co jste dokončili práci na bezodkladné opravě, můžete přepnout zpět na práci, jíž jste se věnovali před telefonátem. Nejprve však smažete větev `hotfix`, kterou teď už nebudete potřebovat – větev `master` ukazuje na totéž místo. Větev smažete přidáním parametru `-d` k příkazu `git branch`: $ git branch -d hotfix - Deleted branch hotfix (3a0874c). + Deleted branch hotfix (was 3a0874c). Nyní můžete přepnout zpět na větev s rozdělanou prací a pokračovat na chybě č. 53 (viz obrázek 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(-) + $ git commit -a -m 'finish the new footer [issue 53]' + [iss53 ad82d7a] finish the new footer [issue 53] + 1 file changed, 1 insertion(+) Insert 18333fig0315.png Obrázek 3-15. Větev iss53 může nezávisle postupovat vpřed. -Za zmínku stojí, že práce, kterou jste udělali ve větvi `hotfix`, není obsažena v souborech ve větvi `iss53`. Pokud potřebujete tyto změny do větve natáhnout, můžete začlenit větev `master` do větve `iss53` – použijte příkaz `git merge master`. Druhou možností je s integrací změn vyčkat a provést ji až ve chvíli, kdy budete chtít větev `iss53` natáhnout zpět do větve `master`. +Za zmínku stojí, že práce, kterou jste udělali ve větvi `hotfix`, není obsažena v souborech ve větvi `iss53`. Pokud potřebujete tyto změny do větve vtáhnout, můžete začlenit větev `master` do větve `iss53` provedením příkazu `git merge master`. Druhou možností je s integrací změn vyčkat a provést ji až ve chvíli, kdy budete chtít větev `iss53` vtáhnout zpět do větve `master`. ### Základní slučování ### @@ -199,9 +199,10 @@ Předpokládejme, že jste dokončili práci na chybě č. 53 a nyní byste ji r $ 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(+) Toto už se trochu liší od začlenění větve `hotfix`, které jste prováděli před chvílí. V tomto případě se historie vývoje od určitého bodu v minulosti rozbíhala. Vzhledem k tomu, že revize na větvi, na níž se nacházíte, není přímým předkem větve, kterou chcete začlenit, Git bude muset podniknout určité kroky. Git v tomto případě provádí jednoduché třícestné sloučení: vychází ze dvou snímků, na které ukazují větve, a jejich společného předka. Obrázek 3-16 označuje ony tři snímky, které Git v tomto případě použije ke sloučení. @@ -210,7 +211,7 @@ Obrázek 3-16. Git automaticky identifikuje nejvhodnějšího společného před Git tentokrát neposune ukazatel větve vpřed, ale vytvoří nový snímek jako výsledek tohoto třícestného sloučení a automaticky vytvoří novou revizi, která bude na snímek ukazovat (viz obrázek 3-17). Takové revizi se říká revize sloučením (merge commit) a její zvláštností je to, že má více než jednoho rodiče. -Na tomto místě bych chtěl zopakovat, že Git určuje nejvhodnějšího společného předka, který bude použit jako základna pro sloučení, automaticky. Liší se tím od systému CVS i Subversion (před verzí 1.5), kde musí vývojář při slučování najít nejvhodnější základnu pro sloučení sám. Slučování větví je tak v systému Git o poznání jednodušší než v těchto ostatních systémech. +Na tomto místě bych chtěl zopakovat, že Git určuje nejvhodnějšího společného předka, který bude použit jako základna pro sloučení, automaticky. Liší se tím od systému CVS i Subversion (před verzí 1.5), kde musí vývojář při slučování najít nejvhodnější základnu pro sloučení sám. Slučování větví je proto v systému Git o poznání jednodušší než v ostatních systémech. Insert 18333fig0317.png Obrázek 3-17. Git automaticky vytvoří nový objekt revize, který obsahuje sloučenou práci. @@ -230,25 +231,27 @@ Může se stát, že sloučení neproběhne bez problémů. Pokud jste tutéž Git nepřistoupil k automatickému vytvoření nové revize sloučením. Prozatím pozastavil celý proces do doby, než konflikt vyřešíte. Chcete-li kdykoli po konfliktu zjistit, které soubory zůstaly nesloučeny, spusťte příkaz `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") -Vše, co při sloučení kolidovalo a nebylo vyřešeno, je označeno jako „unmerged“ (nesloučeno). Git přidává ke kolidujícím souborům standardní poznámky o řešení konfliktů (conflict-resolution markers), takže je můžete ručně otevřít a konflikty vyřešit. Jedna část vašeho souboru bude vypadat zhruba takto: +Vše, co při sloučení kolidovalo a nebylo vyřešeno, je označeno jako „unmerged“ (nesloučeno). Git přidává ke kolidujícím souborům standardní značky pro označení konfliktů (conflict-resolution markers), takže soubor můžete ručně otevřít a konflikty vyřešit. Jedna část vašeho souboru bude vypadat zhruba takto: - <<<<<<< HEAD:index.html + <<<<<<< HEAD ======= - >>>>>>> iss53:index.html + >>>>>>> iss53 To znamená, že verze ve větvi s ukazatelem HEAD (vaše hlavní větev – v té jste se nacházeli při provádění příkazu merge) je uvedena v horní části tohoto bloku (všechno nad oddělovačem `=======`), verze obsažená ve větvi `iss53` je vše, co se nachází v dolní části. Chcete-li vzniklý konflikt vyřešit, musíte buď vybrat jednu z obou stran, nebo konflikt sloučit sami. Tento konflikt můžete vyřešit například nahrazením celého bloku tímto textem: @@ -260,12 +263,17 @@ Toto řešení obsahuje trochu z každé části a zcela jsem odstranil řádky Chcete-li k vyřešení problémů použít grafický nástroj, můžete spustit příkaz `git mergetool`, kterým otevřete příslušný vizuální nástroj pro slučování, a ten vás všemi konflikty provede: $ 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): Chcete-li použít jiný než výchozí nástroj pro slučování (Git mi v tomto případě vybral `opendiff`, protože jsem příkaz zadal v systému Mac), všechny podporované nástroje jsou uvedeny na začátku výstupu v části „merge tool candidates“ (možné nástroje pro slučování). Zadejte název nástroje, který chcete použít. V kapitole 7 probereme, jak lze tuto výchozí hodnotu pro vaše prostředí změnit. @@ -275,12 +283,12 @@ Až nástroj pro slučování zavřete, Git se vás zeptá, zda sloučení prob Ještě jednou můžete spustit příkaz `git status`, abyste si ověřili, že byly všechny konflikty vyřešeny: $ 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 + Pokud jste s výsledkem spokojeni a ujistili jste se, že všechny kolidující soubory jsou připraveny k zapsání, můžete zadat příkaz `git commit` a dokončit revizi sloučením. Zpráva revize má v takovém případě přednastavenu tuto podobu: @@ -289,9 +297,9 @@ Pokud jste s výsledkem spokojeni a ujistili jste se, že všechny kolidující 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. # @@ -331,7 +339,7 @@ Chcete-li zobrazit větve, které obsahují dosud nezačleněnou práci, spusťt Nyní se zobrazila jiná větev. Jelikož obsahuje práci, která ještě nebyla začleněna, bude pokus o její smazání příkazem `git branch -d` neúspěšný: $ 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'. Pokud chcete větev skutečně odstranit a zahodit práci, kterou obsahuje, můžete si to vynutit parametrem `-D` (jak napovídá užitečná zpráva pod řádkem s chybovým hlášením). @@ -344,7 +352,7 @@ Teď, když jste absolvovali základní seznámení s větvemi a jejich slučov Vzhledem k tomu, že Git používá jednoduché třícestné slučování, je velmi snadné začleňovat jednu větev do druhé i několikrát v rámci dlouhého časového intervalu. Můžete tak mít několik větví, které jsou stále otevřené a které používáte pro různé fáze vývojového cyklu. Pravidelně můžete začleňovat práci z jedné větve do ostatních. -Mnoho vývojářů systému Git používá pracovní postup, při němž je tato metoda zcela ideální. Ve větvi `master` mají pouze kód, který je stoprocentně stabilní — třeba jen kód, který byl nebo bude součástí vydání. Kromě ní mají další paralelní větev, pojmenovanou `develop` nebo `next`, v níž skutečně pracují nebo testují stabilitu kódu. Tato větev nemusí být nutně stabilní, ale jakmile se dostane do stabilního stavu, může být začleněna do větve `master`. Používá se k natahování tematických větví (těch dočasných, jako byla vaše větev `iss53`) ve chvíli, kdy je k tomu vše připraveno a nehrozí, že práce neprojde testy nebo bude způsobovat chyby. +Mnoho vývojářů systému Git používá pracovní postup, kdy mají ve větvi `master` pouze kód, který je stoprocentně stabilní — třeba jen kód, který byl nebo bude součástí vydání. Kromě ní mají další paralelní větev, pojmenovanou `develop` nebo `next`, v níž skutečně pracují nebo testují stabilitu kódu. Tato větev nemusí být nutně stabilní, ale jakmile se dostane do stabilního stavu, může být začleněna do větve `master`. Do ní se vtahují tématické větve (ty dočasné, jako byla vaše větev `iss53`) ve chvíli, kdy jsou připravené a je jisté, že projdou všemi testy a nezavlečou chyby. Ve skutečnosti hovoříme o ukazatelích pohybujících se vzhůru po linii revizí, které zapisujete. Stabilní větve leží v linii historie revizí níže a nové, neověřené větve se nacházejí nad nimi (viz obrázek 3-18). @@ -361,11 +369,11 @@ Není nutné používat při práci několik dlouhých větví, ale často to m ### Tematické větve ### -Naproti tomu tematické větve se vám budou hodit v projektech jakékoli velikosti. Tematická větev (topic branch) je krátkodobá větev, kterou vytvoříte a používáte pro jediný konkrétní účel nebo práci. Je to záležitost, do které byste se ve VCS asi raději nikdy nepustili, protože vytvářet a slučovat větve je v něm opravdu složité. V systému Git naopak není výjimkou vytvářet, používat, slučovat a mazat větve i několikrát denně. +Naproti tomu tematické větve se vám budou hodit v projektech jakékoli velikosti. Tematická větev (topic branch) je krátkodobá větev, kterou vytvoříte a používáte pro jediný konkrétní účel nebo práci. Je to záležitost, do které byste se v jiném systému pro správu verzí asi raději nikdy nepustili, protože vytvářet a slučovat větve je v něm opravdu složité. V systému Git naopak není výjimkou vytvářet, používat, slučovat a mazat větve i několikrát denně. -Viděli jste to v předchozí části, kdy jste si vytvořili větve `iss53` a `hotfix`. Provedli jste v nich pár revizí a smazali jste je hned po začlenění změn do hlavní větve. Tato technika umožňuje rychlé a kompletní kontextové přepínání. Protože je vaše práce rozdělena do zásobníků, kde všechny změny v jedné větvi souvisí s jedním tématem, je při kontrole kódu snazší dohledat, čeho se změny týkaly apod. Změny tu můžete uchovávat několik minut, dní i měsíců a začlenit je přesně ve vhodnou chvíli. Na pořadí, v jakém byly větve vytvořeny nebo vyvíjeny, nezáleží. +Viděli jste to v předchozí části, kdy jste si vytvořili větve `iss53` a `hotfix`. Provedli jste v nich pár revizí a smazali jste je hned po začlenění změn do hlavní větve. Tato technika umožňuje rychlé a snadné kontextové přepínání. Protože je vaše práce rozdělena do zásobníků, kde všechny změny v jedné větvi souvisí s jedním tématem, je při kontrole kódu snazší dohledat, čeho se změny týkaly apod. Změny tu můžete uchovávat několik minut, dní i měsíců a začlenit je přesně ve vhodnou chvíli. Na pořadí, v jakém byly větve vytvořeny nebo vyvíjeny, nezáleží. -Uvažujme nyní následující situaci: pracujete na projektu v hlavní větvi (`master`), odbočíte z ní k vyřešení jednoho problému (`iss91`), chvíli na něm pracujete, ale vytvoříte ještě další větev, abyste zkusili jiné řešení stejné chyby (`iss91v2`). Pak se vrátíte zpět na hlavní větev, kde pokračujete v práci, než dostanete nápad, který by se možná mohl osvědčit, a tak pro něj vytvoříte další větev (`dumbidea`). Historie revizí bude vypadat zhruba jako na obrázku 3-20. +Uvažujme nyní následující situaci: pracujete na projektu v hlavní větvi (`master`), odvětvíme se z ní k vyřešení jednoho problému (`iss91`), chvíli na něm pracujete, ale vytvoříte ještě další větev, abyste zkusili jiné řešení stejné chyby (`iss91v2`). Pak se vrátíte zpět do hlavní větve, kde pokračujete v práci, a pak dostanete nápad, který by se možná mohl osvědčit, a tak pro něj vytvoříte další větev (`dumbidea`). Historie revizí bude vypadat zhruba jako na obrázku 3-20. Insert 18333fig0320.png Obrázek 3-20. Historie revizí s několika tematickými větvemi @@ -381,7 +389,7 @@ Při tom všem, co nyní děláte, je důležité mít na paměti, že všechny Vzdálené větve jsou reference (tj. odkazy) na stav větví ve vašich vzdálených repozitářích. Jsou to lokální větve, které nemůžete přesouvat. Přesouvají se automaticky při síťové komunikaci. Vzdálené větve slouží jako záložky, které vám připomínají, kde byly větve ve vzdálených repozitářích, když jste se k nim naposledy připojili. -Vzdálené větve mají podobu `(vzdálený repozitář)/(větev)`. Například: Chcete-li zjistit, jak vypadala větev `master` na vašem vzdáleném serveru `origin`, když jste s ní naposledy komunikovali, budete hledat větev `origin/master`. Pokud pracujete s kolegou na stejném problému a on odešle na server větev s názvem `iss53`, může se stát, že i vy máte jednu z lokálních větví pojmenovanou jako `iss53`. Větev na serveru však ukazuje na revizi označenou jako `origin/iss53`. +Vzdálené větve mají podobu `(vzdálený repozitář)/(větev)`. Pokud například chcete zjistit, jak vypadala větev `master` na vašem vzdáleném serveru `origin`, když jste s ní naposledy komunikovali, budete hledat větev `origin/master`. Pokud pracujete s kolegou na stejném problému a on odešle na server větev s názvem `iss53`, může se stát, že i vy máte jednu z lokálních větví pojmenovanou jako `iss53`. Větev na serveru však ukazuje na revizi označenou jako `origin/iss53`. Mohlo by to být trochu matoucí, takže si uveďme příklad. Řekněme, že máte v síti server Git označený `git.ourcompany.com`. Pokud provedete klonování z tohoto serveru, Git ho automaticky pojmenuje `origin`, stáhne z něj všechna data, vytvoří ukazatel, který bude označovat jeho větev `master`, a lokálně ji pojmenuje `origin/master`. Tuto větev nemůžete přesouvat. Git vám rovněž vytvoří vaši vlastní větev `master`, která bude začínat ve stejném místě jako větev `master` serveru `origin`. Máte tak definován výchozí bod pro svoji práci (viz obrázek 3-22). @@ -393,10 +401,10 @@ Pokud nyní budete pracovat na své lokální hlavní větvi a někdo z kolegů Insert 18333fig0323.png Obrázek 3-23. Pokud pracujete lokálně a někdo jiný odešle svou práci na vzdálený server, obě historie se rozejdou. -K synchronizaci své práce použijte příkaz `git fetch origin`. Tento příkaz zjistí, který server je „origin“ (v našem případě je to `git.ourcompany.com`), vyzvedne z něj všechna data, která ještě nemáte, a aktualizuje vaši lokální databázi. Při tom přemístí ukazatel `origin/master` na novou, aktuálnější pozici (viz obrázek 3-24). +K synchronizaci své práce použijte příkaz `git fetch origin`. Tento příkaz zjistí, který server je `origin` (v našem případě je to `git.ourcompany.com`), vyzvedne z něj všechna data, která ještě nemáte, a aktualizuje vaši lokální databázi. Při tom přemístí ukazatel `origin/master` na novou, aktuálnější pozici (viz obrázek 3-24). Insert 18333fig0324.png -Obrázek 3-24. Příkaz git fetch aktualizuje vaše reference na vzdálený server. +Obrázek 3-24. Příkaz `git fetch` aktualizuje vaše reference na vzdálený server. Abychom si mohli ukázat, jak se pracuje s několika vzdálenými servery a jak vypadají vzdálené větve takových vzdálených projektů, předpokládejme, že máte ještě další interní server Git, který při vývoji používá pouze jeden z vašich sprint teamů. Tento server se nachází na `git.team1.ourcompany.com`. Můžete ho přidat jako novou vzdálenou referenci k projektu, na němž právě pracujete – spusťte příkaz `git remote add` (viz kapitola 2). Pojmenujte tento vzdálený server jako `teamone`, což bude zkrácený název pro celou URL adresu (viz obrázek 3-25). @@ -439,28 +447,28 @@ Tady je důležité upozornit, že pokud vyzvedáváte data a stáhnete s nimi i Chcete-li začlenit tato data do své aktuální pracovní větve, spusťte příkaz `git merge origin/serverfix`. Chcete-li mít vlastní větev `serverfix`, na níž budete pracovat, můžete ji ze vzdálené větve vyvázat: $ git checkout -b serverfix origin/serverfix - Branch serverfix set up to track remote branch refs/remotes/origin/serverfix. - Switched to a new branch "serverfix" + Branch serverfix set up to track remote branch serverfix from origin. + Switched to a new branch 'serverfix' Tímto způsobem získáte lokální větev, na níž můžete pracovat a která začíná na pozici `origin/serverfix`. ### Sledující větve ### -Checkoutem lokální větve ze vzdálené větve automaticky vytvoříte tzv. Sledující větev (angl. tracking branch). Sledující větve jsou lokální větve s přímým vztahem ke vzdálené větvi. Pokud se nacházíte na Sledující větvi a zadáte příkaz `git push`, Git automaticky ví, na který server a do které větve má data odeslat. Také příkazem `git pull` zadaným na sledovací větvi vyzvednete všechny vzdálené reference a Git poté odpovídající vzdálenou větev automaticky začlení. +Checkoutem lokální větve ze vzdálené větve automaticky vytvoříte takzvanou *sledující větev* (angl. tracking branch). Sledující větve jsou lokální větve s přímým vztahem ke vzdálené větvi. Pokud se nacházíte na sledující větvi a zadáte příkaz `git push`, Git automaticky ví, na který server a do které větve má data odeslat. Také příkazem `git pull` zadaným na sledovací větvi vyzvednete všechny vzdálené reference a Git poté odpovídající vzdálenou větev automaticky začlení. -Pokud klonujete repozitář, většinou se vytvoří větev `master`, která bude sledovat větev `origin/master`. To je také důvod, proč příkazy `git push` a `git pull` fungují i bez dalších parametrů. Pokud chcete, můžete nastavit i jiné sledující větve – takové, které nebudou sledovat větve na serveru `origin` a nebudou sledovat hlavní větev `master`. Jednoduchým případem je příklad, který jste právě viděli: spuštění příkazu `git checkout -b [větev] [vzdálený server]/[větev]`. Máte-li Git ve verzi 1.6.2 nebo novější, můžete použít také zkrácenou variantu `--track`: +Pokud klonujete repozitář, většinou se vytvoří větev `master`, která bude sledovat větev `origin/master`. To je také důvod, proč příkazy `git push` a `git pull` fungují samy od sebe i bez dalších parametrů. Pokud chcete, můžete nastavit i jiné sledující větve – takové, které nebudou sledovat větve na serveru `origin` a nebudou sledovat hlavní větev `master`. Jednoduchým případem je příklad, který jste právě viděli: spuštění příkazu `git checkout -b [větev] [vzdálený server]/[větev]`. Máte-li Git ve verzi 1.6.2 nebo novější, můžete použít také zkrácenou variantu `--track`: $ git checkout --track origin/serverfix - Branch serverfix set up to track remote branch refs/remotes/origin/serverfix. - Switched to a new branch "serverfix" + Branch serverfix set up to track remote branch serverfix from origin. + Switched to a new branch 'serverfix' Chcete-li nastavit lokální větev s jiným názvem, než má vzdálená větev, můžete jednoduše použít první variantu s odlišným názvem lokální větve: $ git checkout -b sf origin/serverfix - Branch sf set up to track remote branch refs/remotes/origin/serverfix. - Switched to a new branch "sf" + Branch sf set up to track remote branch serverfix from origin. + Switched to a new branch 'sf' -Vaše lokální větev „sf“ bude nyní automaticky stahovat data ze vzdálené větve origin/serverfix a bude do ní i odesílat. +Vaše lokální větev `sf` bude nyní automaticky stahovat data ze vzdálené větve `origin/serverfix` a bude do ní i odesílat. ### Mazání vzdálených větví ### @@ -488,7 +496,7 @@ Víme, že nejjednodušším způsobem, jak integrovat větve, je příkaz `merg Insert 18333fig0328.png Obrázek 3-28. Integrace rozdělené historie sloučením větví -Existuje však ještě jiný způsob. Můžete vzít záplatu se změnou, kterou jste provedli revizí C3, a aplikovat ji na vrcholu revize C4. V systému Git se tato metoda nazývá přeskládání (rebasing). Příkazem `rebase` vezmete všechny změny, které byly zapsány na jedné větvi, a necháte je znovu provést na jiné větvi. +Existuje však ještě jiný způsob. Můžete vzít záplatu se změnou, kterou jste provedli revizí C3, a aplikovat ji na vrcholu revize C4. V systému Git se tato metoda nazývá *přeskládání* (rebasing). Příkazem `rebase` vezmete všechny změny, které byly zapsány na jedné větvi, a necháte je znovu provést na jiné větvi. V našem případě tedy provedete následující: @@ -537,7 +545,7 @@ Nyní můžete posunout hlavní větev „rychle vpřed“ (viz obrázek 3-33): Insert 18333fig0333.png Obrázek 3-33. Posun hlavní větve rychle vpřed na konec změn přeskládaných z větve client -Řekněme, že se později rozhodnete natáhnout i větev server. Větev server můžete přeskládat na hlavní větev příkazem `git rebase [základna] [tematická větev]`. Příkaz provede checkout tematické větve (v tomto případě větve `server`) a přeskládá její změny na základnu (angl. base branch, v tomto případě `master`): +Řekněme, že se později rozhodnete vtáhnout i větev server. Větev server můžete přeskládat na hlavní větev příkazem `git rebase [základna] [tematická větev]`. Příkaz provede checkout tematické větve (v tomto případě větve `server`) a přeskládá její změny na základnu (angl. base branch, v tomto případě `master`): $ git rebase master server @@ -563,9 +571,9 @@ Obrázek 3-35. Konečná historie revizí Přeskládání sice nabízí určité výhody, má však také svá úskalí. Ta se dají shrnout do jedné věty: -Neprovádějte přeskládání u revizí, které jste odeslali do veřejného repozitáře. +**Neprovádějte přeskládání u revizí, které jste odeslali do veřejného repozitáře.** -Budete-li se touto zásadou řídit, nemusíte se přeskládání obávat. V opačném případě vás čeká opovržení ostatních, rodina a přátelé vás zapřou. +Budete-li se touto zásadou řídit, nemusíte se přeskládání obávat. V opačném případě vás čeká nenávist ostatních a rodina a přátelé vás zavrhnou. Při přeskládání dat zahodíte existující revize a vytvoříte nové, které jsou jim podobné, ale přesto jiné. Pokud odešlete svou práci, ostatní si ji stáhnou a založí na nich svou práci. A vy potom tyto revize přepíšete příkazem `git rebase` a znovu je odešlete, vaši spolupracovníci do ní budou muset znovu začlenit svou práci a ve všem nastane chaos, až se pokusíte natáhnout jejich práci zpět do své. diff --git a/cs/04-git-server/01-chapter4.markdown b/cs/04-git-server/01-chapter4.markdown index 890884cc4..3dd7abd9b 100644 --- a/cs/04-git-server/01-chapter4.markdown +++ b/cs/04-git-server/01-chapter4.markdown @@ -1,22 +1,22 @@ # Git na serveru # -V této chvíli byste už měli zvládat většinu každodenních úkonů, pro něž se vyplatí Git používat. Abyste však mohli v systému Git spolupracovat s ostatními, budete potřebovat vzdálený repozitář Git. Technicky vzato sice můžete odesílat a stahovat změny z repozitářů jednotlivých spolupracovníků, tento postup ale nedoporučujeme, protože se může při troše neopatrnosti velmi snadno stát, že zapomenete, kdo na čem pracuje. Navíc chcete, aby měli vaši spolupracovníci do repozitáře přístup, i když je váš počítač offline – na společný repozitář bývá často lepší spolehnutí. Jako nejlepší metodu spolupráce s ostatními proto můžeme doporučit nastavení „neutrálního“ repozitáře, do nějž budete mít všichni přístup, budete do něj moci odesílat data a budete z něj moci stahovat. Tomuto repozitáři budeme říkat „server Git“. Jak ale zjistíte, nebývá hostování repozitáře Git nijak zvlášť náročné na zdroje, a tak nejspíš nebudete potřebovat celý server. +V této chvíli byste už měli zvládat většinu každodenních úkonů, pro něž se vyplatí Git používat. Abyste však mohli v systému Git spolupracovat s ostatními, budete potřebovat vzdálený repozitář Git. Technicky vzato sice můžete odesílat a stahovat změny z repozitářů jednotlivých spolupracovníků, tento postup ale nedoporučujeme, protože se může při troše neopatrnosti velmi snadno stát, že zapomenete, kdo na čem pracuje. Navíc chcete, aby měli vaši spolupracovníci do repozitáře přístup, i když je váš počítač vypnutý nebo odpojený – na společný repozitář bývá často lepší spolehnutí. Jako nejlepší metodu spolupráce s ostatními proto můžeme doporučit nastavení „neutrálního“ repozitáře, do nějž budete mít všichni přístup, budete do něj moci odesílat data a budete z něj moci stahovat. Tomuto repozitáři budeme říkat „gitový server“. Jak ale zjistíte, nebývá hostování gitového repozitáře nijak zvlášť náročné na zdroje, a tak nejspíš nebudete potřebovat celý server. -Spuštění serveru Git je jednoduché. Nejprve určíte, jakými protokoly má váš server komunikovat. První část této kapitoly se bude věnovat možným protokolům, jejich přednostem a nevýhodám. V dalších částech popíšeme některá typická nastavení pro použití těchto protokolů, a jak s nimi uvést server do provozu. Nakonec se podíváme na několik možností hostování pro případ, že nebudete mít chuť podstupovat martyrium s nastavováním a správou vlastního serveru a nevadí vám umístit svůj kód na cizí server. +Zprovoznění gitového serveru je jednoduché. Nejprve určíte, jakými protokoly má váš server komunikovat. První část této kapitoly se bude věnovat možným protokolům, jejich přednostem a nevýhodám. V dalších částech popíšeme některá typická nastavení pro použití těchto protokolů, a jak s nimi uvést server do provozu. Nakonec se podíváme na několik možností hostování pro případ, že nebudete mít chuť podstupovat martyrium s nastavováním a správou vlastního serveru a nevadí vám umístit svůj kód na cizí server. -Pokud víte, že nebudete chtít spravovat vlastní server, můžete přeskočit rovnou na poslední část této kapitoly a podívat se na možnosti nastavení hostovaného účtu. Pak přejděte na následující kapitolu, v níž se dočtete o různých vstupech a výstupech při práci v prostředí s distribuovanou správou zdrojového kódu. +Pokud víte, že nebudete chtít spravovat vlastní server, můžete přeskočit rovnou na poslední část této kapitoly a podívat se na možnosti nastavení hostovaného účtu. Pak přejděte na následující kapitolu, v níž se dočtete o detailech a záludnostech při práci v prostředí s distribuovanou správou zdrojového kódu. -Vzdálený repozitář je obvykle holý repozitář, tj. repozitář Git bez pracovního adresáře. Protože se repozitář používá pouze jako místo pro spolupráci, není žádný důvod, aby byl na disku načten konkrétní snímek. Jsou tu pouze uložena data systému Git. Jednoduše bychom mohli také říct, že holý repozitář je obsah adresáře `.git` vašeho projektu a nic víc. +Vzdálený repozitář je obvykle *holý repozitář* (bare repository), tj. gitový repozitář bez pracovního adresáře. Protože se repozitář používá pouze jako místo pro spolupráci, není žádný důvod, aby byl na disku načten konkrétní snímek. Jsou tu pouze uložena data systému Git. Jednoduše bychom mohli také říct, že holý repozitář je obsah adresáře `.git` vašeho projektu a nic víc. ## Protokoly ## Git může k přenosu dat používat jeden ze čtyř hlavních síťových protokolů: Local, Secure Shell (SSH), Git nebo HTTP. V této části se podíváme na to, co jsou jednotlivé protokoly zač a za jakých okolností je (ne)vhodné je použít. -Neměli bychom zamlčet ani to, že s výjimkou protokolu HTTP všechny vyžadují, aby byl na serveru nainstalován a spuštěn systém Git. +Neměli bychom zamlčet ani to, že s výjimkou protokolu HTTP všechny vyžadují, aby byl na serveru nainstalován a zprovozněn systém Git. -### Protokol Local ### +### Lokální protokol ### -Nejzákladnější variantou je protokol Local, v němž je vzdálený repozitář uložen v jiném adresáři na disku. Často se využívá v případech, kdy mají všichni z vašeho týmu přístup k vašim sdíleným souborům, např. přes připojení systému NFS, nebo – v méně pravděpodobném případě – se všichni přihlašují na jednom počítači. Tato druhá varianta není právě ideální, protože všechny instance repozitáře s kódem jsou v takovém případě umístěny v jednom počítači, čímž se zvyšuje riziko nevratné ztráty dat. +Nejzákladnější variantou je *lokální protokol* (Local protocol), v němž je vzdálený repozitář uložen v jiném adresáři na disku. Často se využívá v případech, kdy mají všichni z vašeho týmu přístup k vašim sdíleným souborům, např. přes připojení systému NFS, nebo – v méně pravděpodobném případě – se všichni přihlašují na jednom počítači. Tato druhá varianta není právě ideální, protože všechny instance repozitáře s kódem jsou v takovém případě umístěny v jednom počítači, čímž se zvyšuje riziko nevratné ztráty dat. Máte-li připojený sdílený systém souborů, můžete klonovat, odesílat a stahovat z lokálního souborového repozitáře (local file-based repository). Chcete-li takový repozitář naklonovat nebo přidat jako vzdálený repozitář do existujícího projektu, použijte jako URL cestu k repozitáři. K naklonování lokálního repozitáře můžete použít příkaz například v tomto tvaru: @@ -26,7 +26,7 @@ Nebo můžete provést následující: $ git clone file:///opt/git/project.git -Pokud na začátek URL explicitně zadáte výraz `file://`, pracuje Git trochu jinak. Pokud pouze zadáte cestu, Git se pokusí použít hardlinky nebo rovnou zkopírovat soubory, které potřebuje. Pokud zadáte výraz `file://`, Git spustí procesy, jež běžně používá k přenosu dat prostřednictvím sítě. Síť je většinou výrazně méně výkonnou metodou přenosu dat. Hlavním důvodem, proč zadat předponu `file://` je to, že tak získáte čistou kopii repozitáře bez nepotřebných referencí a objektů, např. po importu z jiného verzovacího systému a podobně (úkony správy jsou popsány v kapitole 9). My budeme používat normální cestu, neboť tato metoda je téměř vždy rychlejší. +Pokud na začátek URL explicitně zadáte výraz `file://`, pracuje Git trochu jinak. Pokud pouze zadáte cestu a zdroj i cíl se nacházejí ve stejném systému souborů, pokusí se Git použít hardlinky na potřebné objekty. Pokud se nenacházejí ve stejném systému souborů, dojde k okopírování potřebných objektů pomocí standardních prostředků systému pro kopírování. Pokud zadáte výraz `file://`, Git spustí procesy, jež běžně používá k přenosu dat prostřednictvím sítě. Síť je většinou výrazně méně výkonnou metodou přenosu dat. Hlavním důvodem, proč zadat předponu `file://` je to, že tak získáte čistou kopii repozitáře bez nepotřebných referencí a objektů, například po importu z jiného verzovacího systému a podobně (úkony správy jsou popsány v kapitole 9). My budeme používat normální cestu, neboť tato metoda je téměř vždy rychlejší. K přidání lokálního repozitáře do existujícího projektu Git můžete použít příkaz například v tomto tvaru: @@ -44,17 +44,17 @@ Jedná se také o výbornou možnost, jak rychle získat práci z pracovního re Nevýhodou této metody je, že nastavit a získat sdílený přístup z více umístění je většinou těžší než obyčejný síťový přístup. Budete-li chtít pracovat doma a odeslat data z notebooku, budete muset připojit vzdálený disk, což může být ve srovnání s přístupem prostřednictvím sítě složité a pomalé. -Zapomenout bychom neměli ani na to, že používáte-li sdílené připojení určitého druhu, nemusí být tato možnost vždy nutně nejrychlejší. Lokální repozitář je rychlý pouze v případě, že máte rychlý přístup k datům. Repozitář na NFS je často pomalejší než repozitář nad SSH na tomtéž serveru, který ve všech systémech umožňuje spustit Git z lokálních disků. +Zapomenout bychom neměli ani na to, že používáte-li sdílené připojení určitého druhu, nemusí být tato možnost vždy nutně nejrychlejší. Lokální repozitář je rychlý pouze v případě, že máte rychlý přístup k datům. Repozitář na NFS je často pomalejší než stejný repozitář nad SSH na tomtéž serveru, který ve všech systémech umožňuje spustit Git z lokálních disků. ### Protokol SSH ### -Patrně nejčastějším přenosovým protokolem pro systém Git je SSH. Je to z toho důvodu, že SSH přístup k serverům je na většině míst už nastaven, a pokud ne, není ho těžké nastavit. SSH je navíc jediným síťovým protokolem, z nějž lze snadno číst a do nějž lze snadno zapisovat. Oba zbývající síťové protokoly (HTTP i Git) jsou většinou určeny pouze ke čtení, a proto i když je máte k dispozici, budete potřebovat SSH protokol pro příkazy k zápisu. SSH je také síťovým protokolem s ověřováním, a protože je hojně rozšířen, je jeho nastavení a používání většinou snadné. +Patrně nejčastějším přenosovým protokolem pro systém Git je SSH. Je to z toho důvodu, že SSH přístup k serverům je na většině míst už nastaven, a pokud ne, není ho těžké nastavit. SSH je navíc jediným síťovým protokolem, z nějž lze snadno číst a do nějž lze snadno zapisovat. Oba zbývající síťové protokoly (HTTP i Git) jsou většinou určeny pouze ke čtení, a proto i když je dáváte k dispozici ostatním, pro sebe budete potřebovat SSH protokol pro příkazy zápisu. SSH je také síťovým protokolem s autentizací, a protože je hojně rozšířen, je jeho nastavení a používání většinou snadné. -Chcete-li naklonovat repozitář Git pomocí protokolu SSH, zadejte „ssh:// URL“, například: +Chcete-li naklonovat repozitář Git pomocí protokolu SSH, zadejte `ssh://` URL, například: $ git clone ssh://user@server/project.git -Protokol ostatně ani nemusíte zadávat – pokud žádný výslovně neurčíte, Git použije SSH jako výchozí možnost: +Nebo můžete pro SSH protokol použít kratší zápis jako u scp: $ git clone user@server:project.git @@ -62,24 +62,24 @@ Stejně tak nemusíte zadávat ani uživatele, Git automaticky použije uživate #### Výhody #### -Používání protokolu SSH přináší mnoho výhod. Především byste ho měli používat vždy, když chcete v síti ověřovat oprávnění k zápisu do repozitáře. Zadruhé: protokol SSH má snadné nastavení – SSH démoni jsou zcela běžní, správci sítě si s nimi většinou vědí rady a mnoho distribucí OS je má ve výchozí instalaci nebo má nástroje, aby s nimi mohly pracovat. Z dalších výhod bychom měli zmínit také to, že přístup přes protokol SSH je bezpečný, veškerý přenos dat je šifrovaný a ověřený. A stejně jako protokoly Git a Local je i protokol SSH výkonný. Data jsou před přenosem upravena do co nejkompaktnější podoby. +Používání protokolu SSH přináší mnoho výhod. Především byste ho měli používat vždy, když chcete v síti používat autentizovaný zápis do repozitáře. Zadruhé: protokol SSH se snadno nastavuje – SSH démoni jsou zcela běžní, správci sítě si s nimi většinou vědí rady a mnoho distribucí OS je má ve výchozí instalaci nebo poskytuje nástroje pro jejich správu. Z dalších výhod bychom měli zmínit také to, že přístup přes protokol SSH je bezpečný, veškerý přenos dat je šifrovaný a autentizovaný. A stejně jako protokoly Git a Local je i protokol SSH výkonný, protože data jsou před přenosem upravena do co nejkompaktnější podoby. #### Nevýhody #### -Nevýhodou protokolu SSH je, že neumožňuje anonymní přístup do repozitáře. Chce-li někdo získat přístup do vašeho repozitáře, byť třeba jen ke čtení, musí mít přístup k vašemu počítači přes SSH. Proto se protokol SSH nehodí pro projekty s otevřeným zdrojovým kódem. Pokud repozitář používáte jen v rámci firemní sítě, bude pro vás protokol SSH zřejmě naprosto ideální. Pokud chcete povolit anonymní přístup pro čtení k vašim projektům, budete muset nastavit protokol SSH k odesílání svých dat, ale přidat jiný protokol, pomocí nějž budou ostatní tato data stahovat. +Nevýhodou protokolu SSH je, že neumožňuje anonymní přístup do repozitáře. Chce-li někdo získat přístup do vašeho repozitáře, byť třeba jen ke čtení, musí mít přístup k vašemu počítači přes SSH. Proto se protokol SSH nehodí pro projekty s otevřeným zdrojovým kódem. Pokud repozitář používáte jen v rámci firemní sítě, bude pro vás protokol SSH zřejmě naprosto ideální. Pokud chcete povolit anonymní přístup pro čtení k vašim projektům, budete muset nastavit protokol SSH k odesílání svých dat, ale musíte přidat i jiný protokol, který budou ostatní používat pro stahování. ### 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-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á. +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ékoliv autentizace. Chcete-li, aby byl repozitář zpřístupněn protokolem Git, musíte vytvořit soubor `git-daemon-export-ok`. Bez tohoto souboru nebude repozitář démonem zpřístupněn. Žádné jiné zabezpečení ale 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 zapnout, ale vzhledem k tomu, že protokol neumožňuje autentizaci, aktivované odesílání znamená, že kdokoli na internetu, kdo najde URL vašeho projektu, do něj bude moci odesílat data. Je jasné, že to většinou nechcete. #### Výhody #### -Protokol Git je ze všech dostupných protokolů nejrychlejší. Potřebujete-li, aby protokol obsluhoval frekventovaný provoz u veřejného projektu nebo velmi velký projekt, u nějž není třeba ověřování identity uživatele ohledně oprávnění pro čtení, bude k obsluze nejvhodnější pravděpodobně právě démon Git. Používá stejný mechanismus přenosu dat jako protokol SSH, na rozdíl od něj ale není zpomalován šifrováním a ověřováním. +Protokol Git je ze všech dostupných protokolů nejrychlejší. Potřebujete-li, aby protokol obsluhoval frekventovaný provoz u veřejného projektu nebo velmi velký projekt, u nějž není třeba ověřování identity uživatele ohledně oprávnění pro čtení, bude k obsluze nejvhodnější pravděpodobně právě démon Git. Používá stejný mechanismus přenosu dat jako protokol SSH, na rozdíl od něj ale není zpomalován šifrováním a ověřováním identity (autentizací). #### Nevýhody #### -Nevýhodou protokolu Git je, že neprovádí ověřování. Většinou není žádoucí, aby protokol Git tvořil jediný přístup k vašemu projektu. Protokol Git většinou využijete v kombinaci s přístupem přes SSH. Protokol SSH bude nastaven pro několik málo vývojářů s oprávněním k zápisu (odesílání dat) a všichni ostatní budou používat `git://` pro přístup pouze ke čtení. -Pravděpodobně se také jedná o protokol s nejobtížnějším nastavením. Vyžaduje spuštění vlastního démona – na jeho nastavení se podíváme v části „Gitosis“ této kapitoly – a dále konfiguraci `xinetd` nebo podobnou, která také není právě jednoduchá. Vyžaduje rovněž povolení přístupu k portu 9418 skrz firewall. Tento port nepatří mezi standardní porty, které by firemní firewally vždy povolovaly. Velkými podnikovými firewally je tento málo rozšířený port většinou blokován. +Nevýhodou protokolu Git je, že neprovádí autentizaci. Většinou není žádoucí, aby protokol Git tvořil jediný přístup k vašemu projektu. Protokol Git většinou využijete v kombinaci s přístupem přes SSH. Protokol SSH bude nastaven pro několik málo vývojářů s oprávněním k zápisu (odesílání dat) a všichni ostatní budou používat `git://` pro přístup pouze ke čtení. +Pravděpodobně se také jedná o protokol s nejobtížnějším nastavením. Vyžaduje spuštění vlastního démona – na jeho nastavení se podíváme v části „Gitosis“ této kapitoly – a dále konfiguraci `xinetd` nebo podobnou, což není zrovna procházka růžovou zahradou. Vyžaduje rovněž povolení přístupu k portu 9418 skrz firewall. Tento port nepatří mezi standardní porty, které by firemní firewally vždy povolovaly. Velkými podnikovými firewally je tento málo rozšířený port většinou blokován. ### Protokol HTTP/S ### @@ -91,11 +91,11 @@ Na konec jsme si nechali protokol HTTP. Co je na protokolu HTTP nebo HTTPS sympa $ mv hooks/post-update.sample hooks/post-update $ chmod a+x hooks/post-update -A to je vše. Zásuvný modul `post-update`, který je standardně součástí systému Git, spustí příkaz `git update-server-info`, který zajistí správné vyzvedávání a klonování dat přes protokol HTTP. Tento příkaz se spustí, když do tohoto repozitáře odesíláte data přes protokol SSH. Ostatní mohou klonovat třeba takto: +A to je vše. Zásuvný modul `post-update`, který je standardně součástí systému Git, spustí příslušný příkaz (`git update-server-info`), který zajistí správné vyzvedávání a klonování dat přes protokol HTTP. Tento příkaz se spustí, když do tohoto repozitáře odesíláte data přes protokol SSH. Poté mohou ostatní klonovat třeba takto: $ git clone http://example.com/gitproject.git -V tomto konkrétním případě používáme cestu `/var/www/htdocs`, která je obvyklá u nastavení Apache, ale použít lze v podstatě jakýkoli webový server – stačí uložit holý repozitář do daného umístění. Data repozitáře Git jsou obsluhována jako obyčejné statické soubory (podrobnosti naleznete v kapitole 9). +V tomto konkrétním případě používáme cestu `/var/www/htdocs`, která je obvyklá u nastavení Apache, ale použít lze v podstatě jakýkoli statický webový server – stačí uložit holý repozitář do dané cesty. Data repozitáře Git jsou obsluhována jako obyčejné statické soubory (podrobnosti o přesném způsobu obsluhy naleznete v kapitole 9). Odesílat data do repozitáře Git je možné také přes protokol HTTP, avšak tento způsob není příliš rozšířený a vyžaduje nastavení komplexních požadavků protokolu WebDAV. Protože se tato možnost využívá zřídka, nebudeme se jí v této knize věnovat. Pokud vás zajímá používání protokolů HTTP k odesílání dat, více se o přípravě repozitáře k tomuto účelu dočtete na adrese: `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt` (anglicky). Příjemným faktem na odesílání dat přes protokol HTTP je, že můžete použít jakýkoli server WebDAV i bez speciálních funkcí systému Git. Tuto možnost tak můžete využít, pokud váš poskytovatel webhostingu podporuje WebDAV pro zápis aktualizací na vaše webové stránky. @@ -103,23 +103,24 @@ Odesílat data do repozitáře Git je možné také přes protokol HTTP, avšak Pro používání protokolu HTTP mluví zejména jeho snadné nastavení. Vystačíte s několika málo příkazy, ale získáte jednoduchý způsob, jak nastavit oprávnění pro čtení repozitáře Git pro okolní svět. Celý postup nezabere víc než pár minut. Protokol HTTP navíc jen minimálně omezuje zdroje serveru. Vzhledem k tomu, že k obsluze všech dat používá většinou statický HTTP server, obslouží běžný server Apache průměrně několik tisíc souborů za sekundu. Ani malý server proto není snadné přetížit. -Své repozitáře můžete prostřednictvím protokolu HTTPS poskytovat pouze ke čtení a šifrovat přenos dat. Nebo můžete zajít ještě dál a vyžadovat, aby klienti používali konkrétní podepsané SSL certifikáty. Je pravda, že v takovém případě by už bylo jednodušší použít veřejné SSH klíče, ale ve vašem konkrétním případě může být použití podepsaných SSL certifikátů nebo jiné ověření identity na základě protokolu HTTP lepší metodou, jak zajistit přístup přes HTTPS pouze ke čtení. +Své repozitáře můžete zpřístupnit ke čtení prostřednictvím protokolu HTTPS, což znamená, že se přenášený obsah šifruje. Nebo můžete zajít ještě dál a vyžadovat, aby klienti používali konkrétní podepsané SSL certifikáty. Je pravda, že v takovém případě by už bylo jednodušší použít veřejné SSH klíče, ale ve vašem konkrétním případě může být použití podepsaných SSL certifikátů nebo jiné ověření identity na základě protokolu HTTP lepší metodou, jak zajistit přístup přes HTTPS pouze ke čtení. Z dalších výhod protokolu HTTP bychom mohli jmenovat i jeho značné rozšíření, díky čemuž jsou firemní firewally často nastaveny tak, že umožňují provoz přes standardní port protokolu HTTP. #### Nevýhody #### -Nevýhodou obsluhy repozitáře přes protokol HTTP je poměrně nízká výkonnost pro klienta. Klonovat nebo vyzvedávat data z repozitáře trvá v případě protokolu HTTP obecně mnohem déle a vyžádá si většinou podstatně větší režii síťových operací a objem přenášených dat, než je tomu u ostatních síťových protokolů. Protože protokol není natolik inteligentní, aby přenášel pouze data, která potřebujete – v těchto transakcích se na straně serveru nesetkáte s dynamickou činností – je protokol HTTP často nazýván „dumb protocol“ (hloupý protokol). Více informací o rozdílech ve výkonnosti mezi protokolem HTTP a ostatními protokoly najdete v kapitole 9. +Nevýhodou obsluhy repozitáře přes protokol HTTP je poměrně nízká výkonnost pro klienta. Klonovat nebo vyzvedávat data z repozitáře trvá v případě protokolu HTTP obecně mnohem déle a vyžádá si většinou podstatně větší režii síťových operací a objem přenášených dat, než je tomu u ostatních síťových protokolů. Protože protokol není natolik inteligentní, aby přenášel pouze data, která potřebujete – v těchto transakcích se na straně serveru nesetkáte s dynamickou činností – je protokol HTTP často nazýván *dumb protocol* (hloupý protokol). Více informací o rozdílech ve výkonnosti mezi protokolem HTTP a ostatními protokoly najdete v kapitole 9. ## Jak umístit Git na server ## Pro úvodní nastavení serveru Git je třeba exportovat existující repozitář do nového, holého repozitáře (bare repository), tj. do repozitáře, který neobsahuje pracovní adresář. S tím obvykle nebývá problém. -Chcete-li naklonovat stávající repozitář, a vytvořit tak nový a holý, zadejte příkaz clone s parametrem `--bare`. Je zvykem, že adresáře s holým repozitářem končí na `.git`, například: +Chcete-li naklonovat stávající repozitář, a vytvořit tak nový a holý, zadejte příkaz pro klonování s parametrem `--bare`. Je zvykem, že adresáře s holým repozitářem končí na `.git`, například: $ 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. -Výstup tohoto příkazu je trochu nejasný. Protože příkaz `clone` znamená v podstatě `git init` a následně `git fetch`, vidíme z části `git init`, která vytvoří prázdný adresář, nějaký výstup. Následný přenos objektu neposkytuje žádný výstup, přesto však proběhl. V adresáři `my_project.git` byste nyní měli mít kopii dat z adresáře Git. +V adresáři `my_project.git` byste nyní měli mít kopii dat z adresáře Git. Je to přibližně stejné, jako byste zadali například: @@ -147,7 +148,7 @@ Vidíte, jak je jednoduché vzít repozitář Git, vytvořit jeho holou verzi a A to je skutečně vše, co je třeba ke spuštění serveru Git, k němuž bude mít přístup více lidí – na server stačí přidat SSH účty a umístit holý repozitář někam, kam budou mít všichni uživatelé oprávnění ke čtení i zápisu. Vše je připraveno, nic dalšího se od vás nevyžaduje. -V dalších částech se podíváme na některé pokročilé možnosti nastavení. Dozvíte se v nich, jak se vyhnout nutnosti vytvářet uživatelské účty pro všechny uživatele, jak k repozitářům přiřadit veřejné oprávnění pro čtení, jak nastavit webová rozhraní nebo k čemu se používá nástroj Gitosis. To však nemění nic na tom, že ke spolupráci se skupinou lidí na soukromém projektu vystačíte s jedním SSH serverem a holým repozitářem. +V dalších částech se podíváme na některé pokročilé možnosti nastavení. Dozvíte se v nich, jak se vyhnout nutnosti vytvářet uživatelské účty pro všechny uživatele, jak k repozitářům přiřadit veřejné oprávnění pro čtení, jak nastavit webová rozhraní nebo k čemu se používá nástroj Gitosis. To však nemění nic na tom, že ke spolupráci se skupinou lidí na soukromém projektu *vystačíte* s jedním SSH serverem a holým repozitářem. ### Nastavení pro malou skupinu ### @@ -157,9 +158,9 @@ Pokud provádíte nastavení jen pro malý okruh lidí nebo jen zkoušíte Git v Jestliže už máte server, k němuž mají všichni vaši vývojáři SSH přístup, bude většinou nejjednodušší nastavit první repozitář tam, protože celé nastavení už tím máte v podstatě hotové (jak jsme ukázali v předchozí části). Pokud chcete pro své repozitáře nastavit komplexnější správu oprávnění, můžete je opatřit běžnými oprávněními k systému souborů, které vám nabízí operační systém daného serveru. -Pokud chcete své repozitáře umístit na server, jenž nemá účty pro všechny členy vašeho týmu, kteří by měli mít oprávnění k zápisu, musíte pro ně nastavit SSH přístup. Předpokládáme, že pokud máte server, na němž to lze provést, máte už nainstalován server SSH. Tímto způsobem získáte přístup na server. +Pokud chcete své repozitáře umístit na server, jenž nemá účty pro všechny členy vašeho týmu, kteří by měli mít oprávnění k zápisu, musíte pro ně nastavit SSH přístup. Předpokládáme, že pokud máte server, na němž to lze provést, máte už nainstalován server SSH a jeho prostřednictvím k serveru přistupujete. -Existuje několik způsobů, jak umožnit přístup všem členům vašeho týmu. Prvním způsobem je nastavit účty pro všechny, což není složité, ale může být poněkud zdlouhavé. Možná nebudete mít chuť spouštět příkaz `adduser` (přidat uživatele) a nastavovat dočasná hesla pro každého uživatele zvlášť. +Existuje několik způsobů, jak umožnit přístup všem členům vašeho týmu. Prvním způsobem je nastavit účty pro všechny, což je sice přímočaré, ale může to být poněkud zdlouhavé. Možná nebudete mít chuť spouštět příkaz `adduser` (přidat uživatele) a nastavovat pro každého uživatele dočasná hesla. Druhým způsobem je vytvořit na počítači jediného uživatele 'git', požádat všechny uživatele, kteří mají mít oprávnění k zápisu, aby vám poslali veřejný SSH klíč, a přidat tento klíč do souboru `~/.ssh/authorized_keys` vašeho nového uživatele 'git'. Nyní budou mít všichni přístup k tomuto počítači prostřednictvím uživatele 'git'. Tento postup nemá žádný vliv na data vašich revizí – SSH uživatel, jehož účtem se přihlašujete, neovlivní revize, které jste nahráli. @@ -167,7 +168,7 @@ Dalším možným způsobem je nechat ověřovat SSH přístupy LDAP serveru neb ## Vygenerování veřejného SSH klíče ## -Mnoho serverů Git provádí ověřování pomocí veřejných SSH klíčů. Aby vám mohli všichni uživatelé ve vašem systému poskytnout veřejný klíč, musí si ho nechat vygenerovat (pokud klíč ještě nemají). Tento proces se napříč operačními systémy téměř neliší. +Mnoho serverů Git provádí ověřování totožnosti pomocí veřejných SSH klíčů. Aby vám mohli všichni uživatelé ve vašem systému poskytnout veřejný klíč, musí si ho každý z nich nechat vygenerovat (pokud klíč ještě nemá). Tento proces se napříč operačními systémy téměř neliší. Nejprve byste se měli ujistit, že ještě žádný klíč nemáte. Uživatelské SSH klíče jsou standardně uloženy v adresáři `~/.ssh` daného uživatele. Nejsnazší způsob kontroly, zda už klíč vlastníte, je přejít do tohoto adresáře a zjistit jeho obsah: $ cd ~/.ssh @@ -187,7 +188,7 @@ Zobrazí se několik souborů s názvem `xxx` a `xxx.pub`, kde `xxx` je většin The key fingerprint is: 43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local -Program nejprve potvrdí, kam chcete klíč uložit (`.ssh/id_rsa`), a poté se dvakrát zeptá na přístupové heslo. Pokud nechcete při používání klíče zadávat heslo, nemusíte ho nyní vyplňovat. +Program nejprve potvrdí, kam chcete klíč uložit (`.ssh/id_rsa`), a poté se dvakrát zeptá na přístupové heslo. Pokud nechcete při používání klíče zadávat heslo, můžete ho nyní nechat prázdné. Každý uživatel, který si tímto způsobem nechá vygenerovat veřejný klíč, ho nyní pošle vám nebo jinému správci serveru Git (za předpokladu, že používáte nastavení SSH serveru vyžadující veřejné klíče). Stačí přitom zkopírovat obsah souboru `.pub` a odeslat ho e-mailem. Veřejné klíče mají zhruba tuto podobu: @@ -203,7 +204,7 @@ Budete-li potřebovat podrobnější návod k vytvoření SSH klíče v různýc ## Nastavení serveru ## -Podívejme se nyní na nastavení SSH přístupu na straně serveru. V tomto příkladu použijeme k ověření uživatelů metodu `authorized_keys`. Předpokládáme také, že pracujete se standardní linuxovou distribucí, jako je např. Ubuntu. Nejprve vytvoříte uživatele 'git' a adresář `.ssh` pro tohoto uživatele. +Projděme si nastavení SSH přístupu na straně serveru. V tomto příkladu použijeme k ověření identity uživatelů metodu `authorized_keys`. Předpokládáme také, že pracujete se standardní linuxovou distribucí, jako je např. Ubuntu. Nejprve vytvoříte uživatele 'git' a adresář `.ssh` pro tohoto uživatele. $ sudo adduser git $ su git @@ -220,12 +221,16 @@ V dalším kroku musíte vložit veřejné SSH klíče od svých vývojářů do O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq dAv8JggJICUvax2T9va5 gsg-keypair -Vy nyní klíče vložíte do souboru `authorized_keys`: +Vy nyní klíče přidáte do souboru `authorized_keys`: $ 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 +Autentizace vůči SSH, která je založená na klíči, obvykle vynucuje zvýšenou bezpečnost tím, že pro zúčastněné soubory vyžaduje omezená oprávnění. Aby SSH neodmítl pracovat, napište následující: + + $ chmod -R go= ~/.ssh + Nyní pro ně můžete nastavit prázdný repozitář. Spusťte příkaz `git init` s parametrem `--bare`, který inicializuje repozitář bez pracovního adresáře: $ cd /opt/git @@ -233,7 +238,7 @@ Nyní pro ně můžete nastavit prázdný repozitář. Spusťte příkaz `git in $ cd project.git $ git --bare init -John, Josie a Jessica pak mohou do tohoto repozitáře odeslat první verzi svého projektu: přidají si ho jako vzdálený repozitář a odešlou do něj svou větev. Nezapomeňte, že pokaždé, když chcete přidat projekt, se musí k počítači někdo přihlásit a vytvořit holý repozitář. Pro server, na kterém jste nastavili uživatele 'git' a repozitář, můžeme použít název hostitele `gitserver`. Pokud server provozujete interně a nastavíte DNS pro `gitserver` tak, aby ukazovalo na tento server, můžete používat i takovéto příkazy: +John, Josie a Jessica pak mohou do tohoto repozitáře odeslat první verzi svého projektu: přidají si ho jako vzdálený repozitář a odešlou do něj svou větev. Nezapomeňte, že pokaždé, když chcete vytvořit projekt, musí se k počítači někdo přihlásit a vytvořit holý repozitář. Pro server, na kterém jste nastavili uživatele 'git' a repozitář, můžeme použít název hostitele `gitserver`. Pokud server provozujete interně a nastavíte DNS pro `gitserver` tak, aby ukazovalo na tento server, můžete používat i takovéto příkazy: # on Johns computer $ cd myproject @@ -253,7 +258,7 @@ Ostatní nyní mohou velmi snadno repozitář naklonovat i do něj odesílat zm Tímto způsobem lze rychle vytvořit a spustit server Git ke čtení i zápisu pro menší počet vývojářů. -Pro větší bezpečnost máte možnost využít nástroj `git-shell`, který je distribuován se systémem Git. Pomocí něj lze snadno nastavit, aby uživatel 'git' prováděl pouze operace systému Git. Pokud ho nastavíte jako přihlašovací shell uživatele 'git', pak nebude mít uživatel 'git' normální shellový přístup k vašemu serveru. Chcete-li nástroj použít, zadejte pro přihlašovací shell vašeho uživatele `git-shell` místo bash nebo csh. V takovém případě pravděpodobně budete muset upravit soubor `/etc/passwd`: +Pro větší bezpečnost máte možnost využít nástroj `git-shell`, který je distribuován se systémem Git. Pomocí něj lze uživatele 'git' snadno omezit tak, aby mohl prováděl pouze operace systému Git. Pokud ho nastavíte jako přihlašovací shell uživatele 'git', pak nebude mít uživatel 'git' normální shellový přístup k vašemu serveru. Chcete-li nástroj použít, zadejte pro přihlašovací shell vašeho uživatele `git-shell` místo bash nebo csh. V takovém případě pravděpodobně budete muset upravit soubor `/etc/passwd`: $ sudo vim /etc/passwd @@ -273,7 +278,7 @@ Uživatel 'git' nyní může používat SSH připojení k odesílání a stahov ## Veřejný přístup ## -A co když chcete u svého projektu nastavit anonymní oprávnění pro čtení? Nehostujete třeba interní soukromý projekt, ale „open source“ projekt. Nebo možná máte několik serverů průběžné integrace, které se neustále mění a vy nechcete stále generovat SSH klíče, rádi byste vždy přidali jen obyčejné anonymní oprávnění pro čtení. +A co když chcete u svého projektu nastavit anonymní oprávnění pro čtení? Nehostujete třeba interní soukromý projekt, ale „open source“ projekt. Nebo možná máte několik serverů průběžné integrace, které se neustále mění a vy nechcete stále generovat SSH klíče. Rádi byste vždy přidali jen obyčejné anonymní oprávnění pro čtení. Patrně nejjednodušším způsobem pro menší týmy je spustit statický webový server s kořenovým adresářem dokumentů, v němž budou uloženy vaše Git repozitáře, a zapnout zásuvný modul `post-update`, o kterém jsme se zmínili už v první části této kapitoly. Můžeme pokračovat v našem předchozím příkladu. Řekněme, že máte repozitáře uloženy v adresáři `/opt/git` a na vašem počítači je spuštěn server Apache. Opět, můžete použít jakýkoli webový server. Pro názornost ale ukážeme některá základní nastavení serveru Apache, abyste získali představu, co vás může čekat. @@ -283,12 +288,17 @@ Nejprve ze všeho budete muset zapnout zásuvný modul: $ mv hooks/post-update.sample hooks/post-update $ chmod a+x hooks/post-update -Jestliže používáte verzi systému Git starší než 1.6, nebude příkaz `mv` nutný. Git začal pojmenovávat příklady zásuvných modulů příponou „.sample“ teprve nedávno. - Jaká je funkce zásuvného modulu `post-update`? V principu vypadá asi takto: $ 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 Znamená to, že až budete odesílat data na server prostřednictvím SSH, Git spustí tento příkaz a aktualizuje soubory vyžadované pro přístup přes HTTP. @@ -316,7 +326,7 @@ Tímto způsobem můžete během pár minut nastavit oprávnění pro čtení za ## GitWeb ## -Nyní, když máte ke svému projektu nastavena základní oprávnění pro čtení/zápis a pouze pro čtení, možná budete chtít nastavit jednoduchou online vizualizaci. Git vám nabízí CGI skript s názvem GitWeb, který slouží k tomuto účelu. Jak GitWeb funguje, na to se můžete podívat např. na stránkách `http://git.kernel.org` (viz obrázek 4-1). +Nyní, když máte ke svému projektu nastavena základní oprávnění pro čtení/zápis a pouze pro čtení, možná budete chtít nastavit jednoduchou online vizualizaci. Git vám nabízí CGI skript s názvem GitWeb, který se k tomuto účelu běžně používá. V činnosti můžete GitWeb pozorovat například na stránkách `http://git.kernel.org` (viz obrázek 4-1). Insert 18333fig0401.png Obrázek 4-1. Online uživatelské rozhraní GitWeb @@ -354,7 +364,7 @@ Všimněte si, že musíte příkazu pomocí proměnné `GITWEB_PROJECTROOT` sd -Také GitWeb může být obsluhován jakýmkoli webovým serverem umožňujícím CGI. Chcete-li používat jakýkoli jiný server, nemělo by být nastavení obtížné. V tomto okamžiku byste měli být schopni prohlížet své repozitáře online na adrese `http://gitserver/` a používat `http://git.gitserver` ke klonování a vyzvedávání repozitářů prostřednictvím protokolu HTTP. +Znovu připomeňme, že GitWeb může být obsluhován jakýmkoli webovým serverem podporujícím CGI. Chcete-li používat jakýkoli jiný server, nemělo by být nastavení obtížné. V tomto okamžiku byste měli být schopni prohlížet své repozitáře online na adrese `http://gitserver/` a používat `http://git.gitserver` ke klonování a vyzvedávání repozitářů prostřednictvím protokolu HTTP. ## Gitosis ## @@ -364,7 +374,7 @@ Proto možná rádi přejdete na rozšířený softwarový projekt „Gitosis“ Instalace nástroje Gitosis sice nepatří mezi nejsnazší, ale není ani příliš složitá. Nejjednodušší je k ní použít linuxový server – tyto příklady používají běžný Ubuntu server 8.10. -Gitosis vyžaduje některé nástroje v jazyce Python, a proto první, co musíte udělat, je nainstalovat balíček nástrojů nastavení Python, který je v Ubuntu dostupný jako python-setuptools: +Gitosis vyžaduje některé nástroje v jazyce Python, a proto první, co musíte udělat, je nainstalovat pythonovský balíček setuptools, který je v Ubuntu dostupný jako python-setuptools: $ apt-get install python-setuptools @@ -382,7 +392,7 @@ Gitosis teď bude spravovat klíče za vás. Proto je třeba, abyste odstranili $ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak -Dále musíte znovu zapnout shell na uživatele 'git', jestliže jste ho změnili na příkaz `git-shell`. Uživatelé se stále ještě nebudou moci přihlásit, ale Gitosis za vás bude provádět správu. V souboru `/etc/passwd` tak nyní změníme řádek: +Dále musíte znovu zapnout shell na uživatele 'git', jestliže jste ho změnili na příkaz `git-shell`. Uživatelé se stále ještě nebudou moci přihlásit, ale Gitosis za vás bude provádět správu. Takže v souboru `/etc/passwd` změňte následující řádek git:x:1000:1000::/home/git:/usr/bin/git-shell @@ -390,21 +400,21 @@ zpět na git:x:1000:1000::/home/git:/bin/sh -V tomto okamžiku můžeme inicializovat nástroj Gitosis. Učiníte tak spuštěním příkazu `gitosis-init` se svým osobním veřejným klíčem. Není-li váš veřejný klíč na serveru, bude ho tam nutné zkopírovat: +V tomto okamžiku můžeme inicializovat nástroj Gitosis. Učiníte tak spuštěním příkazu `gitosis-init` se svým osobním veřejným klíčem. Není-li váš veřejný klíč na serveru, musíte ho tam nakopírovat: $ 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/ -Uživatel s tímto klíčem poté bude moci měnit hlavní repozitář Git, který kontroluje nastavení nástroje Gitosis. Dále je třeba ručně nastavit právo spuštění na skriptu `post-update` pro nový řídicí repozitář. +Uživatel s tímto klíčem poté bude moci měnit hlavní repozitář Git, kterým se ovládá nastavení nástroje Gitosis. Dále je třeba ručně nastavit právo spuštění na skriptu `post-update` pro nový řídicí repozitář. $ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update -Nyní máte vše hotovo. Pokud jste nastavení provedli správně, můžete vyzkoušet SSH přístup na server jako uživatel, pro kterého jste přidali veřejný klíč při inicializaci nástroje Gitosis. Mělo by se zobrazit asi následující: +Teď to můžete rozjet. Pokud jste nastavení provedli správně, můžete vyzkoušet SSH přístup na server jako uživatel, pro kterého jste přidali veřejný klíč při inicializaci nástroje Gitosis. Mělo by se zobrazit asi následující: $ 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. To znamená, že vás Gitosis sice rozpoznal, ale nedovolí vám přístup, protože se nepokoušíte zadat žádný příkaz Git. Provedeme tedy skutečný příkaz systému Git a naklonujeme řídicí repozitář Gitosis: @@ -428,28 +438,28 @@ Pokud se podíváte na soubor `gitosis.conf`, měl by udávat pouze informace o [gitosis] [group gitosis-admin] - writable = gitosis-admin members = scott + writable = gitosis-admin Tato informace znamená, že uživatel 'scott' – ten, jehož veřejným klíčem jste inicializovali Gitosis – je jediným uživatelem, který má přístup k projektu `gitosis-admin`. Nyní přidáme nový projekt. Přidáte novou část s názvem `mobile`, která bude obsahovat seznam vývojářů vašeho mobilního týmu a projektů, k nimž tito vývojáři potřebují přístup. Protože je v tuto chvíli jediným uživatelem v systému 'scott', přidáte ho jako jediného člena a vytvoříte pro něj nový projekt s názvem `iphone_project`: [group mobile] - writable = iphone_project members = scott + writable = iphone_project Pokaždé, když provedete změny v projektu `gitosis-admin`, musíte tyto změny zapsat a odeslat je zpět na server, aby nabyly účinnosti: $ 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 Do nového projektu `iphone_project` teď můžete odeslat svá první data: přidejte do lokální verze projektu svůj server jako vzdálený repozitář a odešlete změny. Od této chvíle už nebudete muset ručně vytvářet holé repozitáře pro nové projekty na serveru. Gitosis je vytvoří automaticky, jakmile zjistí první odeslání dat: @@ -458,7 +468,7 @@ Do nového projektu `iphone_project` teď můžete odeslat svá první data: př $ 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 @@ -474,20 +484,20 @@ Na tomto projektu chcete spolupracovat s přáteli, a proto budete muset znovu p Nyní je můžete všechny přidat do týmu 'mobile', čímž získají oprávnění pro čtení i pro zápis k `iphone_project`: [group mobile] - writable = iphone_project members = scott john josie jessica + writable = iphone_project Až tuto změnu zapíšete a odešlete, všichni čtyři uživatelé budou moci z tohoto projektu číst a zapisovat do něj. Gitosis nabízí také jednoduchou správu přístupu. Pokud chcete, aby měl John u projektu pouze oprávnění pro čtení, můžete provést následující: [group mobile] - writable = iphone_project members = scott josie jessica + writable = iphone_project [group mobile_ro] - readonly = iphone_project members = john + readonly = iphone_project John nyní může naklonovat projekt a stahovat jeho aktualizace, ale Gitosis mu neumožní, aby odesílal data zpět do projektu. Takových skupin můžete vytvořit libovolně mnoho. Každá může obsahovat různé uživatele a projekty. Jako jednoho ze členů skupiny můžete zadat také celou jinou skupinu (použijete pro ni předponu `@`). Všichni její členové se tím automaticky zdědí. @@ -495,37 +505,37 @@ John nyní může naklonovat projekt a stahovat jeho aktualizace, ale Gitosis mu 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 Máte-li jakékoli problémy, může vám pomoci zadání `loglevel=DEBUG` do části `[gitosis]`. Pokud jste odesláním nesprávné konfigurace ztratili oprávnění k odesílání dat, můžete ručně opravit soubor na serveru v adresáři `/home/git/.gitosis.conf` – jedná se o soubor, z nějž Gitosis načítá data. Po odeslání dat do projektu bude soubor `gitosis.conf`, který jste právě odeslali, umístěn do tohoto adresáře. Pokud soubor ručně upravíte, zůstane v této podobě až do dalšího úspěšného odeslání do projektu `gitosis-admin`. ## Gitolite ## -Git se stal hodně populárním v korporátním prostředí, které obvykle mívá další doplňující požadavky na kontrolu přístupu. Nástroj Gitolite byl vytvořen právě na řešení těchto požadavků. +Tato podkapitola slouží k rychlému seznámení s Gitolite a uvádí základní pokyny pro instalaci a nastavení. Nemůže ale nahradit ohromný objem [dokumentace][gltoc], která se s Gitolite dodává. Tato podkapitola se může občas změnit, takže se možná chcete podívat na její [poslední verzi][gldpg]. [gldpg]: http://sitaramc.github.com/gitolite/progit.html [gltoc]: http://sitaramc.github.com/gitolite/master-toc.html Gitolite je autorizační vrstva nad gitem, která při autentizaci spoléhá na `sshd` nebo `httpd`. (Připomeňme si: autentizace spočívá v rozpoznání uživatele, autorizací rozumíme rozhodování, zda má povolení k provádění toho, co se provést pokouší.) -Gitolite umožňuje nastavit přístupová práva nejen na repozitáře (podobně jako Gitosis), ale také na větve a značky v každém repozitáři. To znamená, že lze nastavit, aby určití lidé mohli odesílat jen do určité reference (větve nebo značky) a do jiné ne. +Gitolite umožňuje nastavit přístupová práva nejen na repozitáře (podobně jako Gitosis), ale také na větve a značky v každém repozitáři. To znamená, že lze nastavit, aby určití lidé mohli odesílat jen do určité větve (nebo určité značky; obecně „refs“), ale do jiné ne. ### Instalace ### -Instalace Gitolite je velmi jednoduchá a to i když nebudete číst obsáhlou dokumentaci, která je k dispozici. Budete potřebovat účet na nějakém unixovém serveru (bylo testováno na různých distribucích Linuxu a na Solarisu 10), kde musí být nainstalovány git, Perl a SSH server kompatibilní s OpenSSH. V příkladech uvedených níže budeme používat účet `git` na serveru `gitserver`. +Instalace Gitolite je velmi jednoduchá a to i když si nepřečtete obsáhlou dokumentaci, která je k dispozici. Budete potřebovat účet na nějakém unixovém serveru. Pokud už jsou nainstalovány nástroje Git, Perl a SSH server kompatibilní s OpenSSH, nebudete potřebovat ani přístup root. V příkladech uvedených níže budeme používat účet `git` na serveru `gitserver`. -Nástroj Gitolite je ve smyslu „serverového“ softwaru poněkud neobvyklý. Přístup se realizuje přes ssh, takže každá serverová userid je potenciálně „hostitelem gitolite“ (gitolite host). Teď si popíšeme nejjednodušší způsob instalace. V dokumentaci naleznete další metody. +Nástroj Gitolite je ve smyslu „serverového“ softwaru poněkud neobvyklý. Přístup se realizuje přes SSH, takže každá serverová userid je potenciálně „hostitelem gitolite“ (gitolite host). Teď si popíšeme nejjednodušší způsob instalace. V dokumentaci naleznete další metody. -Začněte tím, že na serveru vytvoříte uživatele nazvaného `git` a přihlásíte se na něj. Z vaší pracovní stanice nakopírujte svůj veřejný ssh klíč (pokud jste spustili `ssh-keygen` s implicitními hodnotami, jde o soubor `~/.ssh/id_rsa.pub`) a přejmenujte jej na `VaseJmeno.pub`. Potom proveďte následující příkazy: +Začněte tím, že na serveru vytvoříte uživatele nazvaného `git` a přihlásíte se na něj. Z vaší pracovní stanice nakopírujte svůj veřejný SSH klíč (pokud jste spustili `ssh-keygen` s implicitními hodnotami, jde o soubor `~/.ssh/id_rsa.pub`) a přejmenujte jej na `.pub` (v příkladech budeme používat `scott.pub`). Potom proveďte následující příkazy: $ git clone git://github.com/sitaramc/gitolite $ gitolite/install -ln - # předpokládá existenci $HOME/bin a uvedení tohoto adresáře v $PATH + # assumes $HOME/bin exists and is in your $PATH $ gitolite setup -pk $HOME/scott.pub Poslední příkaz vytvoří na serveru nový gitovský repozitář nazvaný `gitolite-admin`. @@ -538,7 +548,7 @@ Základní rychlá metoda instalace bude většině lidí vyhovovoat. V případ ### Konfigurační soubor a pravidla přístupu ### -Přepněte se do repozitáře `gitolite-admin` (je umístěn ve vašem domácím adresáři), jakmile je instalace dokončena, a podívejte se co tam je: +Jakmile je instalace dokončena, přepněte se do repozitáře `gitolite-admin`, který jste naklonovali na váš počítač, a podívejte se co tam je: $ cd ~/gitolite-admin/ $ ls @@ -558,9 +568,9 @@ Všimněte si, že „scott“ (jméno veřejného klíče v dříve použitém Přidávání dalších uživatelů je snadné. Pokud chceme přidat uživatele „alice“, získáme její veřejný klíč, pojmenujeme jej `alice.pub` a umístíme jej do adresáře `keydir`. Je součástí klonu repozitáře `gitolite-admin`, který jsme právě vytvořili na pracovní stanici. Přidáme, potvrdíme a odešleme změny (add, commit, push). Tím jsme dosáhli přidání uživatele. -Syntaxe konfiguračního souboru pro Gitolite je dobře dokumentovaná, takže zde uvedu jen pár zajímavých věcí. +Syntaxe konfiguračního souboru pro Gitolite je dobře dokumentovaná, takže zde zdůrazníme jen pár věcí. -Pro usnadnění můžete dávat uživatele i repozitáře do skupin. Jména skupin jsou podobná jako makra; když je definujete, je úplně jedno jestli jde o projekty nebo uživatele; rozdíl to je až v momentu, kdy „makro“ použijete. +Pro usnadnění můžete uživatele i repozitáře sdružovat do skupin. Jména skupin se chovají jako makra; když je definujete, je úplně jedno jestli jde o projekty nebo uživatele; rozdíl se pozná až v momentu, kdy „makro“ *použijete*. @oss_repos = linux perl rakudo git gitolite @secret_repos = fenestra pear @@ -578,7 +588,7 @@ Můžete nastavovat přístupová práva na úrovni referencí. Skupina interns RW refs/tags/rc[0-9] = @engineers RW+ = @admins -Výraz za `RW` nebo `RW+` je regulární výraz (regex), se kterým se porovnává jméno odesílané reference. Nazvěme jej tedy „refex“! Refex může mít samozřejmě mnohem více použití než je tady ukázáno, takže si dejte pozor ať to nepřeženete, zvláště pokud se necítíte experty na regulární výrazy. +Výraz za `RW` nebo `RW+` je regulární výraz (regex), se kterým se porovnává jméno odesílané reference (ref). Nazvěme jej tedy „refex“! Refex může mít samozřejmě mnohem více použití než je tady ukázáno, takže si dejte pozor ať to nepřeženete, zvláště pokud nejste kovaní v perlovských regulárních výrazech. Gitolite přidává prefix `refs/heads/` jako usnadnění syntaxe, pokud refex nezačíná na `refs/`, jak jste mohli odhadnout z příkladu. @@ -587,50 +597,50 @@ Důležitou vlastností syntaxe konfiguračního souboru je to, že všechna pra repo gitolite RW+ = sitaram -Toto pravidlo se pak přidá do skupiny pravidel `gitolite` repozitáře. +Toto pravidlo se pak přidá do skupiny pravidel repozitáře `gitolite`. Teď by vás mohlo zajímat, jak jsou vlastně pravidla pro přístup aplikována, pojďme se na to tedy krátce podívat. -V gitolite jsou dvě úrovně kontroly přístupů. První je úroveň repozitářů; jestliže máte práva na čtení (nebo zápis) k jakékoliv referenci v repozitáři, máte tím práva na čtení (nebo zápis) k tomuto repozitáři. Tohle je jediná možnost jakou měl nástroj Gitosis. +V Gitolite jsou dvě úrovně kontroly přístupů. První je úroveň repozitářů; jestliže máte práva na čtení (nebo zápis) *k jakékoliv* referenci v repozitáři, máte tím práva na čtení (nebo zápis) k tomuto repozitáři. Tohle je jediná možnost jakou měl nástroj Gitosis. -Druhá úroveň je pouze pro práva pro „zápis“ a je podle větve nebo značky v repozitáři. Uživatelské jméno uživatele snažícího se o přístup (`W` nebo `+`) a jméno reference, kterou uživatel chce aktualizovat, jsou dané. Pravidla pro přístup jsou procházena postupně v pořadí, tak jak jsou uvedena v konfiguračním souboru a hledají se záznamy odpovídající této kombinaci uživatelského jména a reference (nezapomeňte ale, že refname se porovnává jako regulární výraz nikoliv jako pouhý řetězec). Jestliže je nalezen odpovídající záznam, odesílání je povoleno. Pokud není nalezeno nic, je přístup zamítnut. +Druhá úroveň se dá použít jen pro práva pro „zápis“ a vázána na větve nebo značky v repozitáři. Uživatelské jméno uživatele snažícího se o přístup (`W` nebo `+`) a jméno reference, kterou uživatel chce aktualizovat, jsou dané. Pravidla pro přístup jsou procházena postupně v pořadí, tak jak jsou uvedena v konfiguračním souboru a hledají se záznamy odpovídající této kombinaci uživatelského jména a reference (nezapomeňte ale, že refname se porovnává jako regulární výraz nikoliv jako pouhý řetězec). Jestliže je nalezen odpovídající záznam, odesílání je povoleno. Pokud není nalezeno nic, je přístup zamítnut. -### Rozšířená kontrola přístupu ve větvi „rebel“ ### +### Rozšířené řízení přístupu pravidly typu „odmítnutí“ ### -Jak můžete vidět výše, práva musí být jedno z nastavení `R`, `RW` nebo `RW+`. Dříve zmíněná větev „rebel“ přidává ještě jedno další právo: `-`, znamenající „odmítnutí“. To dává mnohem více možností za cenu zvýšení složitosti, protože nyní už není nenalezení odpovídajícího záznamu při procházení pravidel jedinou možností, jak může být přístup zamítnut. Takže nyní už na pořadí pravidel záleží! +Prozatím jsme si ukázali jen oprávnění nastavená na jednu z hodnot `R`, `RW` nebo `RW+`. Ale Gitolite dovoluje nastavení dalšího oprávnění: `-` s významem „odmítnutí“. To vám dává mnohem více možností, ale za cenu zvýšení složitosti. Popadnutí sítem pravidel už totiž není *jedinou* možností vedoucí k zamítnutí přístupu. *Záleží na pořadí pravidel!* -Řekněme, že ve výše uvedené situaci budeme chtít, aby skupina engineers mohla vracet změny v jakékoliv větvi s výjimkou větvě „hlavní“ a větve „integ“. To se nedá nastavit pomocí normální syntaxe, ale s pomocí větve „rebel“ podle následujícího postupu: +Řekněme, že ve výše uvedené situaci budeme chtít, aby skupina engineers mohla vracet změny v jakékoliv větvi *s výjimkou* větví `master` a `integ`. Udělá se to následovně: RW master integ = @engineers - master integ = @engineers RW+ = @engineers -Pravidla se znovu budou procházet postupně až do momentu, kdy bude nalezeno odpovídají pravidlo nebo bude přístup zamítnut. Odeslání do hlavní větve nebo větve „integ“, která nevracejí zpět změny, jsou povolena prvním pravidlem. Odeslání, která vracejí změny do těchto větví, neodpovídají prvnímu pravidlu. Porovnají se tedy s druhým pravidlem a na jeho základě budou zamítnuty. Odeslání (bez ohledu na to zda se jedná o vracení změn nebo ne) do jiných referencí než hlavní a „integ“ nebudou odpovídat ani prvnímu ani druhému pravidlu a budou tedy díky třetímu pravidlu povolena. +Pravidla se budou opět procházet shora dolů až do momentu, kdy narazíte na shodu s vaším režimem přístupu nebo na pravidlo typu odmítnutí (deny). Odeslání do větve `master` nebo `integ`, která nevracejí zpět změny (non-rewind push), jsou povolena prvním pravidlem. Odeslání, která vracejí změny (rewind push) do těchto větví, neodpovídají prvnímu pravidlu. Porovnají se tedy s druhým pravidlem a na jeho základě budou zamítnuty. Jakékoliv odeslání (bez ohledu na to zda se jedná o vracení změn nebo ne) do jiných referencí než `master` nebo `integ` nebudou odpovídat ani prvnímu ani druhému pravidlu, a proto bude díky třetímu pravidlu povoleno. ### Omezení odesílání změn vázané na soubory ### -K omezení odesílání do určitých větví a určitými uživateli můžete přidat také omezení určující, které soubory mohou uživatelé měnit. Například soubor Makefile (a možná některé programy) by asi neměl kdokoliv měnit, protože je na něm závislá řada dalších věcí. Pokud se neupraví *správným způsobem*, něco by se pokazilo. Nástroji gitolite můžeme říct: +K omezení odesílání do určitých větví a určitými uživateli můžete přidat také omezení určující, které soubory mohou uživatelé měnit. Například soubor Makefile (a možná některé programy) by asi neměl kdokoliv měnit, protože je na něm závislá řada dalších věcí. Pokud se neupraví *správným způsobem*, něco by se pokazilo. Nástroji Gitolite můžeme říct: repo foo RW = @junior_devs @senior_devs - VREF/NAME/Makefile = @junior_devs -Uživatelé, kteří přecházejí ze starší verze gitolite by si měli dát pozor na to, že v souvislosti s uvedeným rysem došlo k výrazné změně chování. Věnujte prosím pozornost detailům, které jsou uvedeny v příručce pro přechod k nové verzi. +Uživatelé, kteří přecházejí ze starší verze Gitolite by si měli dát pozor na to, že v souvislosti s uvedeným rysem došlo k výrazné změně chování. Věnujte prosím pozornost detailům, které jsou uvedeny v příručce pro přechod k nové verzi. ### Osobní větve ### Konečně Gitolite má také funkci, která se nazývá „osobní větve“ (nebo raději „jmenný prostor osobních větví“) a může být velmi užitečná v korporátním prostředí. -Hodně výměny kódu probíhá v otevřeném git světě metodou „prosím stáhněte si“. V korporátním prostředí ovšem nebývá jakýkoliv neautorizovaný přístup vítán a pracovní stanice vývojáře nemůže provádět autentizaci, takže můžete na centrální server odesílat, ale musíte požádat někoho jiného, když odtud chcete stahovat. +Hodně výměny kódu probíhá v otevřeném gitovém světě metodou „prosím stáhněte si“. V korporátním prostředí ovšem nebývá jakýkoliv přístup bez prokázání totožnosti vítán a pracovní stanice vývojáře nemůže provádět autentizaci, takže můžete na centrální server odesílat, ale musíte požádat někoho jiného, když odtud chcete stahovat. -To by za normálních okolností způsobilo stejný zmatek ve jménech větví jako v centralizovaných systémech správy verzí a navíc nastavování přístupových práv by se stalo noční můrou pro administrátory. +To by za normálních okolností způsobilo stejný zmatek ve jménech větví jako v centralizovaných systémech správy verzí a navíc nastavování přístupových práv by administrátorovi přidalo práci. Gitolite vám umožní nadefinovat pro každého vývojáře jmenné prostory s prefixy „personal“ nebo „scratch“ (např. `refs/personal//*`). Podrobnosti hledejte v dokumentaci. ### „Wildcard“ repozitáře ### -Gitolite vám umožní určit repozitáře zástupnými znaky (wildcards; ve skutečnosti jde o perlovské regulární výrazy) -- například k náhodnému výběru zadání příkladu můžeme použít `assignments/s[0-9][0-9]/a[0-9][0-9]`. Umožní nám též přidělit nový režim oprávnění (`C`), který uživatelům povoluje vytvářet repozitáře popsané zástupnými znaky, automaticky přidělí vlastnictví konkrétnímu uživateli, který jej vytvořil, umožní mu přidělit oprávnění `R` a `RW` dalším spolupracovníkům atd. Podrobnosti opět hledejte v dokumentaci. +Gitolite vám umožní určit repozitáře zástupnými znaky (wildcards; ve skutečnosti jde o perlovské regulární výrazy) -- jako například u náhodně vybraného příkladu `assignments/s[0-9][0-9]/a[0-9][0-9]`. Umožní nám též přidělit nový režim oprávnění (`C`), který uživatelům povoluje vytvářet repozitáře popsané zástupnými znaky, automaticky přidělí vlastnictví konkrétnímu uživateli, který jej vytvořil, umožní mu přidělit oprávnění `R` a `RW` dalším spolupracovníkům atd. Podrobnosti opět hledejte v dokumentaci. ### Další vlastnosti ### @@ -638,7 +648,7 @@ Vysvětlení Gitolite završíme přehledem několika vlastností, které jsou d **Logování:** Gitolite loguje všechny úspěšné přístupy. Jestliže máte volná pravidla pro přidělování oprávnění vracet změny (práva `RW+`) a stane se, že někdo takto „zkazí“ větev `master`, je tu ještě log soubor, který vám zachrání život, protože v něm můžete postižené SHA najít. -**Přehledy uživatelských oprávnění:** Další příjemnou vlastností je to, co se stane, pokud se pouze pokusíte připojit pomocí SSH na server. Gitolite vám ukáže, ke kterým repozitářům máte přístup a s jakoými oprávněními. Příklad: +**Přehledy uživatelských oprávnění:** Další příjemnou vlastností je to, co se stane, pokud se pouze pokusíte připojit pomocí SSH na server. Gitolite vám ukáže, ke kterým repozitářům máte přístup a s jakými oprávněními. Příklad: hello scott, this is git@git running gitolite3 v3.01-18-g9609868 on git 1.7.4.4 @@ -650,15 +660,15 @@ Vysvětlení Gitolite završíme přehledem několika vlastností, které jsou d R indic_web_input R shreelipi_converter -**Delegace:** Pro opravdu velké instalace můžete delegovat zodpovědnost za skupiny a repozitáře dalším lidem a nechat je samotné spravovat jednotlivé části. To snižuje vytížení hlavního administrátora, který tím přestává být úským místem správy. +**Delegace:** Pro opravdu velké instalace můžete delegovat zodpovědnost za skupiny a repozitáře dalším lidem a nechat je spravovat jednotlivé části nezávisle. To snižuje vytížení hlavního administrátora, který tím přestává být úzkým místem správy. **Zrcadlení:** Gitolite vám pomůže se správou více zrcadel a při výpadku hlavního serveru můžete snadno přepnout na jiný. ## Démon Git ## -Jestliže potřebujete ke svým projektům veřejný, neověřovaný přístup pro čtení, budete muset překročit hranice vymezené protokolem HTTP a začít používat protokol Git. Mluví pro něj především rychlost. Protokol Git je daleko výkonnější, a proto také rychlejší než protokol HTTP a svým uživatelů tím ušetří spoustu času. +Jestliže potřebujete ke svým projektům přístup pro čtení bez ověřování totožnosti, budete muset obejít protokol HTTP a začít používat protokol Git. Mluví pro něj především rychlost. Protokol Git je daleko výkonnější, a proto také rychlejší než protokol HTTP, takže uživatelům ušetří nějaký čas. -I v tomto případě se jedná o neověřený přístup pouze pro čtení. Pokud protokol používáte na serveru mimo firewall, mělo by to být pouze u projektů, které jsou veřejně viditelné okolnímu světu. Pokud je server, na kterém protokol spouštíte, uvnitř firewallu, můžete ho používat u projektů, k nimž má přístup pro čtení velký počet lidí nebo počítačů (servery průběžné integrace nebo servery sestavení), jimž nechcete jednotlivě přiřazovat SSH klíče. +I v tomto případě se jedná o přístup pouze pro čtení bez ověřování totožnosti. Pokud protokol používáte na serveru mimo firewall, mělo by to být pouze u projektů, které jsou veřejně viditelné okolnímu světu. Pokud je server, na kterém protokol spouštíte, uvnitř firewallu, můžete ho používat u projektů, k nimž má přístup pro čtení velký počet lidí nebo počítačů (servery průběžné integrace nebo servery sestavení), jimž nechcete jednotlivě přiřazovat SSH klíče. Ať tak či tak, na protokolu Git jistě oceníte jeho snadné nastavení. V podstatě je třeba spustit tento příkaz: @@ -689,7 +699,7 @@ Při restartování počítače se démon Git spustí automaticky. V případě V jiných systémech možná budete chtít použít `xinetd`, skript systému `sysvinit`, nebo podobný skript – můžete-li spouštět příkaz démonizovaný a sledovaný. -Dále budete muset svému serveru Gitosis sdělit, k jakým repozitářům si přejete povolit neověřený serverový přístup Git. Pokud přidáte jednu část pro každý repozitář, můžete určit repozitáře, z nichž si přejete dovolit démonovi Git načítat data. Chcete-li povolit přístup přes protokol Git k projektu `iphone_project`, přidejte ho na konec souboru `gitosis.conf`: +Dále budete muset svému serveru Gitosis sdělit, k jakým repozitářům si přejete povolit neautentizovaný serverový přístup Git. Pokud pro každý repozitář přidáte sekci, můžete určit repozitáře, z nichž si přejete dovolit démonovi Git načítat data. Chcete-li povolit přístup přes protokol Git k projektu `iphone_project`, přidejte ho na konec souboru `gitosis.conf`: [repo iphone_project] daemon = yes @@ -701,7 +711,7 @@ Pokud nechcete používat Gitosis, ale chcete nastavit démona Git, budete muset $ cd /path/to/project.git $ touch git-daemon-export-ok -Přítomnost tohoto souboru systému Git sděluje, že si přejete obsluhovat tento projekt bez ověřování. +Přítomnost tohoto souboru systému Git sděluje, že si přejete obsluhovat tento projekt bez ověřování totožnosti. Gitosis může také určovat, jaké projekty bude zobrazovat GitWeb. Nejprve budete muset do souboru `/etc/gitweb.conf` vložit následující: @@ -720,15 +730,15 @@ Pokud teď zapíšete a odešlete projekt, GitWeb začne automaticky zobrazovat ## Hostování projektů Git ## -Pokud nemáte chuť absolvovat celý proces nastavování vlastního serveru Git, existuje několik možností hostování vašich projektů Git na externím specializovaném hostingovém místě. Toto řešení vám nabízí celou řadu výhod. Hostingové místo má většinou velmi rychlé nastavení, snadno se na něm spouštějí projekty a nevyžaduje od vás správu ani monitoring serveru. Dokonce i když budete nastavovat a spouštět interně svůj vlastní server, budete možná přesto chtít použít veřejné hostingové místo pro otevřený zdrojový kód – komunita open source vývojářů si vás tak snáze najde a pomůže vám. +Pokud nemáte chuť absolvovat celý proces nastavování vlastního serveru Git, existuje několik možností hostování vašich projektů Git na externím specializovaném hostingovém místě. Toto řešení vám nabízí celou řadu výhod. Hostingové místo má většinou velmi rychlé nastavení, snadno se na něm zakládají projekty a nevyžaduje od vás správu ani monitoring serveru. Dokonce i když budete nastavovat a spouštět interně svůj vlastní server, budete možná přesto chtít použít veřejné hostingové místo pro otevřený zdrojový kód – komunita open source vývojářů si vás tak snáze najde a pomůže vám. -V dnešní době můžete vybírat z velkého počtu možností hostingu. Každá má jiné klady a zápory. Aktuální seznam těchto míst najdete na stránce GitHosting, dostupné z hlavní stránky GitWiki: +V dnešní době můžete vybírat z velkého počtu možností hostingu. Každá má jiné klady a zápory. Aktuální seznam těchto míst najdete na následující stránce: https://git.wiki.kernel.org/index.php/GitHosting Protože se tu nemůžeme věnovat všem možnostem a protože shodou okolností na jednom hostingovém místě pracuji, využijeme tuto část k tomu, abychom ukázali nastavení účtu a vytvoření nového projektu na serveru GitHub. Získáte tak představu, co všechno vás čeká. -GitHub je zdaleka největším hostingovým místem pro projekty Git s otevřeným zdrojovým kódem a je zároveň jedním z velmi mála těch, která nabízejí možnosti jak veřejného, tak soukromého hostingu. Na jednom místě tak můžete mít uložen jak otevřený zdrojový kód, tak soukromý komerční kód. GitHub se ostatně soukromě podílel i na vzniku této knihy. +GitHub je zdaleka největším hostingovým místem pro projekty Git s otevřeným zdrojovým kódem a je zároveň jedním z velmi mála těch, která nabízejí možnosti jak veřejného, tak soukromého hostingu. Na jednom místě tak můžete mít uložen jak otevřený zdrojový kód, tak soukromý komerční kód. Možnost soukromého použití GitHub jsme ostatně používali pro spolupráci při vzniku této knihy. ### GitHub ### @@ -738,7 +748,7 @@ GitHub je zároveň komerční společnost, jejíž finanční příjmy plynou z ### Založení uživatelského účtu ### -První věcí, kterou budete muset udělat, je vytvoření bezplatného uživatelské účtu. Jestliže na stránce „Pricing and Signup“ (`http://github.com/plans`) kliknete u bezplatného účtu (Free) na tlačítko „Sign Up“ (viz obrázek 4-2), přejdete na registrační stránku. +První věcí, kterou budete muset udělat, je vytvoření bezplatného uživatelské účtu. Jestliže na stránce „Pricing and Signup“ (`https://github.com/pricing`) kliknete u bezplatného účtu (Free) na tlačítko „Sign Up“ (viz obrázek 4-2), přejdete na registrační stránku. Insert 18333fig0402.png Obrázek 4-2. Výběr typu účtu na serveru GitHub @@ -763,7 +773,7 @@ Začněte kliknutím na odkaz „create a new one“ (vytvořit nový) vedle nad Insert 18333fig0405.png Obrázek 4-5. Vytvoření nového repozitáře na serveru GitHub -Vše, co tu bezpodmínečně musíte udělat, je zadat název projektu. Kromě toho můžete přidat i jeho popis. Poté klikněte na tlačítko „Create Repository“ (Vytvořit repozitář). Nyní máte na serveru GitHub vytvořen nový repozitář (viz obrázek 4-6). +Vše, co tu opravdu musíte udělat, je zadat název projektu. Kromě toho můžete přidat i jeho popis. Poté klikněte na tlačítko „Create Repository“ (Vytvořit repozitář). Nyní máte na serveru GitHub vytvořen nový repozitář (viz obrázek 4-6). Insert 18333fig0406.png Obrázek 4-6. Záhlaví s informacemi o projektu na serveru GitHub @@ -795,7 +805,7 @@ Obrázek 4-8. Záhlaví projektu s veřejnou a soukromou adresou URL ### Import ze systému Subversion ### -Máte-li existující veřejný projekt Subversion, který byste rádi importovali do systému Git, GitHub vám s tím často ochotně pomůže. Dole na stránce s instrukcemi najdete odkaz na import ze systému Subversion. Pokud na něj kliknete, zobrazí se formulář s informacemi o importu a textové pole, kam můžete vložit adresu URL svého veřejného projektu Subversion (viz obrázek 4-9). +Máte-li existující veřejný projekt Subversion, který byste rádi importovali do systému Git, GitHub vám s tím obvykle pomůže. Dole na stránce s instrukcemi najdete odkaz na import ze systému Subversion. Pokud na něj kliknete, zobrazí se formulář s informacemi o importu a textové pole, kam můžete vložit adresu URL svého veřejného projektu Subversion (viz obrázek 4-9). Insert 18333fig0409.png Obrázek 4-9. Rozhraní importu ze systému Subversion @@ -830,20 +840,20 @@ Po odeslání projektu nebo jeho naimportování ze systému Subversion budete m Insert 18333fig0413.png Obrázek 4-13. Hlavní stránka projektu na serveru GitHub -Navštíví-li váš projekt ostatní uživatelé, tuto stránku uvidí. Obsahuje několik záložek k různým aspektům vašich projektů. Záložka „Commits“ zobrazuje seznam revizí v obráceném chronologickém pořadí, podobně jako výstup příkazu `git log`. Záložka „Network“ zobrazuje všechny uživatele, kteří rozštěpili váš projekt a přispěli do něj. Záložka „Downloads“ umožňuje nahrávat binární soubory k projektu a přidávat odkazy na tarbally a komprimované verze všech míst ve vašem projektu, které jsou označeny značkou (tagem). Záložka „Wiki“ vám nabízí stránku wiki, kam můžete napsat dokumentaci nebo jiné informace ke svému projektu. Záložka „Graphs“ graficky zobrazuje některé příspěvky a statistiky k vašemu projektu. Hlavní záložka „Source“, na níž se stránka otvírá, zobrazuje hlavní adresář vašeho projektu, a máte-li soubor README, automaticky ho zařadí na konec seznamu. Tato záložka obsahuje rovněž pole s informacemi o poslední zapsané revizi. +Navštíví-li váš projekt ostatní uživatelé, tuto stránku uvidí. Obsahuje několik záložek k různým aspektům vašich projektů. Záložka „Commits“ zobrazuje seznam revizí v obráceném chronologickém pořadí, podobně jako výstup příkazu `git log`. Záložka „Network“ zobrazuje všechny uživatele, kteří se odštěpili od vašeho projektu a zase do něj přispěli. Záložka „Downloads“ umožňuje nahrávat binární soubory k projektu a přidávat odkazy na tarbally a komprimované verze všech míst ve vašem projektu, které jsou označeny značkou (tagem). Záložka „Wiki“ vám nabízí stránku wiki, kam můžete napsat dokumentaci nebo jiné informace ke svému projektu. Záložka „Graphs“ graficky zobrazuje některé příspěvky a statistiky k vašemu projektu. Hlavní záložka „Source“, na níž se stránka otvírá, zobrazuje hlavní adresář vašeho projektu, a máte-li soubor README, automaticky pod adresářem projektu zobrazí jeho obsah. Tato záložka obsahuje rovněž pole s informacemi o poslední zapsané revizi. ### Štěpení projektů ### -Chcete-li přispět do existujícího projektu, k němuž nemáte oprávnění pro odesílání, umožňuje GitHub rozštěpení projektu. Pokud se dostanete na zajímavou stránku projektu a chtěli byste se do projektu zapojit, můžete kliknout na tlačítko „fork“ (rozštěpit) v záhlaví projektu a GitHub vytvoří kopii projektu pro vašeho uživatele. Do ní pak můžete odesílat revize. +Chcete-li přispět do existujícího projektu, k němuž nemáte oprávnění pro odesílání, umožňuje GitHub rozštěpení projektu. Pokud se dostanete na zajímavou stránku projektu a chtěli byste se do projektu zapojit, můžete kliknout na tlačítko „fork“ (rozštěpit -- doslova vidlička) v záhlaví projektu a GitHub vytvoří kopii projektu pro vašeho uživatele. Do ní pak můžete odesílat revize. -Díky tomu se projekty nemusí starat o přidávání uživatelů do role spolupracovníků, aby mohli odesílat své příspěvky. Uživatelé mohou projekt rozštěpit a odesílat do něj revize. Hlavní správce projektu tyto změny natáhne tím, že je přidá jako vzdálené repozitáře a začlení jejich data. +Díky tomu se projekty nemusí starat o přidávání uživatelů do role spolupracovníků, kteří by měli právo zápisu. Uživatelé mohou projekt rozštěpit a odesílat do něj revize. Hlavní správce projektu tyto změny natáhne tím, že je přidá jako vzdálené repozitáře a začlení jejich data. Chcete-li projekt rozštěpit, přejděte na stránku projektu (v tomto případě mojombo/chronic) a klikněte na tlačítko „fork“ v záhlaví (viz obrázek 4-14). Insert 18333fig0414.png Obrázek 4-14. Zapisovatelnou kopii jakéhokoli repozitáře získáte kliknutím na tlačítko „fork“. -Po několika sekundách přejdete na novou stránku svého projektu, která oznamuje, že je tento projekt rozštěpením (fork) jiného projektu (viz obrázek 4-15). +Po několika sekundách přejdete na novou stránku svého projektu, která oznamuje, že je tento projekt odštěpen (fork) z jiného projektu (viz obrázek 4-15). Insert 18333fig0415.png Obrázek 4-15. Vaše rozštěpení projektu @@ -858,4 +868,4 @@ Existuje několik možností, jak vytvořit a zprovoznit vzdálený repozitář Provoz vlastního serveru vám dává celou řadu možností kontroly a umožňuje provozovat server za vaším firewallem. Nastavení a správa takového serveru však obvykle bývají časově náročné. Umístíte-li data na hostovaný server, je jejich nastavení a správa jednoduchá. Svůj zdrojový kód však v takovém případě ukládáte na cizím serveru, což některé organizace nedovolují. -Mělo by být jasně dáno, které řešení nebo jaká kombinace řešení je vhodná pro vás a pro vaši organizaci. +Teď už byste se měli umět rozhodnout, které řešení nebo jaká kombinace řešení se pro vás a pro vaši organizaci hodí. diff --git a/cs/05-distributed-git/01-chapter5.markdown b/cs/05-distributed-git/01-chapter5.markdown index e046c1f2d..da4cbf4b8 100644 --- a/cs/05-distributed-git/01-chapter5.markdown +++ b/cs/05-distributed-git/01-chapter5.markdown @@ -6,7 +6,7 @@ V této kapitole se dozvíte, jak pracovat se systémem Git v distribuovaném pr ## Distribuované pracovní postupy ## -Na rozdíl od centralizovaných systémů správy verzí (CVCS) umožňuje distribuovaný charakter systému Git mnohem větší flexibilitu při spolupráci vývojářů na projektech. V centralizovaných systémech představuje každý vývojář samostatný uzel, pracující více či méně na stejné úrovni vůči centrálnímu úložišti. Naproti tomu je v systému Git každý vývojář potenciálním uzlem i úložištěm, každý vývojář může přispívat kódem do jiných repozitářů i spravovat veřejný repozitář, na němž mohou ostatní založit svou práci a do nějž mohou přispívat. Tím se otvírá široké spektrum možností organizace práce pro váš projekt a/nebo váš tým. Zkusíme se tedy podívat na pár častých postupů, které tato flexibilita umožňuje. Uvedeme přednosti i eventuální slabiny všech těchto postupů. Budete si moci vybrat některý z postupů nebo je navzájem kombinovat a spojovat jejich funkce. +Na rozdíl od centralizovaných systémů správy verzí (CVCS) umožňuje distribuovaný charakter systému Git mnohem větší flexibilitu při spolupráci vývojářů na projektech. V centralizovaných systémech představuje každý vývojář samostatný uzel, pracující více či méně na stejné úrovni vůči centrálnímu úložišti. Naproti tomu je v systému Git každý vývojář potenciálním uzlem i úložištěm, každý vývojář může přispívat kódem do jiných repozitářů i spravovat veřejný repozitář, na němž mohou ostatní založit svou práci a do nějž mohou přispívat. Tím se pro váš projekt a váš tým otvírá široké spektrum pracovních postupů. Zkusíme se tedy podívat na pár častých přístupů, které tato flexibilita umožňuje. Uvedeme jejich přednosti i eventuální slabiny. Budete si moci vybrat některý z postupů nebo je navzájem kombinovat a spojovat jejich vlastnosti. ### Centralizovaný pracovní postup ### @@ -17,12 +17,12 @@ Obrázek 5-1. Centralizovaný pracovní postup To znamená, že pokud dva vývojáři klonují z centrálního úložiště a oba provedou změny, jen první z nich, který odešle své změny, to může provést bez komplikací. Druhý vývojář musí před odesláním svých změn začlenit práci prvního vývojáře do své, aby nepřepsal jeho změny. Tento koncept platí jak pro Git, tak pro Subversion (popř. jakýkoli CVCS). I v systému Git funguje bez problémů. -Pokud pracujete v malém týmu nebo už jste ve své společnosti nebo ve svém týmu zvyklí na centralizovaný pracovní postup, můžete v něm beze všeho pokračovat. Jednoduše vytvořte repozitář a přidělte všem ze svého týmu oprávnění k odesílání dat. Git neumožní uživatelům, aby se navzájem přepisovali. Pokud některý z vývojářů naklonuje data, provede změny a poté se je pokusí odeslat, a jiný vývojář mezitím odeslal svoje revize, server tyto změny odmítne. Git vývojáři při odmítnutí sdělí, že se pokouší odeslat změny, které nesměřují „rychle vpřed“, což není možné provést, dokud nevyzvedne a nezačlení stávající data z repozitáře. +Pokud pracujete v malém týmu nebo už jste ve své společnosti nebo ve svém týmu zvyklí na centralizovaný pracovní postup, můžete v něm beze všeho pokračovat. Jednoduše vytvořte repozitář a přidělte všem ze svého týmu oprávnění k odesílání dat. Git neumožní uživatelům, aby se navzájem přepisovali. Pokud některý z vývojářů naklonuje data, provede změny a poté se je pokusí odeslat, a jiný vývojář mezitím odeslal svoje revize, server tyto změny odmítne. Git vývojáři při odmítnutí sdělí, že se pokouší odeslat změny, které nesměřují „rychle vpřed“, což není možné provést, dokud nevyzvedne a nezačlení (fetch and merge) stávající data z repozitáře. Tento pracovní postup může být pro mnoho lidí zajímavý, protože je to schéma, které jsou zvyklí používat a jsou s ním spokojeni. ### Pracovní postup s integračním manažerem ### -Protože Git umožňuje, abyste měli několik vzdálených repozitářů, lze použít pracovní postup, kdy má každý vývojář oprávnění k zápisu do vlastního veřejného repozitáře a oprávnění pro čtení k repozitářům všech ostatních. Tento scénář často zahrnuje jeden standardní repozitář, který reprezentuje „oficiální“ projekt. Chcete-li do tohoto projektu přispívat, vytvořte vlastní veřejný klon projektu a odešlete do něj změny, které jste provedli. Poté odešlete správci hlavního projektu žádost, aby do projektu natáhl vaše změny. Váš repozitář může přidat jako vzdálený repozitář, lokálně otestovat vaše změny, začlenit je do své větve a odeslat zpět do svého repozitáře. Postup práce je následující (viz obrázek 5-2): +Protože Git umožňuje, abyste měli několik vzdálených repozitářů, lze použít pracovní postup, kdy má každý vývojář oprávnění k zápisu do vlastního veřejného repozitáře a oprávnění pro čtení k repozitářům všech ostatních. Tento scénář často zahrnuje jeden standardní repozitář, který reprezentuje „oficiální“ projekt. Chcete-li do tohoto projektu přispívat, vytvořte vlastní veřejný klon projektu a odešlete do něj změny, které jste provedli. Poté odešlete správci hlavního projektu žádost, aby do projektu natáhl vaše změny. Správce může váš repozitář přidat jako vzdálený repozitář, lokálně otestovat vaše změny, začlenit je do své větve a odeslat zpět do svého repozitáře. Postup práce je následující (viz obrázek 5-2): 1. Správce projektu odešle data do svého veřejného repozitáře. 2. Přispěvatel naklonuje tento repozitář a provede změny. @@ -34,7 +34,7 @@ Protože Git umožňuje, abyste měli několik vzdálených repozitářů, lze p Insert 18333fig0502.png Obrázek 5-2. Pracovní postup s integračním manažerem -Tento pracovní postup je velmi rozšířený na stránkách jako GitHub, kde je snadné rozštěpit projekt a odeslat změny do své odštěpené části, kde jsou pro každého k nahlédnutí. Jednou z hlavních předností tohoto postupu je, že můžete pracovat bez přerušení a správce hlavního repozitáře může natáhnout vaše změny do projektu, kdykoli uzná za vhodné. Přispěvatelé nemusí čekat, až budou jejich změny začleněny do projektu – každá strana může pracovat svým tempem. +Tento pracovní postup je velmi rozšířený na serverech jako je GitHub, kde je snadné rozštěpit projekt a odeslat změny do své odštěpené části, kde jsou pro každého k nahlédnutí. Jednou z hlavních předností tohoto postupu je, že můžete pracovat bez přerušení a správce hlavního repozitáře může natáhnout vaše změny do projektu, kdykoli uzná za vhodné. Přispěvatelé nemusí čekat, až budou jejich změny začleněny do projektu – každá strana může pracovat svým tempem. ### Pracovní postup s diktátorem a poručíky ### @@ -174,7 +174,7 @@ John má referenci ke změnám, které odeslala Jessica, ale než bude moci sám Sloučení probíhá hladce, Johnova historie revizí teď vypadá jako na obrázku 5-5. Insert 18333fig0505.png -Obrázek 5-5. Johnův repozitář po začlenění větve origin/master +Obrázek 5-5. Johnův repozitář po začlenění větve `origin/master` John nyní může otestovat svůj kód, aby se ujistil, že stále pracuje správně, a pak může odeslat svou novou sloučenou práci na server: @@ -215,7 +215,7 @@ Jessica považuje svou tematickou větev za dokončenou, ale chce vědět, do č removed invalid default value -Jessica nyní může začlenit tematickou větev do své hlavní větve, tamtéž začlenit i Johnovu práci (`origin/master`) do své větve `master` a vše odeslat zpět na server. Nejprve se přepne zpět na svou hlavní větev, aby do ní mohla vše integrovat: +Jessica nyní může začlenit tematickou větev do své větve `master`, začlenit (merge) i Johnovu práci (`origin/master`) do své větve `master` a vše odeslat zpět na server. Nejprve se přepne zpět na svou větev `master`, aby do ní mohla vše integrovat: $ git checkout master Switched to branch "master" @@ -255,7 +255,7 @@ Všichni vývojáři zapsali několik revizí a úspěšně začlenili práci os Insert 18333fig0510.png Obrázek 5-10. Historie Jessicy po odeslání všech změn zpět na server -Toto je jeden z nejjednodušších pracovních postupů. Po určitou dobu pracujete, obvykle na nějaké tematické větvi, a když je připravena k integraci, začleníte ji do hlavní větve. Chcete-li tuto práci sdílet, začleníte ji do své hlavní větve. Poté vyzvednete a začleníte větev `origin/master`, jestliže se změnila. Nakonec odešlete všechna data do větve `master` na serveru. Obecná posloupnost kroků je naznačena na obrázku 5-11. +Toto je jeden z nejjednodušších pracovních postupů. Po určitou dobu pracujete, obvykle na nějaké tematické větvi, a když je připravena k integraci, začleníte ji do své větve `master`. Chcete-li tuto práci sdílet, začleníte ji do své větve `master`. Poté vyzvednete (fetch) a začleníte (merge) větev `origin/master`, jestliže se změnila. Nakonec odešlete všechna data do větve `master` na serveru. Obecná posloupnost kroků je naznačena na obrázku 5-11. Insert 18333fig0511.png Obrázek 5-11. Obecná posloupnost kroků u jednoduchého pracovního postupu s více vývojáři v systému Git @@ -328,7 +328,7 @@ Tady nastává určitý problém. Musí odeslat práci začleněnou ve své vět To jessica@githost:simplegit.git fba9af8..cd685d1 featureB -> featureBee -Říká se tomu refspec. Více o vzorcích refspec systému Git a různých možnostech, k nimž je lze využít, najdete v kapitole 9. +Říká se tomu *refspec*. Více o vzorcích refspec systému Git a různých možnostech, k nimž je lze využít, najdete v kapitole 9. Poté pošle John Jessice e-mail, že odeslal několik změn do větve `featureA`, a poprosí ji, aby je ověřila. Jessica spustí příkaz `git fetch`, jímž tyto změny stáhne. @@ -532,7 +532,26 @@ Nejprve je třeba nastavit sekci „imap“ v souboru `~/.gitconfig`. Každou ho sslverify = false Pokud váš server IMAP nepoužívá SSL, dva poslední řádky zřejmě nebudou vůbec třeba a hodnota hostitele bude `imap://`, a nikoli `imaps://`. -Až toto nastavení dokončíte, můžete použít příkaz `git send-email`, jímž umístíte sérii patchů do složky Koncepty (Drafts) zadaného serveru IMAP: +Až toto nastavení dokončíte, můžete použít příkaz `git imap-send`, jímž umístíte sérii záplat (patch) do složky Koncepty (Drafts) zadaného serveru IMAP: + + $ 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 + +V tomto okamžiku byste měli být schopni přejít do složky Drafts, změnit pole To na mailing list, do kterého záplatu posíláte, případně pole CC na správce nebo na osobu zodpovědnou za tuto část, a odeslat. + +Záplaty můžete odesílat i přes SMTP server. Stejně jako v předchozím případu můžete nastavit sérií příkazů `git config` každou hodnotu zvlášť, nebo je můžete vložit ručně do sekce sendemail souboru `~/.gitconfig`: + + [sendemail] + smtpencryption = tls + smtpserver = smtp.gmail.com + smtpuser = user@gmail.com + smtpserverport = 587 + +Jakmile je to hotové, můžete záplaty odeslat příkazem `git send-email`: $ git send-email *.patch 0001-added-limit-to-log-function.patch @@ -559,8 +578,6 @@ Git poté vytvoří log s určitými informacemi, který bude pro každou zápla Result: OK -V tomto okamžiku můžete přejít do své složky Koncepty, změnit pole Komu na adresáty z poštovní konference, jimž chcete záplatu odeslat, případně přidat kopii na správce nebo osobu odpovědnou za tuto část a e-mail odeslat. - ### Shrnutí ### V této části jsme popsali několik obvyklých pracovních postupů při přispívání do velmi odlišných typů projektů Git, s nimiž se můžete setkat. Představili jsme k nim také nové nástroje, které vám mohou v těchto procesech pomoci. V další části se na projekty podíváme z té druhé strany – ukážeme, jak může vypadat jejich správa. Dozvíte se, jak být benevolentním diktátorem nebo integračním manažerem. @@ -594,7 +611,7 @@ Pokud dostanete záplatu od někoho, kdo ji vygeneroval příkazem `git diff` ne Tím změníte soubory ve svém pracovním adresáři. Je to téměř stejné, jako byste k aplikaci záplaty použili příkaz `patch -p1`. Tento postup je však přísnější a nepřijímá tolik přibližných shod jako příkaz patch. Poradí si také s přidanými, odstraněnými a přejmenovanými soubory, jsou-li popsány ve formátu `git diff`, což příkaz `patch` nedělá. A konečně příkaz `git apply` pracuje na principu „aplikuj vše, nebo zruš vše“. Buď jsou tedy aplikovány všechny soubory, nebo žádný. Naproti tomu příkaz `patch` může aplikovat soubory záplaty jen částečně a zanechat váš pracovní adresář v neurčitém stavu. Příkaz `git apply` je tedy celkově víc paranoidní než příkaz `patch`. Tímto příkazem ostatně ani nezapíšete revizi, po jeho spuštění budete muset připravit a zapsat provedené změny ručně. -Příkaz git apply můžete použít také ke kontrole, zda bude záplata aplikována čistě. V takovém případě použijte na patch příkaz `git apply --check`: +Příkaz `git apply` můžete použít také ke kontrole, zda bude záplata aplikována čistě. V takovém případě použijte na patch příkaz `git apply --check`: $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 @@ -615,7 +632,7 @@ K aplikaci patche vygenerovaného příkazem `format-patch` použijte příkaz ` Limit log functionality to the first 20 -Toto je začátek výstupu příkazu format-patch, s nímž jsme se setkali v předchozí části. Zároveň je to také platný e-mailový formát mbox. Jestliže vám přispěvatel řádně poslal záplatu e-mailem pomocí příkazu git send-email a vy záplatu stáhnete do formátu mbox, můžete na soubor mbox použít příkaz git am, který začne aplikovat všechny záplaty, které najde. Jestliže spustíte poštovního klienta, který dokáže uložit několik e-mailů ve formátu mbox, můžete do jednoho souboru uložit celou sérii záplat a příkazem git am je pak aplikovat všechny najednou. +Toto je začátek výstupu příkazu format-patch, s nímž jsme se setkali v předchozí části. Zároveň je to také platný e-mailový formát mbox. Jestliže vám přispěvatel řádně poslal záplatu e-mailem pomocí příkazu `git send-email` a vy záplatu stáhnete do formátu mbox, můžete na soubor mbox použít příkaz `git am`, který začne aplikovat všechny záplaty, které najde. Jestliže spustíte poštovního klienta, který dokáže uložit několik e-mailů ve formátu mbox, můžete do jednoho souboru uložit celou sérii záplat a příkazem `git am` je pak aplikovat všechny najednou. Pokud však někdo nahrál soubor záplaty vygenerovaný příkazem `format-patch` do tiketového nebo podobného systému, můžete soubor uložit lokálně a poté na tento uložený soubor použít příkaz `git am`. Tímto způsobem záplatu aplikujete: diff --git a/cs/06-git-tools/01-chapter6.markdown b/cs/06-git-tools/01-chapter6.markdown index 33cb6cc95..24e5a12d3 100644 --- a/cs/06-git-tools/01-chapter6.markdown +++ b/cs/06-git-tools/01-chapter6.markdown @@ -59,7 +59,7 @@ Někteří uživatelé bývají zmateni, že mohou mít v repozitáři – shodo Pokud náhodou zapíšete objekt, který má stejnou hodnotu SHA-1 otisku jako předchozí objekt ve vašem repozitáři, Git už uvidí předchozí objekt v databázi Git a bude předpokládat, že už byl zapsán. Pokud se někdy v budoucnosti pokusíte znovu provést checkout tohoto objektu, vždy dostanete data prvního objektu. -Měli bychom však také říci, jak moc je nepravděpodobné, že taková situace nastane. Otisk SHA-1 má 20 bytů, neboli 160 bitů. Počet objektů s náhodným otiskem, které bychom potřebovali k 50% pravděpodobnosti, že nastane jediná kolize, je asi 2^80 (vzorec k určení pravděpodobnosti kolize je `p = (n(n-1)/2) * (1/2^160))`. 2^80 je 1,2 * 10^24, neboli 1 milion miliard miliard. To je 1200násobek počtu všech zrnek písku na celé Zemi. +Měli bychom však také říci, jak moc je nepravděpodobné, že taková situace nastane. Otisk SHA-1 má 20 bytů, neboli 160 bitů. Počet objektů s náhodným otiskem, které bychom potřebovali k 50% pravděpodobnosti, že nastane jediná kolize, je asi 2^80 (vzorec k určení pravděpodobnosti kolize je `p = (n(n-1)/2) * (1/2^160)`). 2^80 je 1,2 * 10^24, neboli 1 milion miliard miliard. To je 1200násobek počtu všech zrnek písku na celé Zemi. Abyste si udělali představu, jak je nepravděpodobné, že dojde ke kolizi hodnot SHA-1, připojujeme jeden malý příklad. Kdyby 6,5 miliardy lidí na zemi programovalo a každý by každou sekundu vytvořil kód odpovídající celé historii linuxového jádra (1 milion objektů Git) a odesílal ho do jednoho obřího repozitáře Git, trvalo by 5 let, než by repozitář obsahoval dost objektů na to, aby existovala 50% pravděpodobnost, že dojde ke kolizi jediného objektu SHA-1. To už je pravděpodobnější, že všichni členové vašeho programovacího týmu budou během jedné noci v navzájem nesouvisejících incidentech napadeni a zabiti smečkou vlků. @@ -82,13 +82,13 @@ Jednou z věcí, které probíhají na pozadí systému Git, zatímco vy pracuje Svůj reflog si můžete nechat zobrazit příkazem `git reflog`: $ git reflog - 734713b... HEAD@{0}: commit: fixed refs handling, added gc auto, updated - d921970... HEAD@{1}: merge phedders/rdocs: Merge made by recursive. - 1c002dd... HEAD@{2}: commit: added some blame and merge stuff - 1c36188... HEAD@{3}: rebase -i (squash): updating HEAD - 95df984... HEAD@{4}: commit: # This is a combination of two commits. - 1c36188... HEAD@{5}: rebase -i (squash): updating HEAD - 7e05da5... HEAD@{6}: rebase -i (pick): updating HEAD + 734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated + d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive. + 1c002dd HEAD@{2}: commit: added some blame and merge stuff + 1c36188 HEAD@{3}: rebase -i (squash): updating HEAD + 95df984 HEAD@{4}: commit: # This is a combination of two commits. + 1c36188 HEAD@{5}: rebase -i (squash): updating HEAD + 7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD Pokaždé, když je z nějakého důvodu aktualizován vrchol větve, Git tuto informaci uloží v dočasné historii reflog. Pomocí těchto dat lze rovněž specifikovat starší revize. Chcete-li zobrazit pátou poslední hodnotu ukazatele HEAD svého repozitáře, použijte referenci `@{n}` z výstupu reflog: @@ -457,14 +457,14 @@ Váš pracovní adresář se vyčistil: $ git status # On branch master - nothing to commit (working directory clean) + nothing to commit, working directory clean Nyní můžete bez obav přepnout větve a pracovat na jiném úkolu, vaše změny byly uloženy do zásobníku. Chcete-li se podívat, které soubory jste odložili, spusťte příkaz `git stash list`: $ git stash list stash@{0}: WIP on master: 049d078 added the index file - stash@{1}: WIP on master: c264051... Revert "added file_size" - stash@{2}: WIP on master: 21d80a5... added number to log + stash@{1}: WIP on master: c264051 Revert "added file_size" + stash@{2}: WIP on master: 21d80a5 added number to log V tomto případě byly už dříve provedeny dva další odklady, a máte tak k dispozici tři různé odklady. Naposledy odložené soubory můžete znovu aplikovat příkazem, který byl uveden už v nápovědě ve výstupu původního příkazu stash: `git stash apply`. Chcete-li aplikovat některý ze starších odkladů, můžete ho určit na základě jeho označení, např. `git stash apply stash@{2}`. Pokud u příkazu neoznačíte konkrétní odklad, Git se automaticky pokusí aplikovat ten nejnovější: @@ -498,8 +498,8 @@ Parametr apply se pouze pokusí aplikovat odloženou práci, ta zůstává ulož $ git stash list stash@{0}: WIP on master: 049d078 added the index file - stash@{1}: WIP on master: c264051... Revert "added file_size" - stash@{2}: WIP on master: 21d80a5... added number to log + stash@{1}: WIP on master: c264051 Revert "added file_size" + stash@{2}: WIP on master: 21d80a5 added number to log $ git stash drop stash@{0} Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43) @@ -518,7 +518,7 @@ Jestliže nespecifikujete konkrétní odklad, Git předpokládá odklad posledn Můžete si také vytvořit alias a do svého gitu přidat například příkaz `stash-unapply`: $ git config --global alias.stash-unapply '!git stash show -p | git apply -R' - $ git stash + $ git stash apply $ #... work work work $ git stash-unapply @@ -583,12 +583,19 @@ Spuštěním tohoto příkazu otevřete textový editor se seznamem revizí zhru # # Commands: # p, pick = use commit + # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit + # f, fixup = like "squash", but discard this commit's log message + # x, exec = run command (the rest of the line) using shell + # + # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. + # # However, if you remove everything, the rebase will be aborted. # + # Note that empty commits are commented out Tady bychom chtěli upozornit, že revize jsou uvedeny v opačném pořadí, než jste zvyklí v případě příkazu `log`. Po spuštění příkazu `log` by se zobrazilo následující: @@ -607,6 +614,10 @@ Skript je třeba upravit tak, aby zastavil na revizi, v níž chcete provést zm Po uložení změn a zavření editoru vás Git vrátí zpět na poslední revizi v seznamu a zobrazí vám příkazový řádek s touto zprávou: + + $ git rebase -i HEAD~3 Stopped at 7482e0d... updated the gemspec to hopefully work better You can amend the commit now, with @@ -649,12 +660,19 @@ Další možností, jak lze využít interaktivního nástroje přeskládání, # # Commands: # p, pick = use commit + # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit + # f, fixup = like "squash", but discard this commit's log message + # x, exec = run command (the rest of the line) using shell + # + # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. + # # However, if you remove everything, the rebase will be aborted. # + # Note that empty commits are commented out Zadáte-li místo pick nebo edit instrukci pro komprimaci squash, Git aplikuje změnu na tomto řádku a změnu těsně před ní a zároveň sloučí dohromady obě zprávy k revizím. Chcete-li tedy vytvořit jedinou revizi z těchto tří revizí, bude skript vypadat takto: @@ -747,6 +765,12 @@ Dalším častým případem bývá, že uživatel zapomene spustit příkaz `gi Příkaz projde a přepíše všechny revize tak, aby obsahovaly novou adresu. Protože revize obsahují hodnoty SHA-1 svých rodičů, změní tento příkaz SHA všech revizí ve vaší historii, ne pouze těch, které mají odpovídající e-mailovou adresu. +### Velmi rychlá a nebezpečná zbraň: Big Friendly Giant Repo Cleaner (BFG) ### + +[Roberto Tyley](https://github.com/rtyley) vytvořil nástroj, který se funkčností podobá `filter-branch` a nazval jej BFG. (Celý název lze doslova přeložit jako Velký, přátelský, obří čistič repozitáře --- představte si pod tím, co chcete.) BFG neumí tolik věcí jako `filter-branch`, ale je *velmi* rychlý. Pro velké repozitáře to může být zásadní rozdíl. Pokud lze vámi zamýšlenou změnu pomocí BFG provést a pokud máte problémy s výkonností prostředí, pak byste o použití tohoto nástroje měli uvažovat. + +Podrobnosti naleznete na stránkách [BFG](http://rtyley.github.io/bfg-repo-cleaner/). + ## Ladění v systému Git ## Git také nabízí několik nástrojů, které vám pomohou ladit problémy v projektech. Protože je Git navržen tak, aby pracoval téměř s jakýmkoli typem projektu, jsou tyto nástroje velmi univerzální. Často vám mohou pomoci odhalit vzniklou chybu nebo problém. @@ -1077,9 +1101,9 @@ Až poté přepnete zpět, bude adresář `rack` prázdný. Buď můžete spusti ## Začlenění podstromu ## -Nyní, když jsme poznali obtíže spojené se systémem submodulů, podívejme se na jedno alternativní řešení tohoto problému. Git se vždy při slučování nejprve podívá, co a kam začleňuje, a podle toho zvolí vhodnou strategii začlenění. Pokud slučujete dvě větve, používá Git rekurzivní strategii. Pokud slučujete více než dvě větve, zvolí Git tzv. strategii chobotnice (octopus strategy). Git vybírá tyto strategie automaticky. Rekurzivní strategie zvládá složité třícestné slučování (např. s více než jedním společným předkem), ale nedokáže sloučit více než dvě větve. Chobotnicové sloučení dokáže naproti tomu sloučit několik větví, ale je opatrnější při předcházení složitým konfliktům. Proto je ostatně nastaveno jako výchozí strategie při slučování více než dvou větví. +Nyní, když jsme poznali obtíže spojené se systémem submodulů, podívejme se na jedno alternativní řešení tohoto problému. Git se vždy při slučování nejprve podívá, co a kam začleňuje, a podle toho zvolí vhodnou strategii začlenění. Pokud slučujete dvě větve, používá Git *rekurzivní* strategii. Pokud slučujete více než dvě větve, zvolí Git tzv. strategii *chobotnice* (octopus strategy). Git vybírá tyto strategie automaticky. Rekurzivní strategie zvládá složité třícestné slučování (např. s více než jedním společným předkem), ale nedokáže sloučit více než dvě větve. Chobotnicové sloučení dokáže naproti tomu sloučit několik větví, ale je opatrnější při předcházení složitým konfliktům. Proto je ostatně nastaveno jako výchozí strategie při slučování více než dvou větví. -Existují však ještě další strategie. Jednou z nich je tzv. začlenění podstromu (subtree merge), které lze použít jako řešení problémů se subprojektem. Ukažme si, jak se dá začlenit stejný adresář rack jako v předchozí části, tentokrát však s využitím strategie začlenění podstromu. +Existují však ještě další strategie. Jednou z nich je tzv. začlenění *podstromu* (subtree merge), které lze použít jako řešení problémů se subprojektem. Ukažme si, jak se dá začlenit stejný adresář rack jako v předchozí části, tentokrát však s využitím strategie začlenění podstromu. Začlenění podstromu spočívá v tom, že máte dva projekty a jeden z projektů se promítá do podadresáře druhého projektu a naopak. Pokud určíte strategii začlenění podstromu, je Git natolik inteligentní, aby zjistil, že je jeden podstromem druhého, a provedl sloučení odpovídajícím způsobem – počíná si opravdu sofistikovaně. @@ -1112,7 +1136,7 @@ Nyní máte kořenový adresář s projektem Rack ve větvi `rack_branch` a vlas $ ls README -Projekt Rack chcete do projektu `master` natáhnout jako podadresář. V systému Git k tomu slouží příkaz `git read-tree`. O příkazu `read-tree` a jeho příbuzných se více dočtete v kapitole 9, nyní však vězte, že načte kořenový strom jedné větve do vaší aktuální oblasti připravených změn a do pracovního adresáře. Přepnuli jste zpět na větev `master` a větev `rack` natáhnete do podadresáře `rack` své větve `master` hlavního projektu: +Projekt Rack chcete do projektu `master` natáhnout jako podadresář. V systému Git k tomu slouží příkaz `git read-tree`. O příkazu `read-tree` a jeho příbuzných se více dočtete v kapitole 9, nyní však vězte, že načte kořenový strom jedné větve do vaší aktuální oblasti připravených změn a do pracovního adresáře. Přepnuli jste zpět na větev `master` a větev `rack_branch` natáhnete do podadresáře `rack` své větve `master` hlavního projektu: $ git read-tree --prefix=rack/ -u rack_branch diff --git a/cs/07-customizing-git/01-chapter7.markdown b/cs/07-customizing-git/01-chapter7.markdown index 54d0ca3a5..e910b46f3 100644 --- a/cs/07-customizing-git/01-chapter7.markdown +++ b/cs/07-customizing-git/01-chapter7.markdown @@ -130,7 +130,7 @@ Chcete-li sami nastavit jednotlivé barvy, mají všechny tyto parametry navíc $ git config --global color.diff.meta "blue black bold" -U barev lze zadávat tyto hodnoty: normal (normální), black (černá), red (červená), green (zelená), yellow (žlutá), blue (modrá), magenta (purpurová), cyan (azurová) nebo white (bílá). Pokud chcete použít atribut, jakým bylo v předchozím příkladu například tučné písmo, můžete vybírat mezi bold (tučné), dim (tlumené), ul (podtržené), blink (blikající) a reverse (obrácené). +U barev lze zadávat tyto hodnoty: `normal` (normální), `black` (černá), `red` (červená), `green` (zelená), `yellow` (žlutá), `blue` (modrá), `magenta` (purpurová), `cyan` (azurová) nebo `white` (bílá). Pokud chcete použít atribut, jakým bylo v předchozím příkladu například tučné písmo, můžete vybírat mezi `bold` (tučné), `dim` (tlumené), `ul` (podtržené), `blink` (blikající) a `reverse` (obrácené). Chcete-li použít dílčí nastavení, podrobnější informace naleznete na manuálové stránce `git config`. @@ -142,7 +142,7 @@ Pokud ho chcete vyzkoušet, nemělo by vám v tom nic bránit, P4Merge funguje n P4Merge můžete stáhnout na této adrese: - http://www.perforce.com/perforce/downloads/component.html + http://www.perforce.com/product/components/perforce-visual-merge-and-diff-tools Pro začátek je třeba nastavit kvůli spouštění příkazů externí skripty wrapperu. Jako cestu ke spustitelnému souboru používám cestu v systému Mac. V ostatních systémech použijte cestu k umístění, kde máte nainstalován binární soubor `p4merge`. Nastavte wrapperový skript pro slučování `extMerge`, který bude volat binární soubor všemi dostupnými parametry: @@ -301,17 +301,21 @@ Chcete-li systému Git zadat, aby nakládal se všemi soubory `pbxproj` jako s b *.pbxproj -crlf -diff -Až v projektu spustíte příkaz git show nebo git diff, Git se nebude pokoušet konvertovat nebo opravovat chyby CRLF ani vypočítat ani zobrazit rozdíly v tomto souboru pomocí nástroje diff. V systému Git verze 1.6 můžete také použít existující makro s významem `-crlf -diff`: +Až v projektu spustíte příkaz `git show` nebo `git diff`, Git se nebude pokoušet konvertovat nebo opravovat chyby CRLF ani vypočítat ani zobrazit rozdíly v tomto souboru pomocí nástroje diff. Můžete také použít zabudované makro `binary` s významem `-crlf -diff`: *.pbxproj binary #### Nástroj diff pro binární soubory #### -Ve verzi 1.6 systému Git můžete použít funkci atributů Git k efektivnímu zpracování binárních souborů nástrojem diff. Systému Git přitom sdělíte, jak má konvertovat binární data do textového formátu, který lze zpracovávat běžným nástrojem diff. +V systému Git můžete zadáním vhodných parametrů efektivně porovnávat binární soubory. Dosáhnete toho tím, že systému Git sdělíte, jak má konvertovat binární data do textového formátu, který lze zpracovávat běžným algoritmem pro zjišťování rozdílů (diff). Ale otázkou je, jak byste měli konverzi *binárních* dat na text provést? Nejlepší by bylo, kdybyste našli nějaký nástroj, který vám binární tvar na textový převede. Naneštěstí existuje jen velmi málo binárních formátů, které lze převést na lidsky čitelný text. (Představte si, jak byste na text převáděli zvuková data.) Pokud takový případ nastal a nejste schopni textovou reprezentaci obsahu souboru získat, lze často poměrně snadno získat lidsky čitelný popis obsahu, metadata. Metadata vám sice neposkytnou plnou reprezentaci obsahu souboru, ale v každém případě je to lepší než nic. + +Oba popsané přístupy k získání použitelných informací o rozdílech si ukážeme na některých běžně používaných binárních formátech. + +Poznámka: Existují různé druhy binárních formátů, které obsahují text, a pro které se dají obtížně najít použitelné konvertory. V takovém případě můžete zkusit získat z vašeho souboru texty programem `strings`. Některé z těchto souborů ale mohou používat kódování UTF-16 nebo jiné kódování a `strings` v nich nic rozumného nenajde. Je to případ od případu. Nicméně program `strings` je k dispozici na většině operačních systémů Mac a Linux, takže může jít o dobrou první volbu při pokusech s celou řadou binárních souborů. #### Soubory MS Word #### -Protože se jedná o opravdu šikovnou a nepříliš známou funkci, uvedu několik příkladů. Tuto metodu budete využívat především k řešení jednoho z nejpalčivějších problémů, s nímž se lidstvo potýká: verzování dokumentů Word. Je všeobecně známo, že Word je nejpříšejnější editor na světě, přesto ho však – bůhví proč – všichni používají. Chcete-li verzovat dokumenty Word, můžete je uložit do repozitáře Git a všechny hned zapsat do revize. K čemu to však bude? Spustíte-li příkaz `git diff` normálně, zobrazí se zhruba toto: +Tuto metodu budete využívat především k řešení jednoho z nejpalčivějších problémů, s nímž se lidstvo potýká: verzování dokumentů Word. Je všeobecně známo, že Word je nejpříšernější editor na světě, přesto ho však – bůhví proč – všichni používají. Chcete-li verzovat dokumenty Word, můžete je uložit do repozitáře Git a všechny hned zapsat do revize. K čemu to však bude? Spustíte-li příkaz `git diff` normálně, zobrazí se zhruba toto: $ git diff diff --git a/chapter1.doc b/chapter1.doc @@ -322,18 +326,16 @@ Srovnávat dvě verze přímo nelze, můžete je tak nanejvýš otevřít a ruč *.doc diff=word -Systému Git tím sdělíte, že pro všechny soubory, které odpovídají této masce (.doc), by měl být při zobrazení rozdílů použít filter word. Co je to filtr „word“? To budete muset nastavit. V našem případě nastavíme Git tak, aby ke konverzi dokumentů Word do čitelných textových souborů, způsobilých ke zpracování nástrojem diff, používal program `strings`: +Systému Git tím sdělíte, že pro všechny soubory, které odpovídají této masce (.doc), by měl být při zobrazení rozdílů použít filter „word“. Co je to filtr „word“? To budete muset nastavit. V našem případě nastavíme Git tak, aby ke konverzi dokumentů Word do čitelných textových souborů, způsobilých ke zpracování nástrojem diff, používal program `catdoc`, který byl napsán přímo pro extrakci textu z binární podoby dokumentů MS Word (můžete jej získat z `http://www.wagner.pp.ru/~vitus/software/catdoc/`). Tím wordovské dokumenty převedeme na čitelné textové soubory, na které lze úspěšně aplikovat algoritmus pro zjišťování rozdílů (diff): - $ git config diff.word.textconv strings + $ git config diff.word.textconv catdoc Tento příkaz do vašeho `.git/config` přidá sekci, která vypadá následovně: [diff "word"] - textconv = strings + textconv = catdoc -Okrajová poznámka: Existují různé druhy `.doc` souborů. Některé používají kódování UTF-16 nebo jiné kódové stránky a `strings` v nich nic rozumného nenajde. Záleží na okolnostech. - -Git nyní ví, že až se bude pokoušet vypočítat rozdíl mezi dvěma snímky a jeden ze souborů bude končit na `.doc`, má tyto soubory spustit přes filtr word, který je definován jako program `strings`. Než se Git pokusí porovnat soubory Word nástrojem diff, efektivně vytvoří hezké textové verze souborů. +Git nyní ví, že až se bude pokoušet vypočítat rozdíl mezi dvěma snímky a každý ze souborů končící na `.doc` se má prohnat přes filtr „word“, který je definován jako program `catdoc`. Než se Git pokusí zjistit ve wordovských souborech rozdíly, dojde k jejich převedení na hezké textové verze. Uveďme malý příklad. Kapitolu 1 této knihy jsem vložil do systému Git, do jednoho odstavce jsem přidal kousek textu a dokument jsem uložil. Poté jsem spustil příkaz `git diff`, abych se podíval, co se změnilo: @@ -342,19 +344,18 @@ Uveďme malý příklad. Kapitolu 1 této knihy jsem vložil do systému Git, do 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 mi stroze, ale pravdivě sděluje, že jsem přidal řetězec „Let’s see if this works“. Není to sice dokonalé – na konci je přidáno několik náhodných znaků – ale evidentně to funguje. Pokud se vám podaří najít či vytvořit dobře fungující převaděč dokumentů Word na prostý text, bude toto řešení bezpochyby velmi účinné. Program `strings` je však k dispozici ve většině systémů Mac i Linux, a tak možná nejprve vyzkoušejte tento program s různými binárními formáty. +Git mi stroze, ale pravdivě sděluje, že jsem přidal řetězec „(See Chapter 3)“, což je správné. Funguje to perfektně! ##### OpenDocument Text files ##### -Stejný postup, který jsme použili pro soubory MS Word (`*.doc`), můžeme použít i pro soubory ve formátu OpenDocument Text (`*.odt`), kter vytváří OpenOffice.org. +Stejný postup, který jsme použili pro soubory MS Word (`*.doc`), můžeme použít i pro soubory ve formátu OpenDocument Text (`*.odt`), které vytváří OpenOffice.org. Do souboru `.gitattributes` přidejte následující řádek: @@ -459,7 +460,7 @@ Obrázek 7-2. Filtr smudge spuštěný při checkoutu – git checkout Insert 18333fig0703.png Obrázek 7-3. Filtr clean spuštěný při přípravě souborů k zapsání – git add -Původní zpráva k revizi s touto funkcí uvádí jednoduchý příklad, jak můžete před zapsáním prohnat veškeré vaše céčkové zdrojové texty programem `indent`. Tuto možnost lze aplikovat nastavením atributu `filter` v souboru `.gitattributes` tak, aby přefiltroval soubory `*.c` filtrem pro úpravu odsazování: +Původní zpráva k revizi s touto funkcí uvádí jednoduchý příklad, jak můžete před zapsáním prohnat veškeré vaše céčkové zdrojové texty programem `indent`. V souboru `.gitattributes` můžeme nastavit atribut `filter` tak, aby se soubory `*.c` zpracovaly filtrem `indent`: *.c filter=indent @@ -510,7 +511,7 @@ Systému Git můžete zadat, aby při generování archivu neexportoval určité test/ export-ignore -Až nyní spustíte příkaz git archive k vytvoření tarballu projektu, nebude tento adresář součástí archivu. +Až nyní spustíte příkaz `git archive` k vytvoření tarballu projektu, nebude tento adresář součástí archivu. #### export-subst #### @@ -530,10 +531,14 @@ Spustíte-li příkaz `git archive`, bude po otevření soubor archivu vypadat o Atributy Git lze použít také k nastavení různých strategií slučování pro různé soubory v projektu. Velmi užitečnou možností je například nastavení, aby se Git nepokoušel sloučit konkrétní soubory, pokud u nich dojde ke konfliktu, a raději použil vaši verzi souboru než jinou. -Tuto možnost využijete, pokud se rozdělila nebo specializovala některá z větví vašeho projektu, avšak vy z ní budete chtít začlenit změny zpět a ignorovat přitom určité soubory. Řekněme, že máte soubor s nastavením databáze database.xml, který se ve dvou větvích liší, a vy sem chcete začlenit jinou svoji větev, aniž byste tento soubor změnili. V tom případě můžete nastavit tento atribut: +Tuto možnost využijete, pokud se rozdělila nebo specializovala některá z větví vašeho projektu, avšak vy z ní budete chtít začlenit změny zpět a ignorovat přitom určité soubory. Řekněme, že máte soubor s nastavením databáze nazvaný database.xml, který se ve dvou větvích liší, a vy sem chcete začlenit jinou svoji větev, aniž byste tento soubor změnili. V tom případě můžete nastavit tento atribut: database.xml merge=ours +A potom nadefinujete prázdnou slučovací strategii `ours` příkazem: + + git config --global merge.ours.driver true + Pokud začleníte druhou větev, místo řešení konfliktů u souboru database.xml se zobrazí následující: $ git merge topic @@ -600,7 +605,7 @@ Zásuvný modul `post-receive` se spouští až poté, co je celý proces dokon Skript update je velice podobný skriptu `pre-receive`, avšak s tím rozdílem, že se spouští zvlášť pro každou větev, kterou chce odesílatel aktualizovat. Pokud se uživatel pokouší odeslat revize do více větví, skript `pre-receive` se spustí pouze jednou, zatímco update se spustí jednou pro každou větev, již se odesílatel pokouší aktualizovat. Tento skript nenačítá data ze standardního vstupu, místo nich používá tři jiné parametry: název reference (větve), hodnotu SHA-1, na niž reference ukazovala před odesláním, a hodnotu SHA-1, kterou se uživatel pokouší odeslat. Je-li výstup skriptu update nenulový, je zamítnuta pouze tato reference, ostatní mohou být aktualizovány. -## Příklad standardů kontrolovaných systémem Git ## +## Příklad vynucení chování systémem Git ## V této části použijeme to, co jsme se naučili o vytváření pracovního postupu v systému Git. Systém může kontrolovat formát uživatelovy zprávy k revizi, dovolit pouze aktualizace „rychle vpřed“ a umožňovat změnu obsahu konkrétních podadresářů projektu pouze vybraným uživatelům. V této části vytvoříte skripty pro klienta, které vývojářům pomohou zjistit, zda budou jejich revize odmítnuty, a skripty na server, které si specifikované požadavky přímo vynutí. @@ -612,14 +617,12 @@ Veškerá práce na straně serveru bude uložena do souboru update v adresáři #!/usr/bin/env ruby - $refname = ARGV[0] - $oldrev = ARGV[1] - $newrev = ARGV[2] - $user = ENV['USER'] - - puts "Enforcing Policies... \n(#{$refname}) (#{$oldrev[0,6]}) (#{$newrev[0,6]})" + refname = ARGV[0] + oldrev = ARGV[1] + newrev = ARGV[2] + user = ENV['USER'] -Ano, je to tak, používám globální proměnné. Ale neodsuzujte mne – náš příklad díky tomu bude názornější. + puts "Enforcing Policies... \n(#{refname}) (#{oldrev[0,6]}) (#{newrev[0,6]})" #### Standardizovaná zpráva k revizi #### diff --git a/cs/08-git-and-other-scms/01-chapter8.markdown b/cs/08-git-and-other-scms/01-chapter8.markdown index b12839ae7..303db4d2f 100644 --- a/cs/08-git-and-other-scms/01-chapter8.markdown +++ b/cs/08-git-and-other-scms/01-chapter8.markdown @@ -87,7 +87,7 @@ V tomto okamžiku byste tedy měli mít platný repozitář Git s importovanými tags/release-2.0.2rc1 trunk -Doplňme také, že tento nástroj odlišně přiřazuje jmenný prostor vzdálených referencí. Jestliže klonujete normální repozitář Git, získáte ze vzdáleného serveru všechny větve, lokálně dostupné pod označením `origin/[větev]` – jmenný prostor se přiřazuje na základě vzdáleného serveru. `git svn` však předpokládá, že nebudete mít více vzdálených repozitářů a všechny reference uloží na místa na vzdáleném serveru bez jmenného prostoru. Pokud si přejete zobrazit všechny své reference s úplným názvem, můžete použít nízkoúrovňový příkaz `show-ref`: +Doplňme také, že tento nástroj odlišně přiřazuje jmenný prostor vzdálených referencí. Jestliže klonujete normální repozitář Git, získáte ze vzdáleného serveru všechny větve, lokálně dostupné pod označením `origin/[větev]` – jmenný prostor je dán jménem vzdáleného serveru. Příkaz `git svn` však předpokládá, že nebudete mít více vzdálených repozitářů a všechny odkazy na místa na vzdáleném serveru uloží bez použití jmenného prostoru. Pokud si přejete zobrazit všechny své reference s úplným názvem, můžete použít nízkoúrovňový příkaz `show-ref`: $ git show-ref 1cbd4904d9982f386d87f88fce1c24ad7c0f0471 refs/heads/master @@ -202,7 +202,7 @@ Spustíte-li čas od času příkaz `git svn rebase`, budete mít jistotu, že p ### Problémy s větvemi systému Git ### -Pokud vám vyhovuje způsob práce v systému Git, začnete pravděpodobně vytvářet tematické větve, budete v nich vytvářet svou práci a začleňovat je. Odesíláte-li revize na server Subversion nástrojem git svn, budete možná chtít pokaždé raději přeskládat svou práci na jedinou větev, místo abyste je slučovali. Důvod, proč raději využít možnosti přeskládání, spočívá v tom, že Subversion má lineární historii a neprovádí začleňování stejně jako Git. Nástroj git svn tak při konverzi snímků na revize Subversion sleduje pouze prvního rodiče. +Jakmile pracovní postupy v systému Git zvládnete, začnete pravděpodobně vytvářet tematické větve, budete v nich pracovat a potom je budete začleňovat (merge). Pokud odesíláte revizi na server Subversion nástrojem `git svn`, budete možná místo slučování chtít svou práci pokaždé přeskládat (rebase) na jedinou větev. Důvod, proč raději využít možnosti přeskládání, spočívá v tom, že Subversion uchovává lineární historii a neprovádí začleňování stejně jako Git. Takže `git svn` při konverzi snímků na revize Subversion sleduje pouze prvního rodiče. Předpokládejme, že vaše historie vypadá následovně: vytvořili jste větev `experiment`, zapsali jste dvě revize a začlenili jste je zpět do větve `master`. Výstup příkazu `dcommit` bude nyní vypadat následovně: @@ -231,7 +231,7 @@ Pokud tuto práci naklonuje jiný uživatel, uvidí jen jednu revizi vzniklou sl ### Větve v systému Subversion ### -Princip větvení v systému Subversion se odlišuje od větvení v systému Git. Pokud se mu můžete úplně vyhnout, mohu vám to vřele doporučit. Pokud se mu vyhnout nelze, můžete i tady použít nástroj git svn, pomocí nějž lze vytvářet nové větve a zapisovat do nich revize. +Princip větvení v systému Subversion se odlišuje od větvení v systému Git. Pravděpodobně nejlepší bude, když se mu pokusíte co nejvíc vyhýbat. Nicméně příkaz `git svn` vytváření větví a zapisování revizí do systému Subversion umožňuje. #### Vytvoření nové větve SVN #### @@ -288,7 +288,7 @@ O příkazu `git svn log` byste měli vědět dvě důležité věci. Zaprvé to #### Anotace SVN #### -Tak jako příkaz `git svn log` simuluje offline příkaz `svn log`, ekvivalentem příkazu `svn annotate` je `git svn blame [SOUBOR]`. Jeho výstup vypadá takto: +Tak jako příkaz `git svn log` simuluje příkaz `svn log` (bez nutnosti připojení), ekvivalentem příkazu `svn annotate` je provedení `git svn blame [SOUBOR]`. Jeho výstup vypadá takto: $ git svn blame README.txt 2 temporal Protocol Buffers - Google's data interchange format @@ -324,6 +324,17 @@ Stejné informace, jaké poskytuje příkaz `svn info`, získáte příkazem `gi Stejně jako v případě příkazů `blame` a `log` pracuje i tento příkaz offline a zobrazuje stav v okamžiku, kdy jste naposledy komunikovali se serverem Subversion. +Tip: Pokud vaše skripty pro sestavení projektu chtějí spouštět `svn info`, pak si často můžete vystačit s obálkou příkazu git. +Můžete vyzkoušet + + #!/usr/bin/env bash + + if git rev-parse --git-dir > /dev/null 2>&1 && [[ $1 == "info" ]] ; then + git svn info + else + /usr/local/bin/svn "$@" + fi + #### Ignorování souborů, které ignoruje Subversion #### Jestliže naklonujete repozitář Subversion s nastavenými vlastnostmi `svn:ignore`, pravděpodobně budete chtít nastavit také odpovídající soubory `.gitignore`, abyste omylem nezapsali nežádoucí soubory. Nástroj `git svn` vám k řešení tohoto problému nabízí dva příkazy. Tím prvním je `git svn create-ignore`, jenž automaticky vytvoří odpovídající soubory `.gitignore`, podle nichž se bude řídit už vaše příští revize. @@ -369,7 +380,7 @@ Vytvoříte tím log ve formátu XML. Můžete v něm vyhledávat autory, vytvo Tento soubor můžete dát k dispozici nástroji `git svn`, aby mohl přesněji zmapovat informace o autorech. Nástroji `git svn` můžete také zadat, aby ignoroval metadata, která systém Subversion normálně importuje: zadejte parametr `--no-metadata` k příkazu `clone` nebo `init`. Váš příkaz `import` pak bude mít tuto podobu: - $ 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 Import ze systému Subversion v adresáři `my_project` by měl nyní vypadat o něco lépe. Revize už nebudou mít tuto podobu: @@ -392,7 +403,7 @@ they look like this: Nejenže teď pole Author vypadá podstatně lépe, ale navíc jste se zbavili i záznamu `git-svn-id`. -Po importu bude nutné data trochu vyčistit. Zaprvé je nutné vyčistit nejasné reference, které vytvořil příkaz `git svn`. Nejprve přesunete značky tak, aby se z nich staly skutečné značky, a ne podivné vzdálené větve. V dalším kroku přesunete zbytek větví a uděláte z nich větve lokální. +Po importu bude nutné data trochu vyčistit. Zaprvé je nutné vyčistit podivné reference, které vytvořil příkaz `git svn`. Nejprve přesuňte značky tak, aby se z nich staly skutečné značky, a ne podivné vzdálené větve. V dalším kroku přesunete zbytek větví a uděláte z nich větve lokální. Abyste značky upravili na korektní gitové značky, spusťte @@ -499,7 +510,7 @@ Jako rychlou ukázku napíšeme jednoduchý importér. Řekněme, že pracujete Chcete-li importovat adresář Git, budeme se muset podívat na to, jak Git ukládá svá data. Jak si možná vzpomínáte, říkali jsme, že Git je v podstatě seznam odkazů na objekty revizí, které ukazují na určitý snímek obsahu. Jediné, co tedy musíte udělat, je sdělit příkazu `fast-import`, co je obsahem snímků, jaká data revizí na ně ukazují a pořadí, v němž budou převzaty. Vaše strategie tedy bude spočívat v tom, že postupně projdete jednotlivé snímky a vytvoříte revize s obsahem každého adresáře, přičemž každá revize bude odkazovat na revizi předchozí. -Stejně jako v části „Příklad systémem Git kontrolovaných standardů“ v kapitole 7 použijeme i tentokrát Ruby, s nímž většinou pracuji a který je srozumitelný. Tento příklad můžete ale beze všeho napsat v čemkoli, co vám vyhovuje. Jedinou podmínkou je, aby byly potřebné informace zapsány do výstupu stdout. +Stejně jako v podkapitole „Příklad vynucení chování systémem Git“ v kapitole 7 použijeme i tentokrát Ruby, s nímž většinou pracuji a který je srozumitelný. Tento příklad můžete ale beze všeho napsat v čemkoli, co vám vyhovuje. Jedinou podmínkou je, aby byly potřebné informace zapsány na standardní výstup (stdout). A to v případě používání Windows znamená, že budete muset věnovat zvláštní pozornost tomu, abyste na koncích řádků nevkládali znaky CR (carriage return). Příkaz `git fast-import` je v tomto směru velmi vybíravý a chce jen znaky LF (line feed) a nikoliv kombinaci CRLF, kterou používají Windows. Na začátku přejdete do cílového adresáře a identifikujete všechny podadresáře, z nichž bude každý představovat jeden snímek, který chcete importovat jako revizi. Přejdete do každého podadresáře a zadáte příkazy potřebné k jeho exportu. Základní smyčka bude mít tuto podobu: @@ -601,7 +612,7 @@ Poslední věcí, kterou musíte udělat, je vrátit aktuální označovač, aby return mark -Poznámka: Pokud používáte Windows, budete muset provést jeden krok navíc. Jak už jsem se zmínil, Windows používají nahrazují znak konce řádku posloupností CRLF, zatímco git fast-import očekává pouze LF. Abychom tento problém obešli a aby si git fast-import nestěžoval, musíte ruby říct, aby místo LF používal CRLF: +Poznámka: Pokud používáte Windows, budete muset provést jeden krok navíc. Jak už jsem se zmínil, Windows nahrazují znak konce řádku posloupností CRLF, zatímco `git fast-import` očekává pouze LF. Abychom tento problém obešli a přitom učinili příkaz `git fast-import` šťastným, musíte ruby říct, aby místo LF používal CRLF: $stdout.binmode diff --git a/cs/09-git-internals/01-chapter9.markdown b/cs/09-git-internals/01-chapter9.markdown index 81708d2b4..33ac85619 100644 --- a/cs/09-git-internals/01-chapter9.markdown +++ b/cs/09-git-internals/01-chapter9.markdown @@ -27,7 +27,7 @@ Spustíte-li v novém nebo existujícím adresáři příkaz `git init`, Git vyt objects/ refs/ -Možná ve svém adresáři najdete i další soubory. Toto je však příkazem `git init` čerstvě vytvořený repozitář s výchozím obsahem. Adresář `branches` se už v novějších verzích systému Git nepoužívá a soubor `description` používá pouze program GitWeb, o tyto dvě položky se tedy nemusíte starat. Soubor `config` obsahuje jednotlivá nastavení pro konfiguraci vašeho projektu a v adresáři `info` je uchováván globální soubor .gitignore s maskami ignorovaných souborů a adresářů, které si nepřejete sledovat. Adresář `hooks` obsahuje skripty zásuvných modulů na straně klienta nebo serveru, které jsme podrobně popisovali v kapitole 6. +Možná ve svém adresáři najdete i další soubory. Toto je však příkazem `git init` čerstvě vytvořený repozitář s výchozím obsahem. Adresář `branches` se už v novějších verzích systému Git nepoužívá a soubor `description` používá pouze program GitWeb, takže o tyto dvě položky se nemusíte starat. Soubor `config` obsahuje konfigurační nastavení vašeho projektu a v adresáři `info` je uložen globální soubor `exclude` s maskami ignorovaných souborů a adresářů, které chcete explicitně ignorovat prostřednictvím souboru `.gitignore`. Adresář `hooks` obsahuje skripty zásuvných modulů na straně klienta nebo serveru, které jsme podrobně popisovali v kapitole 7. Zbývají čtyři důležité položky: soubory `HEAD` a `index` a adresáře `objects` a `refs`. To jsou ústřední součásti adresáře Git. V adresáři `objects` je uložen celý obsah vaší databáze, v adresáři `refs` jsou uloženy ukazatele na objekty revizí v datech (větve). Soubor `HEAD` ukazuje na větev, na níž se právě nacházíte, a soubor `index` je pro systém Git úložištěm informací o oblasti připravených změn. Na každou z těchto částí se teď podíváme podrobněji, abyste pochopili, jak Git pracuje. @@ -433,7 +433,7 @@ Vraťme se zpět do databáze objektů vašeho testovacího repozitáře Git. V Git komprimuje obsah těchto souborů metodou zlib a uložená data tak nejsou příliš velká. Všechny tyto soubory zabírají dohromady pouhých 925 bytů. Do repozitáře tak nyní přidáme větší objem dat, na němž si budeme moci ukázat jednu zajímavou funkci systému Git. Z knihovny Grit, s níž jsme pracovali před časem, přidejte soubor „repo.rb“. Je to soubor se zdrojovým kódem o velikosti asi 12 kB: - $ curl https://raw.github.com/mojombo/grit/master/lib/grit/repo.rb > repo.rb + $ curl -L 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 diff --git a/de/01-introduction/01-chapter1.markdown b/de/01-introduction/01-chapter1.markdown index a7d675858..28c1e64e3 100644 --- a/de/01-introduction/01-chapter1.markdown +++ b/de/01-introduction/01-chapter1.markdown @@ -221,7 +221,7 @@ Wenn eine bestimmte Version einer Datei im Git Verzeichnis liegt, gilt sie als ## Git installieren ## - + Lass uns damit anfangen, Git tatsächlich zu verwenden. Der erste Schritt besteht natürlich darin, Git zu installieren und das kann, wie üblich, auf unterschiedliche Weisen geschehen. Die beiden wichtigsten bestehen darin, entweder den Quellcode herunterzuladen und selbst zu kompilieren oder ein fertiges Paket für Dein Betriebssystem zu installieren. @@ -281,11 +281,11 @@ Auf einem Debian-basierten System wie Ubuntu steht Dir apt-get zur Verfügung: ### Installation unter Mac OS X ### - + -Auf einem Mac kann man Git auf zwei Arten installieren. Der einfachste ist, das grafische Git Installationsprogramm zu verwenden, den man von der Google Code Webseite herunterladen kann (siehe Bild 1-7) +Auf einem Mac kann man Git auf zwei Arten installieren. Der einfachste ist, das grafische Git Installationsprogramm zu verwenden, den man von der SourceForge Webseite herunterladen kann (siehe Bild 1-7) - http://code.google.com/p/git-osx-installer + http://sourceforge.net/projects/git-osx-installer/ @@ -302,6 +302,16 @@ Die andere Möglichkeit ist, Git via MacPorts (http://www.macports.org) zu insta Du brauchst die optionalen Features natürlich nicht mit zu installieren, aber es macht Sinn `+svn` zu verwenden, falls Du jemals Git mit einem Subversion Repository verwenden willst. + + +Alternativ kann man Git auch über Homebrew (`http://brew.sh/`) installieren. Hast Du Homebrew bereits, kannst Du Git einfach über den folgenden Befehl installieren: + + $ brew install git + ### Installation unter Windows ### @@ -340,7 +350,7 @@ Git umfasst das Werkzeug `git config`, das Dir erlaubt, Konfigurationswerte zu v -Auf Windows Systemen sucht Git nach der `.gitconfig` Datei im `$HOME` Verzeichnis (für die meisten Leute ist das das Verzeichnis `C:\Dokumente und Einstellungen\$USER`). Git sucht außerdem auch nach dem Verzeichnis /etc/gitconfig, aber es sucht relativ demjenigen Verzeichnis, in dem Du Git mit Hilfe des Installers installiert hast. +Auf Windows Systemen sucht Git nach der `.gitconfig` Datei im `$HOME` Verzeichnis (für die meisten Leute ist das das Verzeichnis `C:\Dokumente und Einstellungen\$USER`). Es schaut auch immer nach `/etc/gitconfig`, auch wenn dieses relativ zu dem MSys Wurzelverzeichnis ist, welches das ist, wohin Du Git bei der Installation in Windows installiert hast. ### Deine Identität ### diff --git a/de/02-git-basics/01-chapter2.markdown b/de/02-git-basics/01-chapter2.markdown index 525e6382b..bb13f3dbd 100644 --- a/de/02-git-basics/01-chapter2.markdown +++ b/de/02-git-basics/01-chapter2.markdown @@ -115,7 +115,7 @@ Sagen wir Du fügst eine neue `README` Datei zu Deinem Projekt hinzu. Wenn die D -Alle Dateien, die in der Sektion „Untracked files“ aufgelistet werden, sind Dateien, die bisher nocht nicht versioniert sind. Dort wird jetzt auch die Datei `README` angezeigt. Mit anderen Worten, die Datei `README` wird in diesem Bereich gelistet, weil sie im letzen Snapshot (Commit) von Git nicht enthalten ist. Git nimmt eine solche Datei nicht automatisch in die Versionskontrolle auf, sondern man muss Git dazu ausdrücklich auffordern. Ansonsten würden generierte Binärdateien oder andere Dateien, die Du nicht in Deinem Repository haben willst, automatisch hinzugefügt werden. Das möchte man in den meisten Fällen vermeiden. Jetzt wollen wir aber Änderungen an der Datei `README` verfolgen und fügen sie deshalb zur Versionskontrolle hinzu. +Alle Dateien, die in der Sektion „Untracked files“ aufgelistet werden, sind Dateien, die bisher noch nicht versioniert sind. Dort wird jetzt auch die Datei `README` angezeigt. Mit anderen Worten, die Datei `README` wird in diesem Bereich gelistet, weil sie im letzen Snapshot (Commit) von Git nicht enthalten ist. Git nimmt eine solche Datei nicht automatisch in die Versionskontrolle auf, sondern man muss Git dazu ausdrücklich auffordern. Ansonsten würden generierte Binärdateien oder andere Dateien, die Du nicht in Deinem Repository haben willst, automatisch hinzugefügt werden. Das möchte man in den meisten Fällen vermeiden. Jetzt wollen wir aber Änderungen an der Datei `README` verfolgen und fügen sie deshalb zur Versionskontrolle hinzu. ### Neue Dateien zur Versionskontrolle hinzufügen ### @@ -1129,7 +1129,7 @@ Dieser Befehl lädt alle Daten aus dem Remote Repository herunter, die noch nich -Wenn Du ein Repository geklont hast, legt der Befehl automatisch einen Verweis auf dieses Repository unter dem Namen `origin` an. D.h. `git fetch origin` lädt alle Neuigkeiten herunter, die in dem Remote Repository von anderen hinzugefügt wurden, seit Du es geklont hast (oder zuletzt `git fetch` ausgeführt hast). Es ist wichtig, zu verstehen, dass der `git fetch` Befehl Daten lediglich in Dein lokales Repository lädt. Er führt sich mit Deinen eigenen Commits in keiner Weise zusammen (mergt) oder modifiziert, woran Du gerade arbeitest. D.h. Du musst die heruntergeladenen Änderungen anschließend selbst manuell mit Deinen eigenen zusammeführen, wenn Du das willst. +Wenn Du ein Repository geklont hast, legt der Befehl automatisch einen Verweis auf dieses Repository unter dem Namen `origin` an. D.h. `git fetch origin` lädt alle Neuigkeiten herunter, die in dem Remote Repository von anderen hinzugefügt wurden, seit Du es geklont hast (oder zuletzt `git fetch` ausgeführt hast). Es ist wichtig, zu verstehen, dass der `git fetch` Befehl Daten lediglich in Dein lokales Repository lädt. Er führt sich mit Deinen eigenen Commits in keiner Weise zusammen (mergt) oder modifiziert, woran Du gerade arbeitest. D.h. Du musst die heruntergeladenen Änderungen anschließend selbst manuell mit Deinen eigenen zusammenführen, wenn Du das willst. diff --git a/de/03-git-branching/01-chapter3.markdown b/de/03-git-branching/01-chapter3.markdown index 81fea42ec..6ff4380eb 100644 --- a/de/03-git-branching/01-chapter3.markdown +++ b/de/03-git-branching/01-chapter3.markdown @@ -3,18 +3,18 @@ -Nahezu jedes VCS unterstützt eine Form von Branching. Branching bedeutet, dass Du von der Hauptentwicklungslinie abzweigst und unabhängig von dem Hauptzweig weiterarbeitest. Bei vielen VCS ist das ein umständlicher und komplizierter Prozess. Nicht selten ist es notwendig, dass eine Kopie des kompletten Arbeitsverzeichnisses erstellt werden muss, was bei großen Projekten eine ganze Weile dauern kann. +Nahezu jedes VCS unterstützt eine Form von Branching. Branching bedeutet, dass Du von der Hauptentwicklungslinie abzweigst und unabhängig vom Hauptzweig weiterarbeitest. Bei vielen VCS ist das ein ziemlch aufwendiger Prozess, welcher häufig erfordert, eine Kopie des kompletten Arbeitsverzeichnisses zu erstellen, was bei großen Projekten eine ganze Weile dauern kann. -Manche Leute bezeichnen Gits Branching-Modell als dessen „Killer-Feature“, was Git zweifellos von dem Rest der VCS-Community abhebt. Aber was macht es so besonders? Die Art und Weise, wie Git Branches behandelt, ist unglaublich leichtfüßig. Dies führt dazu, dass nahezu jede Branch-Operation verzögerungsfrei ausgeführt wird. Auch das Hin- und Herschalten zwischen einzelnen Entwicklungszweigen läuft genauso schnell ab. Im Gegensatz zu anderen VCS ermutigt Git zu einer Arbeitsweise mit häufigem Branching und Merging – oft mehrmals am Tag. Die Branching-Funktion zu verstehen und zu meistern gibt Dir ein mächtiges und einmaliges Werkzeug an die Hand und kann Deine Art zu entwickeln buchstäblich verändern. +Manche Leute bezeichnen Gits Branching-Modell als dessen „Killer-Feature“, was Git zweifellos von dem Rest der VCS-Community abhebt. Was ist das Besondere daran? Die Art und Weise, wie Git Branches behandelt, ist unglaublich leichtgewichtig, wodurch Branch-Operationen nahezu verzögerungsfrei ausgeführt werden und auch das Hin- und Herschalten zwischen einzelnen Entwicklungszweigen im allgemeinen genauso schnell abläuft. Im Gegensatz zu anderen VCS ermutigt Git zu einer Arbeitsweise mit häufigem Branching und Merging – oft mehrmals am Tag. Wenn Du diese Funktion vertstehst und beherrschst, besitzt Du ein mächtiges und einmaliges Werkzeug, welches Deine Art zu entwickeln buchstäblich verändern. ## Was ist ein Branch? ## -Um wirklich zu verstehen wie Git Branching durchführt, müssen wir einen Schritt zurück gehen und untersuchen wie Git die Daten speichert. Wie Du Dich vielleicht noch an Kapitel 1 erinnerst, speichert Git seine Daten nicht als Serie von Änderungen oder Unterschieden, sondern als Serie von Schnappschüssen. +Um wirklich zu verstehen, wie Git Branching durchführt, müssen wir einen Schritt zurück gehen und untersuchen, wie Git die Daten speichert. Wie Du Dich vielleicht noch an Kapitel 1 erinnerst, speichert Git seine Daten nicht als Serie von Änderungen oder Unterschieden, sondern als Serie von Schnappschüssen. @@ -29,11 +29,11 @@ Um das zu verdeutlichen, lass uns annehmen, Du hast ein Verzeichnis mit drei Dat -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. +Wenn Du einen Commit mit der Anweisung `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. -Dein Git-Repository enthält nun fünf Objekte: einen Blob für den Inhalt jeder der drei Dateien, einen Baum, der den Inhalt des Verzeichnisses auflistet und spezifiziert welcher Dateiname zu welchem Blob gehört, sowie einen Zeiger, der auf die Wurzel des Projektbaumes und die Metadaten des Commits verweist. Prinzipiell sehen Deine Daten im Git Repository wie in Abbildung 3-1 aus. +Dein Git-Repository enthält nun fünf Objekte: einen Blob für den Inhalt von jeder der drei Dateien, einen Baum, der den Inhalt des Verzeichnisses auflistet und spezifiziert, welcher Dateiname zu welchem Blob gehört, sowie einen Zeiger, der auf die Wurzel des Projektbaumes und die Metadaten des Commits verweist. Prinzipiell sehen Deine Daten im Git Repository wie in Abbildung 3-1 aus. @@ -60,7 +60,7 @@ Abbildung 3-3. Branch, der auf einen Commit in der Historie zeigt. -Was passiert, wenn Du einen neuen Branch erstellst? Nun, zunächst wird ein neuer Zeiger erstellt. Sagen wir, Du erstellst einen neuen Branch mit dem Namen `testing`. Das machst Du mit dem `git branch` Befehl: +Was passiert, wenn Du einen neuen Branch erstellst? Nun, zunächst wird ein neuer Zeiger erstellt. Sagen wir, Du erstellst einen neuen Branch mit dem Namen `testing`. Das machst Du mit der Anweisung `git branch`: $ git branch testing @@ -75,7 +75,7 @@ Abbildung 3-4. Mehrere Branches zeigen in den Commit-Verlauf -Woher weiß Git, welchen Branch Du momentan verwendest? Dafür gibt es einen speziellen Zeiger mit dem Namen HEAD. Berücksichtige, dass dieses Konzept sich grundsätzlich von anderen HEAD-Konzepten anderer VCS, wie Subversion oder CVS, unterscheidet. Bei Git handelt es sich bei HEAD um einen Zeiger, der auf Deinen aktuellen lokalen Branch zeigt. In dem Fall bist Du aber immer noch auf dem `master`-Branch. Das `git branch` Kommando hat nur einen neuen Branch erstellt, aber nicht zu diesem gewechselt (siehe Abbildung 3-5). +Woher weiß Git, welchen Branch Du momentan verwendest? Dafür gibt es einen speziellen Zeiger mit dem Namen HEAD. Berücksichtige, dass dieses Konzept sich grundsätzlich von anderen HEAD-Konzepten anderer VCS, wie Subversion oder CVS, unterscheidet. Bei Git handelt es sich bei HEAD um einen Zeiger, der auf Deinen aktuellen lokalen Branch zeigt. In dem Fall bist Du aber immer noch auf dem `master`-Branch. Die Anweisung `git branch` hat nur einen neuen Branch erstellt, aber nicht zu diesem gewechselt (siehe Abbildung 3-5). @@ -84,7 +84,7 @@ Abbildung 3-5. Der HEAD-Zeiger verweist auf Deinen aktuellen Branch. -Um zu einem anderen Branch zu wechseln, benutze das Kommando `git checkout`. Lass uns nun zu unserem neuen Branch `testing` wechseln: +Um zu einem anderen Branch zu wechseln, benutze die Anweisung `git checkout`. Lass uns nun zu unserem neuen Branch `testing` wechseln: $ git checkout testing @@ -115,7 +115,7 @@ Abbildung 3-7. Der HEAD-Zeiger schreitet mit jedem weiteren Commit voran. -Das ist interessant, denn Dein Branch `testing` hat sich jetzt voranbewegt und Dein `master`-Branch zeigt immer noch auf seinen letzten Commit. Den Commit, den Du zuletzt bearbeitet hattest, bevor Du mit `git checkout` den aktuellen Zweig gewechselt hast. Lass uns zurück zu dem `master`-Branch wechseln: +Das ist interessant, denn Dein Branch `testing` hat sich jetzt voranbewegt, während Dein `master`-Branch immer noch auf den Commit zeigt, welchen Du bearbeitet hast, bevor Du mit `git checkout` den aktuellen Zweig gewechselt hast. Lass uns zurück zu dem `master`-Branch wechseln: $ git checkout master @@ -130,7 +130,7 @@ Abbildung 3-8. HEAD zeigt nach einem Checkout auf einen anderen Branch. -Das Kommando hat zwei Dinge veranlasst. Zum einen bewegt es den HEAD-Zeiger zurück zum `master`-Branch, zum anderen setzt es alle Dateien im Arbeitsverzeichnis auf den Bearbeitungsstand des letzte Commits in diesem Zweig zurück. Das bedeutet aber auch, dass nun alle Änderungen am Projekt vollkommen unabhängig von älteren Projektversionen erfolgen. Kurz gesagt, werden alle Änderungen aus dem `testing`-Zweig vorübergehend rückgängig gemacht und Du hast die Möglichkeit einen vollkommen neuen Weg in der Entwicklung einzuschlagen. +Diese Anweisung hat zwei Dinge veranlasst. Zum einen bewegt es den HEAD-Zeiger zurück zum `master`-Branch, zum anderen setzt es alle Dateien im Arbeitsverzeichnis auf den Bearbeitungsstand des letzten Commits in diesem Zweig zurück. Das bedeutet aber auch, dass nun alle Änderungen am Projekt vollkommen unabhängig von älteren Projektversionen erfolgen. Kurz gesagt, werden alle Änderungen aus dem `testing`-Zweig vorübergehend rückgängig gemacht und Du hast die Möglichkeit, einen vollkommen neuen Weg in der Entwicklung einzuschlagen. @@ -141,7 +141,7 @@ Lass uns ein paar Änderungen machen und mit einem Commit festhalten: -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. +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`-Anweisungen vollbracht. @@ -150,7 +150,7 @@ Abbildung 3-9. Die Historie läuft auseinander. -Branches können in Git spielend erstellt und entfernt werden, da sie nur kleine Dateien sind, die eine 40 Zeichen lange SHA-1 Prüfsumme der Commits enthalten, auf die sie verweisen. Einen neuen Zweig zu erstellen erzeugt ebenso viel Aufwand wie das Schreiben einer 41 Byte großen Datei (40 Zeichen und einen Zeilenumbruch). +Branches können in Git spielend erstellt und entfernt werden, da sie nur kleine Dateien sind, die eine 40 Zeichen lange SHA-1 Prüfsumme der Commits enthalten, auf die sie verweisen. Einen neuen Zweig zu erstellen, erzeugt ebenso viel Aufwand wie das Schreiben einer 41 Byte großen Datei (40 Zeichen und einen Zeilenumbruch). @@ -172,20 +172,20 @@ Lass uns das Ganze an einem Beispiel durchgehen, dessen Workflow zum Thema Branc 1. Arbeite an einer Webseite. -2. Erstell einen Branch für irgendeine neue Geschichte, an der Du arbeitest. +2. Erstelle einen Branch für irgendeine neue Geschichte, an der Du arbeitest. 3. Arbeite in dem Branch. 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. +1. Schalte zurück zu Deinem „Produktiv“-Zweig. +2. Erstelle einen Branch für den Hotfix. 3. Nach dem Testen führst Du den Hotfix-Branch mit dem „Produktiv“-Branch zusammen. 4. Schalte wieder auf Deine alte Arbeit zurück und werkel weiter. @@ -203,7 +203,7 @@ Abbildung 3-10. Eine kurze, einfache Commit-Historie -Du hast Dich dafür entschieden an dem Issue #53, des Issue-Trackers XY, zu arbeiten. Um eines klarzustellen, Git ist an kein Issue-Tracking-System gebunden. Da der Issue #53 allerdings ein Schwerpunktthema betrifft, wirst Du einen neuen Branch erstellen um daran zu arbeiten. Um in einem Arbeitsschritt einen neuen Branch zu erstellen und zu aktivieren kannst Du das Kommando `git checkout` mit der Option `-b` verwenden: +Du hast Dich dafür entschieden, am Issue #53 des Issue-Trackers XY zu arbeiten. Um eines klarzustellen, Git ist an kein Issue-Tracking-System gebunden. Da der Issue #53 allerdings ein Schwerpunktthema betrifft, wirst Du einen neuen Branch erstellen, um daran zu arbeiten. Um in einem Arbeitsschritt einen neuen Branch zu erstellen und zu aktivieren, kannst Du die Anweisung `git checkout` mit der Option `-b` verwenden: $ git checkout -b iss53 Switched to a new branch 'iss53' @@ -238,22 +238,22 @@ Abbildung 3-12. Der `iss53`-Branch hat mit Deiner Arbeit Schritt gehalten. -Nun bekommst Du einen Anruf, in dem Dir mitgeteilt wird, dass es ein Problem mit der Internet-Seite gibt, das Du umgehend beheben sollst. Mit Git musst Du Deine Fehlerkorrektur nicht zusammen mit den `iss53`-Änderungen einbringen. Und Du musst keine Zeit damit verschwenden Deine bisherigen Änderungen rückgängig zu machen, bevor Du mit der Fehlerbehebung an der Produktionsumgebung beginnen kannst. Alles was Du tun musst, ist zu Deinem MASTER-Branch wechseln. +Nun bekommst Du einen Anruf, in dem Dir mitgeteilt wird, dass es ein Problem mit der Internet-Seite gibt, das Du umgehend beheben sollst. Bei Git musst Du Deine Fehlerkorrektur nicht zusammen mit den `iss53`-Änderungen einbringen. Und Du musst keine Zeit damit verschwenden, Deine bisherigen Änderungen rückgängig zu machen, bevor Du mit der Fehlerbehebung an der Produktionsumgebung beginnen kannst. Alles, was Du tun musst, ist, zu Deinem master-Branch wechseln. -Beachte jedoch, dass Dich Git den Branch nur wechseln lässt, wenn bisherige Änderungen in Deinem Arbeitsverzeichnis oder Deiner Staging-Area nicht in Konflikt mit dem Zweig stehen, zu dem Du nun wechseln möchtest. Am besten es liegt ein sauberer Status vor wenn man den Branch wechselt. Wir werden uns später mit Wegen befassen, dieses Verhalten zu umgehen (namentlich „Stashing“ und „Commit Ammending“). Vorerst aber hast Du Deine Änderungen bereits comitted, sodass Du zu Deinem MASTER-Branch zurückwechseln kannst. +Beachte jedoch, dass Dich Git den Branch nur wechseln lässt, wenn bisherige Änderungen in Deinem Arbeitsverzeichnis oder Deiner Staging-Area nicht in Konflikt mit dem Zweig stehen, zu dem Du nun wechseln möchtest. Am besten ist es, wenn ein sauberer Arbeitsstand vorliegt, wenn man den Branch wechselt. Wir werden uns später mit Wegen befassen, dieses Verhalten zu umgehen (namentlich „Stashing“ und „Commit Ammending“). Vorerst aber hast Du Deine Änderungen bereits comitted, sodass Du zu Deinem master-Branch zurückwechseln kannst. $ git checkout master Switched to branch 'master' -Zu diesem Zeitpunkt befindet sich das Arbeitsverzeichnis des Projektes in exakt dem gleichen Zustand, in dem es sich befand, als Du mit der Arbeit an Issue #53 begonnen hast und Du kannst Dich direkt auf Deinen Hotfix konzentrieren. Dies ist ein wichtiger Moment um sich vor Augen zu halten, dass Git Dein Arbeitsverzeichnis auf den Zustand des Commits, auf den dieser Branch zeigt, zurücksetzt. Es erstellt, entfernt und verändert Dateien automatisch, um sicherzustellen, dass Deine Arbeitskopie haargenau so aussieht wie der Zweig nach Deinem letzten Commit. +Zu diesem Zeitpunkt befindet sich das Arbeitsverzeichnis des Projektes in exakt dem gleichen Zustand, in dem es sich befand, als Du mit der Arbeit an Issue #53 begonnen hast und Du kannst Dich direkt auf Deinen Hotfix konzentrieren. Dies ist ein wichtiger Moment, um sich vor Augen zu halten, dass Git Dein Arbeitsverzeichnis auf den Zustand des Commits, auf den dieser Branch zeigt, zurücksetzt. Es erstellt, entfernt und verändert Dateien automatisch, um sicherzustellen, dass Deine Arbeitskopie haargenau so aussieht wie der Zweig nach Deinem letzten Commit. -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): +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 Switched to a new branch 'hotfix' @@ -265,11 +265,11 @@ Nun hast Du einen Hotfix zu erstellen. Lass uns dazu einen Hotfix-Branch erstell Insert 18333fig0313.png -Abbildung 3-13. Der Hotfix-Branch basiert auf dem zurückliegenden Master-Branch. +Abbildung 3-13. Der hotfix-Branch basiert auf dem zurückliegenden master-Branch. -Mach Deine Tests, stell sicher das sich der Hotfix verhält wie erwartet und führe ihn mit dem Master-Branch zusammen, um ihn in die Produktionsumgebung zu integrieren. Das machst Du mit dem `git merge`-Kommando: +Du kannst Deine Tests durchführen und sicherstellen, dass der Hotfix seinen Zweck erfüllt und ihn dann mit dem master-Branch zusammenführen, um ihn in die Produktionsumgebung zu integrieren. Das machst Du mit der Anweisung `git merge`: $ git checkout master $ git merge hotfix @@ -280,7 +280,7 @@ Mach Deine Tests, stell sicher das sich der Hotfix verhält wie erwartet und fü -Du wirst die Mitteilung „Fast Forward“ während des Zusammenführens bemerken. Da der neue Commit direkt von dem ursprünglichen Commit, auf den sich der nun eingebrachte Zweig bezieht, abstammt, bewegt Git einfach den Zeiger weiter. Mit anderen Worten kann Git den neuen Commit, durch verfolgen der Commitabfolge, direkt erreichen, dann bewegt es ausschließlich den Branch-Zeiger. Zu einer tatsächlichen Kombination der Commits besteht ja kein Anlass. Dieses Vorgehen wird „Fast Forward“ genannt. +Du wirst die Mitteilung „Fast Forward“ während des Zusammenführens bemerken. Da der neue Commit direkt von dem ursprünglichen Commit, auf den sich der nun eingebrachte Zweig bezieht, abstammt, bewegt Git einfach den Zeiger weiter. Mit anderen Worten kann Git den neuen Commit durch Verfolgen der Commitabfolge direkt erreichen, dann bewegt es ausschließlich den Branch-Zeiger. Zu einer tatsächlichen Kombination der Commits besteht ja kein Anlass. Dieses Vorgehen wird „Fast Forward“ genannt. @@ -289,11 +289,11 @@ Deine Modifikationen befinden sich nun als Schnappschuss in dem Commit, auf den Insert 18333fig0314.png -Abbildung 3-14. Der Master-Branch zeigt nach der Zusammenführung auf den gleichen Commit wie der Hotfix-Branch. +Abbildung 3-14. Der master-Branch zeigt nach der Zusammenführung auf den gleichen Commit wie der hotfix-Branch. -Nachdem Dein superwichtiger Hotfix veröffentlicht wurde, kannst Du Dich wieder Deiner ursprünglichen Arbeit zuwenden. Vorher wird sich allerdings des nun nutzlosen Hotfix-Zweiges entledigt, schließlich zeigt der Master-Branch ebenfalls auf die aktuelle Version. Du kannst ihn mit der `-d`-Option von `git branch` entfernen: +Nachdem Dein superwichtiger Hotfix veröffentlicht wurde, kannst Du Dich wieder Deiner ursprünglichen Arbeit zuwenden. Vorher wird sich allerdings des nun nutzlosen hotfix-Zweiges entledigt, schließlich zeigt der master-Branch ebenfalls auf die aktuelle Version. Du kannst ihn mit der `-d`-Option von `git branch` entfernen: $ git branch -d hotfix Deleted branch hotfix (was 3a0874c). @@ -316,7 +316,7 @@ Abbildung 3-15. Dein `iss53`-Branch kann sich unabhängig weiterentwickeln. -An dieser Stelle ist anzumerken, dass die Änderungen an dem `hotfix`-Branch nicht in Deinen `iss53`-Zweig eingeflossen sind. Falls nötig kannst Du den `master`-Branch allerdings mit dem Kommando `git merge master` mit Deinem Zweig kombinieren. Oder Du wartest, bis Du den `iss53`-Branch später in den Master-Zweig zurückführst. +An dieser Stelle ist anzumerken, dass die Änderungen an dem `hotfix`-Branch nicht in Deinen `iss53`-Branch eingeflossen sind. Falls nötig, kannst Du den `master`-Branch allerdings mit der Anweisung `git merge master` mit Deinem Branch kombinieren. Oder Du wartest, bis Du den `iss53`-Branch später in den `master`-Branch zurückführst. @@ -324,7 +324,7 @@ An dieser Stelle ist anzumerken, dass die Änderungen an dem `hotfix`-Branch nic -Angenommen Du entscheidest dich, dass Deine Arbeit an issue #53 getan ist und Du diese mit der `master` Branch zusammenführen möchtest. Das passiert, indem Du ein `merge` in die `iss53` Branch machst, ähnlich dem `merge` mit der `hotfix` Branch von vorhin. Alles was Du machen musst, ist ein `checkout` der Branch, in die Du das `merge` machen willst und das Ausführen des Kommandos `git merge`: +Angenommen, Du hast entschieden, dass Deine Arbeiten an issue #53 abgeschlossen sind und das Ganze soweit ist, dass es mit dem `master` Branch zusammengeführt werden kann. Um das zu erreichen, wirst Du Deinen `iss53` Branch in den `master` Branch einfließen lassen, genauso wie Du es mit dem `hotfix` Branch zuvor getan hast. Du musst nur mit der Anweisung `checkout` zum dem Branch zu wechseln, in welchen Du etwas einfließen lassen möchtest und dann die Anweisung `git merge` ausführen: $ git checkout master $ git merge iss53 @@ -335,20 +335,20 @@ Angenommen Du entscheidest dich, dass Deine Arbeit an issue #53 getan ist und Du -Das sieht ein bisschen anders aus als das `hotfix merge` von vorhin. Hier läuft Deine Entwicklungshistorie auseinander. Ein `commit` auf Deine Arbeits-Branch ist kein direkter Nachfolger der Branch in die Du das `merge` gemacht hast, Git hat da einiges zu tun, es macht einen 3-Wege `merge`: es geht von den beiden `snapshots` der Branches und dem allgemeinen Nachfolger der beiden aus. Abbildung 3-16 zeigt die drei `snapshots`, die Git in diesem Fall für das `merge` verwendet. +Das sieht ein bisschen anders aus als das `hotfix merge` von vorhin. Hier haben sich die Entwicklungsstränge schon zu einem früheren Zeitpunkt geteilt. Da der `commit` auf dem Branch, in dem Du Dich befindest, kein direkter Nachfolger von dem Branch ist, in den Du das `merge` machst, hat Git einiges zu tun. Dazu macht Git einen 3-Wege `merge`, wobei es die beiden Schnappschüsse verwendet, welche auf die Enden der Branches zeigen, und den gemeinsamen Vorfahren dieser beiden. Abbildung 3-16 zeigt die drei `snapshots`, die Git in diesem Fall für das `merge` verwendet. Insert 18333fig0316.png -Abbildung 3-16. Git ermittelt automatisch die beste Nachfolgebasis für die Branchzusammenführung. +Abbildung 3-16. Git erkennt automatisch den am besten geeigneten gemeinsamen Vorgänger für die Branchzusammenführung. -Anstatt einfach den 'pointer' weiterzubewegen, erstellt Git einen neuen `snapshot`, der aus dem 3-Wege 'merge' resultiert und erzeugt einen neuen 'commit', der darauf verweist (siehe Abbildung 3-17). Dies wird auch als 'merge commit' bezeichnet und ist ein Spezialfall, weil es mehr als nur ein Elternteil hat. +Anstatt einfach den Zeiger vorwärts zu bewegen, erstellt Git einen neuen `snapshot`, der aus dem 3-Wege 'merge' resultiert und erzeugt automatisch einen neuen `commit`, der darauf verweist (siehe Abbildung 3-17). Dies wird auch als `merge commit` bezeichnet und ist ein Spezialfall, weil es mehr als nur einen Elternteil hat. -Es ist wichtig herauszustellen, dass Git den besten Nachfolger für die 'merge' Basis ermittelt, denn hierin unterscheidet es sich von CVS und Subversion (vor Version 1.5), wo der Entwickler die 'merge' Basis selbst ermitteln muss. Damit wird das Zusammenführen in Git um einiges leichter, als in anderen Systemen. +Es ist wichtig herauszustellen, dass Git den am besten geeigneten gemeinsamen Vorgänger als Grundlage für das Zusammenführen bestimmt, denn hierin unterscheidet es sich von CVS und Subversion (vor Version 1.5), wo der Entwickler beim Zusammenführen die 'merge' Basis selbst ermitteln muss. In Git ist das Zusammenführen dadurch wesentlich einfacher, als in anderen Systemen. @@ -357,7 +357,7 @@ Abbildung 3-17. Git erstellt automatisch ein 'commit', dass die zusammengeführt -Jetzt da wir die Arbeit zusammengeführt haben, ist der `iss53`-Branch nicht mehr notwendig. Du kannst ihn löschen und das Ticket im Ticket-Tracking-System schliessen. +Jetzt, da wir die Arbeit zusammengeführt haben, ist der `iss53`-Branch nicht mehr notwendig. Du kannst ihn löschen und das Ticket im Ticket-Tracking-System schließen. $ git branch -d iss53 @@ -381,12 +381,12 @@ Git hat hier keinen 'merge commit' erstellt. Es hat den Prozess gestoppt, damit 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") @@ -403,7 +403,7 @@ Alles, was einen 'merge' Konflikt aufweist und nicht gelöst werden konnte, wird -Das heisst, die Version in HEAD (Deines 'master'-Branches, denn der wurde per 'checkout' aktiviert als Du das 'merge' gemacht hast) ist der obere Teil des Blocks (alles oberhalb von '======='), und die Version aus dem `iss53`-Branch sieht wie der darunter befindliche Teil aus. Um den Konflikt zu lösen, musst Du Dich entweder für einen der beiden Teile entscheiden oder Du ersetzt den Teil komplett: +Das heißt, die Version in HEAD (Deines 'master'-Branches, denn der wurde per 'checkout' aktiviert, als Du das 'merge' gemacht hast) ist der obere Teil des Blocks (alles oberhalb von '======='), und die Version aus dem `iss53`-Branch sieht wie der darunter befindliche Teil aus. Um den Konflikt zu lösen, musst Du Dich entweder für einen der beiden Teile entscheiden oder Du ersetzt den Teil komplett: >>>>>>> iss53:index.html -Donde nos dice que la versión en HEAD (la rama 'master', la que habias activado antes de lanzar el comando de fusión), contiene lo indicado en la parte superior del bloque (todo lo que está encima de '======='). Y que la versión en 'iss53' contiene el resto, lo indicado en la parte inferior del bloque. Para resolver el conflicto, has de elegir manualmente contenido de uno o de otro lado. Por ejemplo, puedes optar por cambiar el bloque, dejandolo tal que: +Donde nos dice que la versión en HEAD (la rama `master`, la que habias activado antes de lanzar el comando de fusión), contiene lo indicado en la parte superior del bloque (todo lo que está encima de `=======`). Y que la versión en `iss53` contiene el resto, lo indicado en la parte inferior del bloque. Para resolver el conflicto, has de elegir manualmente contenido de uno o de otro lado. Por ejemplo, puedes optar por cambiar el bloque, dejándolo tal que: -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. +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 permitirá ir resolviendo conflictos con ella. $ git mergetool merge tool candidates: kdiff3 tkdiff xxdiff meld gvimdiff opendiff emerge vimdiff @@ -268,11 +268,11 @@ Si en lugar de resolver directamente, prefieres utilizar una herramienta gráfic {remote}: modified Hit return to start merge resolution tool (opendiff): -Si deseas usar una herramienta distinta de la escogida por defecto (en mi caso 'opendiff', porque estoy lanzando el comando en un Mac), puedes escogerla entre la lista de herramientas soportadas mostradas al principio ("merge tool candidates"). Tecleando el nombre de dicha herramienta. En el capítulo 7 se verá cómo cambiar este valor por defecto de tu entorno de trabajo. +Si deseas usar una herramienta distinta de la escogida por defecto (en mi caso `opendiff`, porque estoy lanzando el comando en un Mac), puedes escogerla entre la lista de herramientas soportadas mostradas al principio ("merge tool candidates"). Tecleando el nombre de dicha herramienta. En el capítulo 7 se verá cómo cambiar este valor por defecto de tu entorno de trabajo. Tras salir de la herramienta de fusionado, Git preguntará a ver si hemos resuelto todos los conflictos y la fusión ha sido satisfactoria. Si le indicas que así ha sido, Git marca como preparado (staged) el archivo que acabamos de modificar. -En cualquier momento, puedes lanzar el comando 'git status' para ver si ya has resuelto todos los conflictos: +En cualquier momento, puedes lanzar el comando `git status` para ver si ya has resuelto todos los conflictos: $ git status # On branch master @@ -282,7 +282,7 @@ En cualquier momento, puedes lanzar el comando 'git status' para ver si ya has r # modified: index.html # -Si todo ha ido correctamente, y ves que todos los archivos conflictivos están marcados como preparados, puedes lanzar el comando 'git commit' para terminar de confirmar la fusión. El mensaje de confirmación por defecto será algo parecido a: +Si todo ha ido correctamente, y ves que todos los archivos conflictivos están marcados como preparados, puedes lanzar el comando `git commit` para terminar de confirmar la fusión. El mensaje de confirmación por defecto será algo parecido a: Merge branch 'iss53' @@ -295,46 +295,46 @@ Si todo ha ido correctamente, y ves que todos los archivos conflictivos están m # and try again. # -Puedes modificar este mensaje añadiendo detalles sobre cómo has resuelto la fusión, si lo consideras util para que otros entiendan esta fusión en un futuro. Se trata de indicar porqué has hecho lo que has hecho; a no ser que resulte obvio, claro está. +Puedes modificar este mensaje añadiendo detalles sobre cómo has resuelto la fusión, si lo consideras útil para que otros entiendan esta fusión en un futuro. Se trata de indicar porqué has hecho lo que has hecho; a no ser que resulte obvio, claro está. ## Gestión de ramificaciones ## Ahora que ya has creado, fusionado y borrado algunas ramas, vamos a dar un vistazo a algunas herramientas de gestión muy útiles cuando comienzas a utilizar ramas profusamente. -El comando 'git branch' tiene más funciones que las de crear y borrar ramas. Si lo lanzas sin argumentos, obtienes una lista de las ramas presentes en tu proyecto: +El comando `git branch` tiene más funciones que las de crear y borrar ramas. Si lo lanzas sin argumentos, obtienes una lista de las ramas presentes en tu proyecto: $ git branch iss53 * master testing -Fijate en el carácter `*` delante de la rama 'master': nos indica la rama activa en este momento. Si hacemos una confirmación de cambios (commit), esa será la rama que avance. Para ver la última confirmación de cambios en cada rama, puedes usar el comando 'git branch -v': +Fijate en el carácter `*` delante de la rama `master`: nos indica la rama activa en este momento. Si hacemos una confirmación de cambios (commit), esa será la rama que avance. Para ver la última confirmación de cambios en cada rama, puedes usar el comando `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 -Otra opción útil para averiguar el estado de las ramas, es filtrarlas y mostrar solo aquellas que han sido fusionadas (o que no lo han sido) con la rama actualmente activa. Para ello, Git dispone, desde la versión 1.5.6, las opciones '--merged' y '--no-merged'. Si deseas ver las ramas que han sido fusionadas en la rama activa, puedes lanzar el comando 'git branch --merged': +Otra opción útil para averiguar el estado de las ramas, es filtrarlas y mostrar solo aquellas que han sido fusionadas (o que no lo han sido) con la rama actualmente activa. Para ello, Git dispone, desde la versión 1.5.6, las opciones `--merged` y `--no-merged`. Si deseas ver las ramas que han sido fusionadas en la rama activa, puedes lanzar el comando `git branch --merged`: $ git branch --merged iss53 * master -Aparece la rama 'iss53' porque ya ha sido fusionada. Y no lleva por delante el caracter `*` porque todo su contenido ya ha sido incorporado a otras ramas. Podemos borrarla tranquilamente con 'git branch -d', sin miedo a perder nada. +Aparece la rama `iss53` porque ya ha sido fusionada. Y no lleva por delante el caracter `*` porque todo su contenido ya ha sido incorporado a otras ramas. Podemos borrarla tranquilamente con `git branch -d`, sin miedo a perder nada. -Para mostrar todas las ramas que contienen trabajos sin fusionar aún, puedes utilizar el comando 'git branch --no-merged': +Para mostrar todas las ramas que contienen trabajos sin fusionar aún, puedes utilizar el comando `git branch --no-merged`: $ git branch --no-merged testing -Esto nos muestra la otra rama en el proyecto. Debido a que contiene trabajos sin fusionar aún, al intentarla borrar con 'git branch -d', el comando nos dará un error: +Esto nos muestra la otra rama en el proyecto. Debido a que contiene trabajos sin fusionar aún, al intentarla borrar con `git branch -d`, el comando nos dará un error: $ 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'. -Si realmente deseas borrar la rama, y perder el trabajo contenido en ella, puedes forzar el borrado con la opción '-D'; tal y como lo indica el mensaje de ayuda. +Si realmente deseas borrar la rama, y perder el trabajo contenido en ella, puedes forzar el borrado con la opción `-D`; tal y como lo indica el mensaje de ayuda. ## Flujos de trabajo ramificados ## @@ -342,9 +342,9 @@ Ahora que ya has visto los procedimientos básicos de ramificación y fusión, ### Ramas de largo recorrido ### -Por la sencillez de la fusión a tres bandas de Git, el fusionar de una rama a otra multitud de veces a lo largo del tiempo es facil de hacer. Esto te posibilita tener varias ramas siempre abiertas, e irlas usando en diferentes etapas del ciclo de desarrollo; realizando frecuentes fusiones entre ellas. +Por la sencillez de la fusión a tres bandas de Git, el fusionar de una rama a otra multitud de veces a lo largo del tiempo es fácil de hacer. Esto te posibilita tener varias ramas siempre abiertas, e irlas usando en diferentes etapas del ciclo de desarrollo; realizando frecuentes fusiones entre ellas. -Muchos desarrolladores que usan Git llevan un flujo de trabajo de esta naturaleza, manteniendo en la rama 'master' únicamente el código totalmente estable (el código que ha sido o que va a ser liberado). Teniendo otras ramas paralelas denominadas 'desarrollo' o 'siguiente', en las que trabajan y realizan pruebas. Estas ramas paralelas no suele estar siempre en un estado estable; pero cada vez que sí lo están, pueden ser fusionadas con la rama 'master'. También es habitual el incorporarle (pull) ramas puntuales (ramas temporales, como la rama 'iss53' del anterior ejemplo) cuando las completamos y estamos seguros de que no van a introducir errores. +Muchos desarrolladores que usan Git llevan un flujo de trabajo de esta naturaleza, manteniendo en la rama `master` únicamente el código totalmente estable (el código que ha sido o que va a ser liberado). Teniendo otras ramas paralelas denominadas `desarrollo` o `siguiente`, en las que trabajan y realizan pruebas. Estas ramas paralelas no suele estar siempre en un estado estable; pero cada vez que sí lo están, pueden ser fusionadas con la rama `master`. También es habitual el incorporarle (pull) ramas puntuales (ramas temporales, como la rama `iss53` del anterior ejemplo) cuando las completamos y estamos seguros de que no van a introducir errores. En realidad, en todo momento estamos hablando simplemente de apuntadores moviendose por la línea temporal de confirmaciones de cambio (commit history). Las ramas estables apuntan hacia posiciones más antiguas en el registro de confirmaciones. Mientras que las ramas avanzadas, las que van abriendo camino, apuntan hacia posiciones más recientes. @@ -356,63 +356,63 @@ Podría ser más sencillo pensar en las ramas como si fueran silos de almacenami Insert 18333fig0319.png Figura 3-19. Puede ayudar pensar en las ramas como silos de almacenamiento. -Este sistema de trabajo se puede ampliar para diversos grados de estabilidad. Algunos proyectos muy grandes suelen tener una rama denominada 'propuestas' o 'pu' (proposed updates). Donde suele estar todo aquello integrado desde otras ramas, pero que aún no está listo para ser incorporado a las ramas 'siguiente' o 'master'. La idea es mantener siempre diversas ramas en diversos grados de estabilidad; pero cuando alguna alcanza un estado más estable, la fusionamos con la rama inmediatamente superior a ella. +Este sistema de trabajo se puede ampliar para diversos grados de estabilidad. Algunos proyectos muy grandes suelen tener una rama denominada `propuestas` o `pu` (proposed updates). Donde suele estar todo aquello integrado desde otras ramas, pero que aún no está listo para ser incorporado a las ramas `siguiente` o `master`. La idea es mantener siempre diversas ramas en diversos grados de estabilidad; pero cuando alguna alcanza un estado más estable, la fusionamos con la rama inmediatamente superior a ella. Aunque no es obligatorio el trabajar con ramas de larga duración, realmente es práctico y útil. Sobre todo en proyectos largos o complejos. ### Ramas puntuales ### Las ramas puntuales, en cambio, son útiles en proyectos de cualquier tamaño. Una rama puntual es aquella de corta duración que abres para un tema o para una funcionalidad muy concretos. Es algo que nunca habrías hecho en otro sistema VCS, debido a los altos costos de crear y fusionar ramas que se suelen dar en esos sistemas. Pero en Git, por el contrario, es muy habitual el crear, trabajar con, fusionar y borrar ramas varias veces al día. -Tal y como has visto con las ramas 'iss53' y 'hotfix' que has creado en la sección anterior. Has hecho unas pocas confirmaciones de cambio en ellas, y luego las has borrado tras fusionarlas con la rama principal. Esta técnica te posibilita realizar rápidos y completos saltos de contexto. Y, debido a que el trabajo está claramente separado en silos, con todos los cambios de cada tema en su propia rama, te será mucho más sencillo revisar el código y seguir su evolución. Puedes mantener los cambios ahí durante minutos, dias o meses; y fusionarlos cuando realmente estén listos. En lugar de verte obligado a fusionarlos en el orden en que fueron creados y comenzaste a trabajar en ellos. +Tal y como has visto con las ramas `iss53` y `hotfix` que has creado en la sección anterior. Has hecho unas pocas confirmaciones de cambio en ellas, y luego las has borrado tras fusionarlas con la rama principal. Esta técnica te posibilita realizar rápidos y completos saltos de contexto. Y, debido a que el trabajo está claramente separado en silos, con todos los cambios de cada tema en su propia rama, te será mucho más sencillo revisar el código y seguir su evolución. Puedes mantener los cambios ahí durante minutos, dias o meses; y fusionarlos cuando realmente estén listos. En lugar de verte obligado a fusionarlos en el orden en que fueron creados y comenzaste a trabajar en ellos. -Por ejemplo, puedes realizar cierto trabajo en la rama 'master', ramificar para un problema concreto (rama 'iss91'), trabajar en él un rato, ramificar a una segunda rama para probar otra manera de resolverlo (rama 'iss92v2'), volver a la rama 'master' y trabajar un poco más, y, por último, ramificar temporalmente para probar algo de lo que no estás seguro (rama 'dumbidea'). El registro de confirmaciones (commit history) será algo parecido a la Figura 3-20. +Por ejemplo, puedes realizar cierto trabajo en la rama `master`, ramificar para un problema concreto (rama `iss91`), trabajar en él un rato, ramificar a una segunda rama para probar otra manera de resolverlo (rama `iss92v2`), volver a la rama `master` y trabajar un poco más, y, por último, ramificar temporalmente para probar algo de lo que no estás seguro (rama `dumbidea`). El registro de confirmaciones (commit history) será algo parecido a la Figura 3-20. Insert 18333fig0320.png Figura 3-20. El registro de confirmaciones con múltiples ramas puntuales. -En este momento, supongamos que te decides por la segunda solución al problema (rama 'iss92v2'); y que, tras mostrar la rama 'dumbidea' a tus compañeros, resulta que les parece una idea genial. Puedes descartar la rama 'iss91' (perdiendo las confirmaciones C5 y C6), y fusionar las otras dos. El registro será algo parecido a la Figura 3-21. +En este momento, supongamos que te decides por la segunda solución al problema (rama `iss92v2`); y que, tras mostrar la rama `dumbidea` a tus compañeros, resulta que les parece una idea genial. Puedes descartar la rama `iss91` (perdiendo las confirmaciones C5 y C6), y fusionar las otras dos. El registro será algo parecido a la Figura 3-21. Insert 18333fig0321.png -Figura 3-21. El registro tras fusionar 'dumbidea' e 'iss91v2'. +Figura 3-21. El registro tras fusionar `dumbidea` e `iss91v2`. -Es importante recordar que, mientras estás haciendo todo esto, todas las ramas son completamente locales. Cuando ramificas y fusionas, todo se realiza en tu propio repositório Git. No hay nigún tipo de tráfico con ningún servidor. +Es importante recordar que, mientras estás haciendo todo esto, todas las ramas son completamente locales. Cuando ramificas y fusionas, todo se realiza en tu propio repositorio Git. No hay nigún tipo de tráfico con ningún servidor. ## Ramas Remotas ## Las ramas remotas son referencias al estado de ramas en tus repositorios remotos. Son ramas locales que no puedes mover; se mueven automáticamente cuando estableces comunicaciones en la red. Las ramas remotas funcionan como marcadores, para recordarte en qué estado se encontraban tus repositorios remotos la última vez que conectaste con ellos. -Suelen referenciarse como '(remoto)/(rama)'. Por ejemplo, si quieres saber cómo estaba la rama 'master' en el remoto 'origin'. Puedes revisar la rama 'origin/master'. O si estás trabajando en un problema con un compañero y este envia (push) una rama 'iss53', tu tendrás tu propia rama de trabajo local 'iss53'; pero la rama en el servidor apuntará a la última confirmación (commit) en la rama 'origin/iss53'. +Suelen referenciarse como `(remoto)/(rama)`. Por ejemplo, si quieres saber cómo estaba la rama `master` en el remoto `origin`. Puedes revisar la rama `origin/master`. O si estás trabajando en un problema con un compañero y este envia (push) una rama `iss53`, tu tendrás tu propia rama de trabajo local `iss53`; pero la rama en el servidor apuntará a la última confirmación (commit) en la rama `origin/iss53`. -Esto puede ser un tanto confuso, pero intentemos aclararlo con un ejemplo. Supongamos que tienes un sevidor Git en tu red, en 'git.ourcompany.com'. Si haces un clón desde ahí, Git automáticamente lo denominará 'origin', traerá (pull) sus datos, creará un apuntador hacia donde esté en ese momento su rama 'master', denominará la copia local 'origin/master'; y será inamovible para tí. Git te proporcionará también tu propia rama 'master', apuntando al mismo lugar que la rama 'master' de 'origin'; siendo en esta última donde podrás trabajar. +Esto puede ser un tanto confuso, pero intentemos aclararlo con un ejemplo. Supongamos que tienes un sevidor Git en tu red, en `git.ourcompany.com`. Si haces un clón desde ahí, Git automáticamente lo denominará `origin`, traerá (pull) sus datos, creará un apuntador hacia donde esté en ese momento su rama `master`, denominará la copia local `origin/master`; y será inamovible para ti. Git te proporcionará también tu propia rama `master`, apuntando al mismo lugar que la rama `master` de `origin`; siendo en esta última donde podrás trabajar. 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. +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. -Para sincronizarte, puedes utilizar el comando 'git fetch origin'. Este comando localiza en qué servidor está el origen (en este caso 'git.ourcompany.com'), recupera cualquier dato presente allí que tu no tengas, y actualiza tu base de datos local, moviendo tu rama 'origin/master' para que apunte a esta nueva y más reciente posición (ver Figura 3-24). +Para sincronizarte, puedes utilizar el comando `git fetch origin`. Este comando localiza en qué servidor está el origen (en este caso `git.ourcompany.com`), recupera cualquier dato presente allí que tu no tengas, y actualiza tu base de datos local, moviendo tu rama `origin/master` para que apunte a esta nueva y más reciente posición (ver Figura 3-24). Insert 18333fig0324.png -Figura 3-24. El comando 'git fetch' actualiza tus referencias remotas. +Figura 3-24. El comando `git fetch` actualiza tus referencias remotas. -Para ilustrar mejor el caso de tener múltiples servidores y cómo van las ramas remotas para esos proyectos remotos. Supongamos que tienes otro servidor Git; utilizado solamente para desarrollo, por uno de tus equipos sprint. Un servidor en 'git.team1.ourcompany.com'. Puedes incluirlo como una nueva referencia remota a tu proyecto actual, mediante el comando 'git remote add', tal y como vimos en el capítulo 2. Puedes denominar 'teamone' a este remoto, poniendo este nombre abreviado para la URL (ver Figura 3-25) +Para ilustrar mejor el caso de tener múltiples servidores y cómo van las ramas remotas para esos proyectos remotos. Supongamos que tienes otro servidor Git; utilizado solamente para desarrollo, por uno de tus equipos sprint. Un servidor en `git.team1.ourcompany.com`. Puedes incluirlo como una nueva referencia remota a tu proyecto actual, mediante el comando `git remote add`, tal y como vimos en el capítulo 2. Puedes denominar `teamone` a este remoto, poniendo este nombre abreviado para la URL (ver Figura 3-25) Insert 18333fig0325.png Figura 3-25. Añadiendo otro servidor como remoto. -Ahora, puedes usar el comando 'git fetch teamone' para recuperar todo el contenido del servidor que tu no tenias. Debido a que dicho servidor es un subconjunto de de los datos del servidor 'origin' que tienes actualmente, Git no recupera (fetch) ningún dato; simplemente prepara una rama remota llamada 'teamone/master' para apuntar a la confirmación (commit) que 'teamone' tiene en su rama 'master'. +Ahora, puedes usar el comando `git fetch teamone` para recuperar todo el contenido del servidor que tu no tenias. Debido a que dicho servidor es un subconjunto de de los datos del servidor `origin` que tienes actualmente, Git no recupera (fetch) ningún dato; simplemente prepara una rama remota llamada `teamone/master` para apuntar a la confirmación (commit) que `teamone` tiene en su rama `master`. Insert 18333fig0326.png -Figura 3-26. Obtienes una referencia local a la posición en la rama 'master' de 'teamone'. +Figura 3-26. Obtienes una referencia local a la posición en la rama `master` de `teamone`. ### Publicando ### Cuando quieres compartir una rama con el resto del mundo, has de llevarla (push) a un remoto donde tengas permisos de escritura. Tus ramas locales no se sincronizan automáticamente con los remotos en los que escribes. Sino que tienes que llevar (push) expresamente, cada vez, al remoto las ramas que desees compartir. De esta forma, puedes usar ramas privadas para el trabajo que no deseas compartir. Llevando a un remoto tan solo aquellas partes que deseas aportar a los demás. -Si tienes una rama llamada 'serverfix', con la que vas a trabajar en colaboración; puedes llevarla al remoto de la misma forma que llevaste tu primera rama. Con el comando 'git push (remoto) (rama)': +Si tienes una rama llamada `serverfix`, con la que vas a trabajar en colaboración; puedes llevarla al remoto de la misma forma que llevaste tu primera rama. Con el comando `git push (remoto) (rama)`: $ git push origin serverfix Counting objects: 20, done. @@ -422,9 +422,9 @@ Si tienes una rama llamada 'serverfix', con la que vas a trabajar en colaboraci To git@github.com:schacon/simplegit.git * [new branch] serverfix -> serverfix -Esto es un poco como un atajo. Git expande automáticamente el nombre de rama 'serverfix' a 'refs/heads/serverfix:refs/heads/serverfix', que significa: "coge mi rama local 'serverfix' y actualiza con ella la rama 'serverfix' del remoto". Volveremos más tarde sobre el tema de 'refs/heads/', viendolo en detalle en el capítulo 9; aunque puedes ignorarlo por ahora. También puedes hacer 'git push origin serverfix:serverfix', que hace lo mismo; es decir: "coge mi 'serverfix' y hazlo el 'serverfix' remoto". Puedes utilizar este último formato para llevar una rama local a una rama remota con otro nombre distinto. Si no quieres que se llame 'serverfix' en el remoto, puedes lanzar, por ejemplo, 'git push origin serverfix:awesomebranch'; para llevar tu rama 'serverfix' local a la rama 'awesomebranch' en el proyecto remoto. +Esto es un poco como un atajo. Git expande automáticamente el nombre de rama `serverfix` a `refs/heads/serverfix:refs/heads/serverfix`, que significa: "coge mi rama local `serverfix` y actualiza con ella la rama `serverfix` del remoto". Volveremos más tarde sobre el tema de `refs/heads/`, viéndolo en detalle en el capítulo 9; aunque puedes ignorarlo por ahora. También puedes hacer `git push origin serverfix:serverfix`, que hace lo mismo; es decir: "coge mi `serverfix` y hazlo el `serverfix` remoto". Puedes utilizar este último formato para llevar una rama local a una rama remota con otro nombre distinto. Si no quieres que se llame `serverfix` en el remoto, puedes lanzar, por ejemplo, `git push origin serverfix:awesomebranch`; para llevar tu rama `serverfix` local a la rama `awesomebranch` en el proyecto remoto. -La próxima vez que tus colaboradores recuperen desde el servidor, obtendrán una referencia a donde la versión de 'serverfix' en el servidor esté bajo la rama remota 'origin/serverfix': +La próxima vez que tus colaboradores recuperen desde el servidor, obtendrán bajo la rama remota `origin/serverfix` una referencia a donde esté la versión de `serverfix` en el servidor: $ git fetch origin remote: Counting objects: 20, done. @@ -434,21 +434,21 @@ La próxima vez que tus colaboradores recuperen desde el servidor, obtendrán un From git@github.com:schacon/simplegit * [new branch] serverfix -> origin/serverfix -Es importante destacar que cuando recuperas (fetch) nuevas ramas remotas, no obtienes automáticamente una copia editable local de las mismas. En otras palabras, en este caso, no tienes una nueva rama 'serverfix'. Sino que únicamente tienes un puntero no editable a 'origin/serverfix'. +Es importante destacar que cuando recuperas (fetch) nuevas ramas remotas, no obtienes automáticamente una copia editable local de las mismas. En otras palabras, en este caso, no tienes una nueva rama `serverfix`. Sino que únicamente tienes un puntero no editable a `origin/serverfix`. -Para integrar (merge) esto en tu actual rama de trabajo, puedes usar el comando 'git merge origin/serverfix'. Y si quieres tener tu propia rama 'serverfix', donde puedas trabajar, puedes crearla directamente basandote en rama remota: +Para integrar (merge) esto en tu actual rama de trabajo, puedes usar el comando `git merge origin/serverfix`. Y si quieres tener tu propia rama `serverfix`, donde puedas trabajar, puedes crearla directamente basaádote en rama remota: $ 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" -Esto sí te da una rama local donde puedes trabajar, comenzando donde 'origin/serverfix' estaba en ese momento. +Esto sí te da una rama local donde puedes trabajar, comenzando donde `origin/serverfix` estaba en ese momento. ### Haciendo seguimiento a las ramas ### -Activando (checkout) una rama local a partir de una rama remota, se crea automáticamente lo que podríamos denominar "una rama de seguimiento" (tracking branch). Las ramas de seguimiento son ramas locales que tienen una relación directa con alguna rama remota. Si estás en una rama de seguimiento y tecleas el comando 'git push', Git sabe automáticamente a qué servidor y a qué rama ha de llevar los contenidos. Igualmente, tecleando 'git pull' mientras estamos en una de esas ramas, recupera (fetch) todas las referencias remotas y las consolida (merge) automáticamente en la correspondiente rama remota. +Activando (checkout) una rama local a partir de una rama remota, se crea automáticamente lo que podríamos denominar "una rama de seguimiento" (tracking branch). Las ramas de seguimiento son ramas locales que tienen una relación directa con alguna rama remota. Si estás en una rama de seguimiento y tecleas el comando `git push`, Git sabe automáticamente a qué servidor y a qué rama ha de llevar los contenidos. Igualmente, tecleando `git pull` mientras estamos en una de esas ramas, recupera (fetch) todas las referencias remotas y las consolida (merge) automáticamente en la correspondiente rama remota. -Cuando clonas un repositorio, este suele crear automáticamente una rama 'master' que hace seguimiento de 'origin/master'. Y es por eso que 'git push' y 'git pull' trabajan directamente, sin necesidad de más argumentos. Sin embargo, puedes preparar otras ramas de seguimiento si deseas tener unas que no hagan seguimiento de ramas en 'origin' y que no sigan a la rama 'master'. El ejemplo más simple, es el que acabas de ver al lanzar el comando 'git checkout -b [rama] [nombreremoto]/[rama]'. Si tienes la versión 1.6.2 de Git, o superior, puedes utilizar también el parámetro '--track': +Cuando clonas un repositorio, este suele crear automáticamente una rama `master` que hace seguimiento de `origin/master`. Y es por eso que `git push` y `git pull` trabajan directamente, sin necesidad de más argumentos. Sin embargo, puedes preparar otras ramas de seguimiento si deseas tener unas que no hagan seguimiento de ramas en `origin` y que no sigan a la rama `master`. El ejemplo más simple, es el que acabas de ver al lanzar el comando `git checkout -b [rama] [nombreremoto]/[rama]`. Si tienes la versión 1.6.2 de Git, o superior, puedes utilizar también el parámetro `--track`: $ git checkout --track origin/serverfix Branch serverfix set up to track remote branch refs/remotes/origin/serverfix. @@ -460,17 +460,17 @@ Para preparar una rama local con un nombre distinto a la del remoto, puedes util Branch sf set up to track remote branch refs/remotes/origin/serverfix. Switched to a new branch "sf" -Así, tu rama local 'sf' va a llevar (push) y traer (pull) hacia o desde 'origin/serverfix'. +Así, tu rama local `sf` va a llevar (push) y traer (pull) hacia o desde `origin/serverfix`. ### Borrando ramas remotas ### -Imagina que ya has terminado con una rama remota. Es decir, tanto tu como tus colaboradores habeis completado una determinada funcionalidad y la habeis incorporado (merge) a la rama 'master' en el remoto (o donde quiera que tengais la rama de código estable). Puedes borrar la rama remota utilizando la un tanto confusa sintaxis: 'git push [nombreremoto] :[rama]'. Por ejemplo, si quieres borrar la rama 'serverfix' del servidor, puedes utilizar: +Imagina que ya has terminado con una rama remota. Es decir, tanto tu como tus colaboradores habeis completado una determinada funcionalidad y la habeis incorporado (merge) a la rama `master` en el remoto (o donde quiera que tengais la rama de código estable). Puedes borrar la rama remota utilizando la un tanto confusa sintaxis: `git push [nombreremoto] :[rama]`. Por ejemplo, si quieres borrar la rama `serverfix` del servidor, puedes utilizar: $ git push origin :serverfix To git@github.com:schacon/simplegit.git - [deleted] serverfix -Y....Boom!. La rama en el servidor ha desaparecido. Puedes grabarte a fuego esta página, porque necesitarás ese comando y, lo más probable es que hayas olvidado su sintaxis. Una manera de recordar este comando es dándonos cuenta de que proviene de la sintaxis 'git push [nombreremoto] [ramalocal]:[ramaremota]'. Si omites la parte '[ramalocal]', lo que estás diciendo es: "no cojas nada de mi lado y haz con ello [ramaremota]". +Y... ¡Boom!. La rama en el servidor ha desaparecido. Puedes grabarte a fuego esta página, porque necesitarás ese comando y, lo más probable es que hayas olvidado su sintaxis. Una manera de recordar este comando es dándonos cuenta de que proviene de la sintaxis `git push [nombreremoto] [ramalocal]:[ramaremota]`. Si omites la parte `[ramalocal]`, lo que estás diciendo es: "no cojas nada de mi lado y haz con ello [ramaremota]". ## Reorganizando el trabajo realizado ## @@ -483,12 +483,12 @@ Volviendo al ejemplo anterior, en la sección sobre fusiones (ver Figura 3-27), Insert 18333fig0327.png Figura 3-27. El registro de confirmaciones inicial. -La manera más sencilla de integrar ramas, tal y como hemos visto, es el comando 'git merge'. Realiza una fusión a tres bandas entre las dos últimas instantáneas de cada rama (C3 y C4) y el ancestro común a ambas (C2); creando una nueva instantánea (snapshot) y la correspondiente confirmación (commit), según se muestra en la Figura 3-28. +La manera más sencilla de integrar ramas, tal y como hemos visto, es el comando `git merge`. Realiza una fusión a tres bandas entre las dos últimas instantáneas de cada rama (C3 y C4) y el ancestro común a ambas (C2); creando una nueva instantánea (snapshot) y la correspondiente confirmación (commit), según se muestra en la Figura 3-28. Insert 18333fig0328.png Figura 3-28. Fusionando una rama para integrar el registro de trabajos divergentes. -Aunque también hay otra forma de hacerlo: puedes coger los cambios introducidos en C3 y reaplicarlos encima de C4. Esto es lo que en Git llamamos _reorganizar_. Con el comando 'git rebase', puedes coger todos los cambios confirmados en una rama, y reaplicarlos sobre otra. +Aunque también hay otra forma de hacerlo: puedes coger los cambios introducidos en C3 y reaplicarlos encima de C4. Esto es lo que en Git llamamos _reorganizar_. Con el comando `git rebase`, puedes coger todos los cambios confirmados en una rama, y reaplicarlos sobre otra. Por ejemplo, puedes lanzar los comandos: @@ -502,29 +502,29 @@ Haciendo que Git: vaya al ancestro común de ambas ramas (donde estás actualmen Insert 18333fig0329.png Figura 3-29. Reorganizando sobre C4 los cambios introducidos en C3. -En este momento, puedes volver a la rama 'master' y hacer una fusión con avance rápido (fast-forward merge). (ver Figura 3-30) +En este momento, puedes volver a la rama `master` y hacer una fusión con avance rápido (fast-forward merge). (ver Figura 3-30) Insert 18333fig0330.png -Figura 3-30. Avance rápido de la rama 'master'. +Figura 3-30. Avance rápido de la rama `master`. Así, la instantánea apuntada por C3' aquí es exactamente la misma apuntada por C5 en el ejemplo de la fusión. No hay ninguna diferencia en el resultado final de la integración, pero el haberla hecho reorganizando nos deja un registro más claro. Si examinas el registro de una rama reorganizada, este aparece siempre como un registro lineal: como si todo el trabajo se hubiera realizado en series, aunque realmente se haya hecho en paralelo. -Habitualmente, optarás por esta vía cuando quieras estar seguro de que tus confirmaciones de cambio (commits) se pueden aplicar limpiamente sobre una rama remota; posiblemente, en un proyecto donde estés intentando colaborar, pero lleves tu el mantenimiento. En casos como esos, puedes trabajar sobre una rama y luego reorgainzar lo realizado en la rama 'origin/master' cuando lo tengas todo listo para enviarlo al proyecto principal. De esta forma, la persona que mantiene el proyecto no necesitará hacer ninguna integración con tu trabajo; le bastará con un avance rápido o una incorporación limpia. +Habitualmente, optarás por esta vía cuando quieras estar seguro de que tus confirmaciones de cambio (commits) se pueden aplicar limpiamente sobre una rama remota; posiblemente, en un proyecto donde estés intentando colaborar, pero lleves tu el mantenimiento. En casos como esos, puedes trabajar sobre una rama y luego reorganizar lo realizado en la rama `origin/master` cuando lo tengas todo listo para enviarlo al proyecto principal. De esta forma, la persona que mantiene el proyecto no necesitará hacer ninguna integración con tu trabajo; le bastará con un avance rápido o una incorporación limpia. -Cabe destacar que la instantánea (snapshot) apuntada por la confirmación (commit) final, tanto si es producto de una regorganización (rebase) como si lo es de una fusión (merge), es exactamente la misma instantánea. Lo único diferente es el registro. La reorganización vuelve a aplicar cambios de una rama de trabajo sobre otra rama, en el mismo orden en que fueron introducidos en la primera. Mientras que la fusión combina entre sí los dos puntos finales de ambas ramas. +Cabe destacar que la instantánea (snapshot) apuntada por la confirmación (commit) final, tanto si es producto de una reorganización (rebase) como si lo es de una fusión (merge), es exactamente la misma instantánea. Lo único diferente es el registro. La reorganización vuelve a aplicar cambios de una rama de trabajo sobre otra rama, en el mismo orden en que fueron introducidos en la primera. Mientras que la fusión combina entre sí los dos puntos finales de ambas ramas. ### Algunas otras reorganizaciones interesantes ### -También puedes aplicar una reorganización (rebase) sobre otra cosa además de sobre la rama de reorganización. Por ejemplo, sea un registro como el de la Figura 3-31. Has ramificado a una rama puntual ('server') para añadir algunas funcionalidades al proyecto, y luego has confirmado los cambios. Despues, vuelves a la rama original para hacer algunos cambios en la parte cliente (rama 'client'), y confirmas también esos cambios. Por último, vuelves sobre la rama 'server' y haces algunos cambios más. +También puedes aplicar una reorganización (rebase) sobre otra cosa además de sobre la rama de reorganización. Por ejemplo, sea un registro como el de la Figura 3-31. Has ramificado a una rama puntual (`server`) para añadir algunas funcionalidades al proyecto, y luego has confirmado los cambios. Después, vuelves a la rama original para hacer algunos cambios en la parte cliente (rama `client`), y confirmas también esos cambios. Por último, vuelves sobre la rama `server` y haces algunos cambios más. Insert 18333fig0331.png Figura 3-31. Un registro con una rama puntual sobre otra rama puntual. -Imagina que decides incorporar tus cambios de la parte cliente sobre el proyecto principal, para hacer un lanzamiento de versión; pero no quieres lanzar aún los cambios de la parte server porque no están aún suficientemente probados. Puedes coger los cambios del cliente que no estan en server (C8 y C9), y reaplicarlos sobre tu rama principal usando la opción '--onto' del comando 'git rebase': +Imagina que decides incorporar tus cambios de la parte cliente sobre el proyecto principal, para hacer un lanzamiento de versión; pero no quieres lanzar aún los cambios de la parte server porque no están aún suficientemente probados. Puedes coger los cambios del cliente que no están en server (C8 y C9), y reaplicarlos sobre tu rama principal usando la opción `--onto` del comando `git rebase`: $ git rebase --onto master server client -Esto viene a decir: "Activa la rama 'client', averigua los cambios desde el ancestro común entre las ramas 'client' y 'server', y aplicalos en la rama 'master'. Puede parecer un poco complicado, pero los resultados, mostrados en la Figura 3-32, son realmente interesantes. +Esto viene a decir: "Activa la rama `client`, averigua los cambios desde el ancestro común entre las ramas `client` y `server`, y aplicarlos en la rama `master`. Puede parecer un poco complicado, pero los resultados, mostrados en la Figura 3-32, son realmente interesantes. Insert 18333fig0332.png Figura 3-32. Reorganizando una rama puntual fuera de otra rama puntual. @@ -535,23 +535,23 @@ Y, tras esto, ya puedes avanzar la rama principal (ver Figura 3-33): $ git merge client Insert 18333fig0333.png -Figura 3-33. Avance rápido de tu rama 'master', para incluir los cambios de la rama 'client'. +Figura 3-33. Avance rápido de tu rama `master`, para incluir los cambios de la rama `client`. -Ahora supongamos que decides traerlos (pull) también sobre tu rama 'server'. Puedes reorganizar (rebase) la rama 'server' sobre la rama 'master' sin necesidad siquiera de comprobarlo previamente, usando el comando 'git rebase [ramabase] [ramapuntual]'. El cual activa la rama puntual ('server' en este caso) y la aplica sobre la rama base ('master' en este caso): +Ahora supongamos que decides traerlos (pull) también sobre tu rama `server`. Puedes reorganizar (rebase) la rama `server` sobre la rama `master` sin necesidad siquiera de comprobarlo previamente, usando el comando `git rebase [ramabase] [ramapuntual]`. El cual activa la rama puntual (`server` en este caso) y la aplica sobre la rama base (`master` en este caso): $ git rebase master server -Esto vuelca el trabajo de 'server' sobre el de 'master', tal y como se muestra en la Figura 3-34. +Esto vuelca el trabajo de `server` sobre el de `master`, tal y como se muestra en la Figura 3-34. Insert 18333fig0334.png -Figura 3-34. Reorganizando la rama 'server' sobre la rama 'branch'. +Figura 3-34. Reorganizando la rama `server` sobre la rama `branch`. -Después, puedes avanzar rápidamente la rama base ('master'): +Después, puedes avanzar rápidamente la rama base (`master`): $ git checkout master $ git merge server -Y por último puedes eliminar las ramas 'client' y 'server' porque ya todo su contenido ha sido integrado y no las vas a necesitar más. Dejando tu registro tras todo este proceso tal y como se muestra en la Figura 3-35: +Y por último puedes eliminar las ramas `client` y `server` porque ya todo su contenido ha sido integrado y no las vas a necesitar más. Dejando tu registro tras todo este proceso tal y como se muestra en la Figura 3-35: $ git branch -d client $ git branch -d server @@ -561,15 +561,15 @@ Figura 3-35. Registro final de confirmaciones de cambio. ### Los peligros de la reorganización ### -Ahh...., pero la dicha de la reorganización no la alcanzamos sin sus contrapartidas: +Ahh..., pero la dicha de la reorganización no la alcanzamos sin sus contrapartidas: **Nunca reorganices confirmaciones de cambio (commits) que hayas enviado (push) a un repositorio público.** Siguiendo esta recomendación, no tendrás problemas. Pero si no la sigues, la gente te odiará y serás despreciado por tus familiares y amigos. -Cuando reorganizas algo, estás abandonando las confirmaciones de cambio ya creadas y estás creando unas nuevas; que son similares, pero diferentes. Si envias (push) confirmaciones (commits) a alguna parte, y otros las recogen (pull) de allí. Y después vas tu y las reescribes con 'git rebase' y las vuelves a enviar (push) de nuevo. Tus colaboradores tendrán que refusionar (re-merge) su trabajo y todo se volverá tremendamente complicado cuando intentes recoger (pull) su trabajo de vuelta sobre el tuyo. +Cuando reorganizas algo, estás abandonando las confirmaciones de cambio ya creadas y estás creando unas nuevas; que son similares, pero diferentes. Si envias (push) confirmaciones (commits) a alguna parte, y otros las recogen (pull) de allí. Y después vas tu y las reescribes con `git rebase` y las vuelves a enviar (push) de nuevo. Tus colaboradores tendrán que refusionar (re-merge) su trabajo y todo se volverá tremendamente complicado cuando intentes recoger (pull) su trabajo de vuelta sobre el tuyo. -Vamos a verlo con un ejemplo. Imaginate que haces un clon desde un servidor central, y luego trabajas sobre él. Tu registro de cambios puede ser algo como lo de la Figura 3-36. +Vamos a verlo con un ejemplo. Imagínate que haces un clon desde un servidor central, y luego trabajas sobre él. Tu registro de cambios puede ser algo como lo de la Figura 3-36. Insert 18333fig0336.png Figura 3-36. Clonar un repositorio y trabajar sobre él. @@ -579,20 +579,20 @@ Ahora, otra persona trabaja también sobre ello, realiza una fusión (merge) y l Insert 18333fig0337.png Figura 3-37. Traer (fetch) algunas confirmaciones de cambio (commits) y fusionarlas (merge) sobre tu trabajo. -A continuación, la persona que habia llevado cambios al servidor central decide retroceder y reorganizar su trabajo; haciendo un 'git push --force' para sobreescribir el registro en el servidor. Tu te traes (fetch) esos nuevos cambios desde el servidor. +A continuación, la persona que había llevado cambios al servidor central decide retroceder y reorganizar su trabajo; haciendo un `git push --force` para sobrescribir el registro en el servidor. Tu te traes (fetch) esos nuevos cambios desde el servidor. Insert 18333fig0338.png -Figura 3-38. Alguien envia (push) confirmaciones (commits) reorganizadas, abandonando las confirmaciones en las que tu habias basado tu trabajo. +Figura 3-38. Alguien envií (push) confirmaciones (commits) reorganizadas, abandonando las confirmaciones en las que tu habías basado tu trabajo. En ese momento, tu te ves obligado a fusionar (merge) tu trabajo de nuevo, aunque creias que ya lo habias hecho antes. La reorganización cambia los resumenes (hash) SHA-1 de esas confirmaciones (commits), haciendo que Git se crea que son nuevas confirmaciones. Cuando realmente tu ya tenias el trabajo de C4 en tu registro. Insert 18333fig0339.png Figura 3-39. Vuelves a fusionar el mismo trabajo en una nueva fusión confirmada. -Te ves obligado a fusionar (merge) ese trabajo en algún punto, para poder seguir adelante con otros desarrollos en el futuro. Tras todo esto, tu registro de confirmaciones de cambio (commit history) contendrá tanto la confirmación C4 como la C4'; teniendo ambas el mismo contenido y el mismo mensaje de confirmación. Si lanzas un 'git log' en un registro como este, verás dos confirmaciones con el mismo autor, misma fecha y mismo mensaje. Lo que puede llevar a confusiones. Es más, si luego tu envias (push) ese registro de vuelta al servidor, vas a introducir todas esas confirmaciones reorganizadas en el servidor central. Lo que puede confundir aún más a la gente. +Te ves obligado a fusionar (merge) ese trabajo en algún punto, para poder seguir adelante con otros desarrollos en el futuro. Tras todo esto, tu registro de confirmaciones de cambio (commit history) contendrá tanto la confirmación C4 como la C4'; teniendo ambas el mismo contenido y el mismo mensaje de confirmación. Si lanzas un `git log` en un registro como este, verás dos confirmaciones con el mismo autor, misma fecha y mismo mensaje. Lo que puede llevar a confusiones. Es más, si luego tu envías (push) ese registro de vuelta al servidor, vas a introducir todas esas confirmaciones reorganizadas en el servidor central. Lo que puede confundir aún más a la gente. Si solo usas la reorganización como una vía para hacer limpieza y organizar confirmaciones de cambio antes de enviarlas, y si únicamente reorganizas confirmaciones que nunca han sido públicas. Entonces no tendrás problemas. Si, por el contrario, reorganizas confirmaciones que alguna vez han sido públicas y otra gente ha basado su trabajo en ellas. Entonces estarás en un aprieto. ## Recapitulación ## -Hemos visto los procedimientos básicos de ramificación (branching) y fusión (merging) en Git. A estas alturas, te sentirás cómodo creando nuevas ramas (branch), saltando (checkout) entre ramas para trabajar y fusionando (merge) ramas entre ellas. También conocerás cómo compatir tus ramas enviandolas (push) a un servidor compartido, cómo trabajar colaborativamente en ramas compartidas, y cómo reorganizar (rebase) tus ramas antes de compartirlas. +Hemos visto los procedimientos básicos de ramificación (branching) y fusión (merging) en Git. A estas alturas, te sentirás cómodo creando nuevas ramas (branch), saltando (checkout) entre ramas para trabajar y fusionando (merge) ramas entre ellas. También conocerás cómo compartir tus ramas enviándolas (push) a un servidor compartido, cómo trabajar colaborativamente en ramas compartidas, y cómo reorganizar (rebase) tus ramas antes de compartirlas. diff --git a/es/04-git-server/01-chapter4.markdown b/es/04-git-server/01-chapter4.markdown index 81597c804..b9fde505d 100755 --- a/es/04-git-server/01-chapter4.markdown +++ b/es/04-git-server/01-chapter4.markdown @@ -584,7 +584,7 @@ GitHub es también una compañia comercial, que cobra por las cuentas que tienen ### Configurando una cuenta de usuario ### -El primer paso es dar de alta una cuenta gratuita. Si visitas la página de Precios e Inicio de Sesión, en 'http://github.com/plans', y clicas sobre el botón "Registro" ("Sign Up") de las cuentas gratuitas, verás una página de registro: +El primer paso es dar de alta una cuenta gratuita. Si visitas la página de Precios e Inicio de Sesión, en 'https://github.com/pricing', y clicas sobre el botón "Registro" ("Sign Up") de las cuentas gratuitas, verás una página de registro: Insert 18333fig0402.png Figura 4-2. La página de planes GitHub. diff --git a/es/06-git-tools/01-chapter6.markdown b/es/06-git-tools/01-chapter6.markdown index 254a8656f..5ae5c5c8b 100644 --- a/es/06-git-tools/01-chapter6.markdown +++ b/es/06-git-tools/01-chapter6.markdown @@ -59,7 +59,7 @@ Mucha gente se suele preocupar por si, por casualidad, dos objetos en su reposit Si se da la casualidad de confirmar cambios en un objeto y que a este se le asigne el mismo código SHA-1 que otro ya existente en el repositorio. Al ver el objeto previamente almacenado en la base de datos, Git asumirá que este ya existía. Al intentar recuperar (check-out) el objeto más tarde, siempre se obtendrán los datos del primer objeto. -No obstante, hemos de ser conscientes de lo altamente improbable de un suceso así. Los códigos SHA-1 son de 20 bytes, (160 bits). El número de objetos, codificados aleatóriamente, necesarios para asegurar un 50% de probabilidad de darse una sola colisión es cercano a 2^80 (la fórmula para determinar la probabilidad de colisión es `p = (n(n-1)/2) * (1/2^160))`). 2^80 es 1'2 x 10^24, o lo que es lo mismo, 1 billón de billones. Es decir, unas 1.200 veces el número de granos de arena en la Tierra. +No obstante, hemos de ser conscientes de lo altamente improbable de un suceso así. Los códigos SHA-1 son de 20 bytes, (160 bits). El número de objetos, codificados aleatóriamente, necesarios para asegurar un 50% de probabilidad de darse una sola colisión es cercano a 2^80 (la fórmula para determinar la probabilidad de colisión es `p = (n(n-1)/2) * (1/2^160)`)). 2^80 es 1'2 x 10^24, o lo que es lo mismo, 1 billón de billones. Es decir, unas 1.200 veces el número de granos de arena en la Tierra. El siguiente ejemplo puede ser bastante ilustrativo, para hacernos una idea de lo que podría tardarse en darse una colisión en el código SHA-1: Si todos los 6'5 billones de humanos en el planeta Tierra estuvieran programando y, cada segundo, cada uno de ellos escribiera código equivalente a todo el histórico del kernel de Linux (cerca de 1 millón de objetos Git), enviandolo todo a un enorme repositorio Git. Serían necesarios unos 5 años antes de que dicho repositorio contuviera suficientes objetos como para tener una probabilidad del 50% de darse una sola colisión en el código SHA-1. Es mucho más probable que todos los miembros de nuestro equipo de programación fuesen atacados y matados por lobos, en incidentes no relacionados entre sí, acaecidos todos ellos en una misma noche. @@ -440,7 +440,7 @@ Con ello, se limpia el área de trabajo: $ git status # On branch master - nothing to commit (working directory clean) + nothing to commit, working directory clean Y se permite cambiar de rama para ponerse a trabajar en cualquier otra parte. Con la tranquilidad de que los cambios a medio completar están guardados a buen recaudo en la pila de guardado rápido. Para ver el contenido de dicha pila, se emplea el comando 'git stash list': diff --git a/es/07-customizing-git/01-chapter7.markdown b/es/07-customizing-git/01-chapter7.markdown index af19b3cc6..6ac5413f4 100644 --- a/es/07-customizing-git/01-chapter7.markdown +++ b/es/07-customizing-git/01-chapter7.markdown @@ -142,7 +142,7 @@ Si lo quieres probar, P4Merge funciona en todas las principales plataformas. Los P4Merge se puede descargar desde: - http://www.perforce.com/perforce/downloads/component.html + http://www.perforce.com/product/components/perforce-visual-merge-and-diff-tools Para empezar, tienes que preparar los correspondientes scripts para lanzar tus comandos. En estos ejemplos, voy a utilizar caminos y nombres Mac para los ejecutables; en otros sistemas, tendrás que sustituirlos por los correspondientes donde tengas instalado 'p4merge'. El primer script a preparar es uno al que denominaremos 'extMerge', para llamar al ejecutable con los correspodientes argumentos: diff --git a/es/omegat-Benzirpi.tmx b/es/omegat-Benzirpi.tmx index f789972d9..95f49f3b2 100644 --- a/es/omegat-Benzirpi.tmx +++ b/es/omegat-Benzirpi.tmx @@ -2369,10 +2369,10 @@ Figura 3-36. - http://www.perforce.com/perforce/downloads/component.html + http://www.perforce.com/product/components/perforce-visual-merge-and-diff-tools - http://www.perforce.com/perforce/downloads/component.html + http://www.perforce.com/product/components/perforce-visual-merge-and-diff-tools @@ -28305,12 +28305,12 @@ Figura 5-21. $ git status # On branch master - nothing to commit (working directory clean) + nothing to commit, working directory clean $ git status # On branch master - nothing to commit (working directory clean) + nothing to commit, working directory clean diff --git a/fa/.gitignore b/fa/.gitignore new file mode 100644 index 000000000..b7cd94167 --- /dev/null +++ b/fa/.gitignore @@ -0,0 +1,2 @@ +.DS_store +.idea \ No newline at end of file diff --git a/fa/01-introduction/01-chapter1.markdown b/fa/01-introduction/01-chapter1.markdown new file mode 100644 index 000000000..f259f012f --- /dev/null +++ b/fa/01-introduction/01-chapter1.markdown @@ -0,0 +1,262 @@ +# سرآغاز # + +در این فصل در رابطه با شروع کار با Git صحبت خواهد شد. این فصل با توضیحاتی در رابطه با تاریخچه ابزارهای کنترل نسخه شروع می‌شود، سپس چگونگی راه اندازی Git برروی یک سیستم خاص آموزش داده خواهد شد و در انتها انجام تنظیمات موردنیاز برروی این نرم افزار جهت شروع به کار با آن مورد بررسی قرار می‌گیرد. در انتهای این فصل خواننده باید دلیل وجود و استفاده از Git را بداند و همچنین باید محیط کار را برای استفاده از آن فراهم کرده باشد. + +## کنترل نسخه ## + +کنترل نسخه چیست و چه اهمیتی دارد؟ کنترل نسخه سیستمی است که تغییرات مربوط به یک یا چندین فایل را در طول زمان ذخیره می‌کند، تا کاربر بتواند به نسخه‌های قبلی مراجعت داشته باشد. در مثال‌های استفاده شده در این کتاب از فایل های سورس نرم افزار جهت نمایش کنترل نسخه استفاده می‌شود، ولی با این وجود می‌توان هر نوع فایلی را تحت کنترل نسخه قرار داد. + +اگر شما یک گرافیست یا طراح وب باشید و تصمیم به نگهداری تمامی نسخه‌های یک عکس یا ساختار را داشته باشید (که قطعًا به همین منوال است)، استفاده از یک سیستم کنترل نسخه (VCS) راهبردی عاقلانه است. یک VCS این امکان را به شما می‌دهد تا: فایل‌ها یا پروژه‌ای را به یک وضعیت قبل برگردانید، تغییرات انجام گرفته در مرور زمان را مشاهده کنید، باعث و بانی تغییری را که منجر به ایجاد خطا یا مشکلی در سیستم شده است بیابید، چه کسی و چه زمانی موردی خاص را مطرح کرده است و بسیاری موارد دیگر. استفاده از یک VCS حتی این امکان را به شما می‌دهد که اگر احیاناً خطایی مرتکب شدید یا فایلی را اشتباهاً حذف یا از دست دادید، به راحتی آن را اصلاح و بازیابی کنید. + +### سیستمهای کنترل نسخه محلی ### + +روشی که اکثر کاربران جهت کنترل نسخه انتخاب می‌کنند شامل کپی کردن فایل‌ها در پوشه‌های دیگر است (البته اگر هوشمندی نشان دهند، پوشه موردنظر را با تاریخ و زمان مشخصی نامگذاری می‌کنند). چنین روشی به جهت سادگی بین کاربران بسیار رایج است، ولی خطاپذیری بالایی نیز دارد. در این روش امکان دارد فرد به آسانی پوشه‌ای که در آن قرار دارد را فراموش کرده و به اشتباه دست به تغییر فایل‌هایی بزند که مدنظر او نیست. + +برای مقابله با این موذل، برنامه نویسان از زمان‌های بسیار قبل اقدام به توسعه VCSها زده‌اند که در بردارنده پایگاه داده ساده‌ای هستند به گونه ای که تمامی تغییرات انجام شده برروی فایل‌های هدف را در قالب کنترل نسخه نگهداری می‌کنند (تصویر 1-1) + +Insert 18333fig0101.png +تصویر 1-1. دیاگرام کنترل نسخه محلی. + +یکی از رایجترین ابزارهای VCS سیستمی با نام rcs بوده است، که هم اکنون نیز به همراه تعداد زیادی از کامپیوترهای امروزی نیز توزیع می‌شود. حتی سیستم عامل رایج Mac OS X نیز با نصب ابزارهای توسعه توسط کاربر برروی آن، دستور خط فرمان rcs را در اختیار فرد قرار می‌دهد. این ابزار به زبانی ساده با حفظ مجموعه‌ای از وصله‌ها (که تغییرات بین فایل‌ها می‌باشند) از یک نسخه به نسخه‌ای دیگر در قالب فرمتی خاص برروی دیسک عمل می‌کند؛ این ابزار با اجرای چنین سیستمی قادر است با متصل کردن وصله‌ها به یکدیگر توانایی بازسازی هر فایلی را در هر لحظه‌ای از زمان داشته باشد. + +### سیستمهای کنترل نسخه‌ مرکزی ### + +مسئله مهم دیگری که کاربران با آن مواجه می‌شوند، نیاز آن‌ها به همکاری با دیگر توسعه‌دهندگان برروی سیستم‌های دیگر است. برای حل این مسئله، سیستم‌های کنترل نسخه مرکزی (CVCSs) توسعه یافتند. چنین سیستم‌هایی مانند CVS، Subversion و Perforce در بردارنده سروری مرکزی هستند که تمامی نسخه‌های فایل‌ها و حتی کاربرانی که این فایل‌ها را از این مکان مرکزی checkout کرده‌اند در خود نگهداری می‌کند. برای سال‌های زیادی، چنین روشی، روشی استاندارد برای کنترل نسخه بوده است (تصویر 1-2). + +Insert 18333fig0102.png +تصویر 1-2. دیاگرام کنترل نسخه مرکزی. + +این ساختار مزایای بسیاری مخصوصاً نسبت به سیستم‌های کنترل نسخه محلی دارد. به عنوان مثال، هر فرد در حد و اندازه مشخصی خواهد توانست بداند که دیگر افراد تا چه اندازه در پروژه شریک هستند. مدیران از این نظر که هرکس از نظر سطح دسترسی قادر به انجام چه کاری است، کنترل مناسبی دارند؛ همچنین مدیریت یک CVCS به مراتب آسانتر از تعامل با پایگاه‌های داده محلی موجود برروی سیستم‌های کاربران است. + +با این وجود، چنین ساختاری معایبی نیز دارد. واضح‌ترین موضوع بروز کوچکترین ایراد در سرورهای مرکزی است. اگر برای مدت یک ساعت این سرور متوقف و از کار بیفتد، در طی این بازه یک ساعته هیچکس نخواهد توانست تعاملی با سرور داشته باشد یا حتی تغییرات نسخه را برروی چیزی که در حال کارکردن با آن است ذخیره کند. اگر هارد دیسکی که پایگاه داده مرکزی برروی آن قرار دارد خراب شود، و پشتیبان مناسبی از آن گرفته نشده باشد، کاربر به طور کامل تاریخچه پروژه را از دست خواهد داد به جز تصاویر لحظه‌ای که هر کاربر احتمالاً برروی ماشین محلی خود خواهد داشت. سیستمهای VCS محلی نیز این عیب را به ارث می‌برند-اگر کاربر تمامی تاریخچه پروژه را در یک مکان ذخیره کند، ریسک از دادن همه چیز به قوت خود باقی خواهد ماند. + +### سیستمهای کنترل نسخه پخشی ### + +اینجا است که سیستم‌های کنترل نسخه پخشی (DVCSs) نمود پیدا می‌کنند. در یک DVCS (مانند Git، Mercurial، Bazaar یا Darcs) کابران به checkout کردن آخرین تصویر لحظه‌ای فایل‌ها اکتفا نمی‌کنند: آن‌ها مخزن را نیز به‌صورت کامل کپی می‌کنند. بنابراین اگر هر سروری که سیستم‌ها به واسطه آن در حال تعامل با یکدیگر هستند متوقف و از کار بیافتد، با کپی مخرن هر کدام از کاربران برروی سرور، عمل بازیابی انجام می‌گیرد. در واقع هر checkoutای، پشتیبان کاملی از تمامی داده‌ها است. + +Insert 18333fig0103.png +تصویر 1-3. دیاگرام کنترل نسخه پخشی. + +علاوه بر آن اکثر این سیستم‌ها تعامل خوبی با داشتن مخازن خارجی متعدد جهت کار کردن با آن‌ها دارند، در نتیجه شخص خواهد توانست با گروه‌های مختلفی در قالب پروژه‌ای یکسان به‌صورت همزمان تعامل داشته باشد. این قابلیت این امکان را به کاربر خواهد داد که جریان‌های کاری متنوعی همانند مدل‌های سلسه مراتبی را پیاده سازی کند که انجام آن در سیستم‌های متمرکز امکان پذیر نیست. + +## تاریخچه کوتاهی از Git ## + +همانند اکثر حوادث بزرگ در در زندگی، Git نیز با خلاقیتی مخرب و جنجالی آتشین شروع شد. هسته لینوکس پروژه نرم‌افزاری متن باز با وسعت نسبتاً زیادی است. جهت نگهداری هسته لینوکس برای مدت زمان زیادی (1991 - 2002) تغییرات نرم‌افزاری به واسطه وصله‌ها و فایل‌های بایگانی شده انتقال پیدا می‌کرد. در سال 2002، پروژه هسته لینوکس شروع به استفاده از سیستم DVCS خصوصی با نام BitKeeper کرد. + +در سال 2005، ارتباط بین مجموعه تیم توسعه دهنده هسته لینوکس و شرکت تجاری توسعه دهنده BitKeeper گسسته شد و وضعیت ابزاری که قبل از آن به صورت رایگان عرضه می‌گشت تغییر پیدا کرد. این اتفاق زنگ هشداری برای مجموعه تیم توسعه دهنده لینوکس (به خصوص مؤسس لینوکس، لینوس تورلوادز) بود که بر اساس تجربه‌های کسب شده در استفاده از BitKeeper، خود اقدام به تولید نرم افزاری در این زمینه بزنند. مواردی از اهداف سیستم جدید عبارت بودند از: + +* سرعت +* طراحی ساده +* پشتیبانی قوی از توسعه غیر خطی (هزاران انشعاب موازی) +* کاملاً پخشی +* قابلیت کنترل بهینه پروژه‌های بزرگ همانند هسته لینوکس (از نظر سرعت و اندازه داده) + +از زمان تولد Git در سال 2005، این نرم افزار از نظر استفاده آسان و حفظ اهداف اولیه ذکر شده به تکامل و بلوغ رسیده است. Git نرم افزاری سریع، بسیار بهینه در مواجه با پروژه‌های بزرگ و حاوی سیستم انشعابی باورنکردنی برای توسعه غیر خطی است (فصل 3). + +## مقدمات Git ## + +خوب، Git چیست؟ این بخش از نظر یادگیری، بخشی مهم قلمداد می شود، زیرا اگر فرد از پایه و اساس عملکرد Git اطلاع پیدا کند، آنگاه خواهد توانست آسان‌تر در استفاده مؤثر از آن بهره جوید. در حین یادگیری Git، بهتر است فرد ذهن خود را از مواردی که احیاناً در رابطه با دیگر VCSها همانند Subversion و Perforce می‌داند تخلیه کند؛ بدین سبب از بروز اشتباهات موردی در استفاده از این ابزار پیشگیری می‌شود. با وجود آن‌که رابط کاربری Git نسبتاً مشابه با دیگر سیستم‌ها است، ولی در ذخیره سازی و نگاه به اطلاعات، دید بسیار متفاوتی در مقایسه با دیگر سیستم‌ها دارد؛ دانستن این تفاوت‌ها می‌تواند به فرد در جلوگیری از بروز اشتباهات بعدی در استفاده از این ابزار یاری دهد. + +### تصاویر لحظه‌ای، نه تفاوتها ### + +اصلی‌ترین تفاوت بین Git و دیگر VCSها (که شامل Subversion و هم خانواده های آن نیز می‌شود) دیدگاهی است که Git نسبت به داده‌های خود دارد. از نظر مفهومی، اکثریت دیگر سیستم‌ها اطلاعات را به مثابه لیستی از تغییرات بر مبنای فایل، ذخیره می‌کنند. این سیستم‌ها (CVS، Subversion، Perfoce، Bazaar و غیره) همان‌طور که در تصویر 1-4 نشان داده شده است، به اطلاعاتی که نگهداری می‌کنند به شکل مجموعه‌ای از فایل‌ها و تغییراتی که برروی هر فایل در مرور زمان انجام گرفته است، می‌نگرند. + + +Insert 18333fig0104.png +تصویر 1-4. دیگر سیستم‌ها داده‌ها به شکل تغییرات در نسخه پایه هر فایل ذخیره می‌کنند. + +سGit از چنین تفکر یا روش ذخیره سازی داده‌ای پیروی نمی‌کند. در عوض دیدگاه Git نسبت به داده‌های خود به شکل تصاویر لحظه‌ای از یک سیستم فایلی کوچک است. هر زمانی که شخص commitای انجام می‌دهد یا وضعیت پروژه خود را در Git ذخیره می‌کند، در اصل تصویری از وضعیت تمامی فایل‌ها در لحظه موردنظر تهیه و ارجاعی به تصویر لحظه‌ای ایجاد شده ذخیره می شود. برای آن‌که این عمل به صورت بهینه انجام پذیرد، اگر در فایلی تغییری ایجاد نشده باشد، Git اقدام به ذخیره سازی مجدد فایل نمی‌کند - تنها پیوندی به نسخه مشابه آن فایل که قبلاً ذخیره شده است را ذخیره می کند. طریقه نگرش Git به داده در تصویر 1-5 نمایش داده شده است. + +Insert 18333fig0105.png +تصویر 1-5. Git داده‌ها را به شکل تصاویر لحظه‌ای از پروژه در مرور زمان نگهداری می‌کند. + +این شکل نگرش مهمترین اصل تمایز Git با دیگر VCSها است. این امر موجب می‌شود تا Git تجدیدنظری نسبت به تمامی ابعاد کنترل نسخه داشته باشد، که اکثریت دیگر سیستم‌ها از نسل‌های قبل از خود به ارث برده‌اند. این موضوع باعث شده است تا Git از یک VCS ساده، به سیستم فایلی کوچکی بدل شود که در بالادست آن ابزار قدرتمند باورنکردنی بنا شده است. در فصل 3 بعضی از مزایای چنین دیدگاهی نسبت به داده، پوشش داده می‌شود. + +### تقریباً تمام عملیات به صورت محلی انجام می‌پذیرد ### + +اکثر عملیاتی که در Git انجام می‌پذیرد جهت اجرا تنها نیازمند فایل‌ها و منابع محلی هستند - به‌طور کلی نیازمند هیچ‌گونه اطلاعاتی از کامپیوتری دیگر در شبکه نیست. اگر شما فردی هستید که به CVCSای عادت کرده‌اید که در آن اکثر فعالیت‌ها دارای افزونگی رکود شبکه‌ای داشته‌اند، شاید این مزیت Git این فکر را برای شما تداعی کند که خدایان سرعت Git را با قدرتی وصف ناشدنی مورد لطف و رحمت قرار داده‌اند. از آن جهت که تمامی تاریخچه پروژه برروی دیسک محلی قرار دارد، به نظر می‌رسد که اکثر عملیات به صورت لحظه‌ای و بلادرنگ انجام می‌پذیرند. + +به عنوان مثال، Git برای نمایش تاریخچه پروژه نیازی جهت مراجعه به سرور برای اخذ تاریخچه و نمایش آن ندارد - Git این عمل را با خواندن مستقیم پایگاه داده محلی انجام می‌دهد. این بدان معناست که شخص می‌تواند تاریخچه پروژه را تقریباً بلادرنگ مشاهده کند. اگر نیاز به مشاهده تغییرات بین نسخه فعلی یک فایل با نسخه یک ماه قبل از آن باشد، Git می‌تواند به‌جای آن‌که از سرور درخواست این عمل را داشته باشد و یا آن‌که نسخه قبلی را از سرور خارجی فراخوانی و سپس مقایسه محلی را انجام دهد، این عمل را با نگاهی به نسخه یک ماه قبل فایل و انجام محاسبات محلی تغییرات رخ داده، انجام می‌دهد. + +همچنین بدین معناست که در صورت آفلاین بودن و یا وصل نبودن به VPN دامنه عملکرد شخص زیاد محدود نمی‌شود. اگر سوار بر هواپیما یا قطار شده باشید و تصمیم به انجام کاری داشته باشید، می‌توانید به راحتی commit را انجام داده و زمانی که دسترسی به شبکه پیدا کردید آپلود را انجام دهید. اگر به خانه رفته باشید و قادر به فعال سازی VPN خود نشده باشید، باز هم وقفه‌ای در کار شما حاصل نمی‌شود. در اکثریت دیگر سیستم‌ها انجام این موارد غیرممکن یا به سختی انجام می‌پذیرد. به عنوان مثال در Perforce، در صورتی که به شبکه متصل نباشید در واقع توانایی انجام کاری نخواهید داشت؛ در Subversion و CVS، امکان دست‌کاری فایل‌ها برای شما وجود دارد، ولی برای commit تغییرات روی پایگاه داده محدودیت دارید (زیرا اتصال شما به پایگاه داده بر قرار نیست). شاید این موضوع مسئله مهمی به نظر نیاید، ولی شاید با مشاهده تفاوت‌های بزرگی که می‌تواند به موجب آن ایجاد شود، شگفت زده شوید. + +### Git صداقت دارد ### + +هرچیزی که بخواهد در Git ذخیره شود، ابتدا checksum آن محاسبه می‌شود و سپس به‌وسیله همین checksum ارجاع داده می‌شود. چنین عملی موجب می‌شود که در صورت ایجاد کوچکترین تغییری در محتویات فایل یا پوشه‌ای، Git از آن آگاهی پیدا کند. این دستورالعمل در Git در پایینترین سطح پیاده‌سازی شده است و تأییدی بر صحت فلسفه Git دارد. بدین دلیل است که اگر داده‌ای در حین انتقال از دست برود و یا فایلی مخدوش شود، Git به سرعت از آن اطلاع پیدا می‌کند. + +مکانیزمی که Git برای تولید checksum استفاده می‌کند، هش SHA-1 است. این هش یک رشته 40 کاراکتری از کاراکترهای مبنای شانزده است (0 - 9 و a - f) که از روی محتویات فایل و یا ساختار پوشه موردنظر در Git محاسبه می‌گردد. در ادامه یک نمونه از هش SHA-1 آورده شده است: + + + 24b9da6552252987aa493b52f8696cd6d3b00373 + +به علت استفاده زیاد Git از این هش، به کرات در جای جای Git مشاهده‌گر این هش‌ها خواهید بود. در واقع، Git از نام فایل برای ذخیره‌سازی آن استفاده نمی‌کند بلکه Git از هش تولید شده از محتویات فایل مربوطه برای آدرس دهی آن در پایگاه داده خود بهره می‌گیرد. + +### عموماً Git فقط داده اضافه میکند ### + +هرگاه عملی در Git انجام می‌پذیرد، تقریباً در تمامی موارد Git داده‌ای به داده‌های خود در پایگاه داده اضافه می‌کند. انجام دادن عملی در این سیستم که برگشت‌پذیر نباشد یا باعث حذف داده ای از سیستم شود، بسیار سخت است. مشابه اکثر VCSها، فرد می‌تواند تا قبل از commit هرگونه تغییراتی را انجام دهد؛ ولی به محض commit یک تصویر لحظه‌ای در Git، امکان حذف آن بسیار سخت است، مخصوصاً اگر فرد عادتاً پایگاه داده خود را به مخزن دیگری push کند. + +این قابلیت باعث می‌شود که استفاده از Git، به عملی فرح بخش تبدیل شود زیرا فرد خواهد توانست بدون در خطر انداختن چیزی دست به هرگونه آزمایشی بزند. برای آشنایی بیشتر با چگونگی ذخیره‌سازی و بازیابی داده‌ها در Git که به نظر از دست رفته می‌باشند، می‌توانید به فصل 9 مراجعه کنید. + +### سه وضعیت ### + +توجه، توجه. اگر می‌خواهید پروسه یادگیری Git را بدون دردسر ادامه دهید، این بخش را به دقت مطالعه کنید. فایلها در Git می‌توانند در سه وضعیت اصلی قرار داشته باشند: committed، modified و staged. committed بدین معناست که فایل موردنظر در پایگاه داده محلی ذخیره شده است. modified یعنی تغییری در فایل ایجاد شده است ولی هنوز commitای از این فایل روی پایگاه داده انجام نگرفته است. فایلی که در وضعیت staged قرار گرفته است، فایلی تغییر یافته است که نسخه فعلی آن در تصویر لحظه‌ای بعدی جهت commit نشانه‌گذاری شده است. + +حال می‌توان سه بخش اصلی پروژه Git را معرفی کرد: پوشه Git، پوشه در حال کار (working directory) و staging area. + +Insert 18333fig0106.png +تصویر 1-6. پوشه در حال کار، staging area و پوشه Git + +در Git، metadata و پایگاه داده پروژه در پوشه Git ذخیره می‌شوند. این قسمت مهمترین بخش Git است، در واقع هنگامی که از مخزن کامپیوتری cloneای گرفته می‌شود، کپی از این پوشه ایجاد می‌گردد. + +پوشه در حال کار، checkout منفردی از نسخه‌ای از پروژه است. فایل‌های این بخش، فایل‌هایی می‌باشند که از پایگاه داده فشرده واقع در پوشه Git بیرون کشیده شده و جهت استفاده و ایجاد تغییر بر روی دیسک قرار داده شده‌اند. + +staging area عموماً از یک فایل ساده تشکیل شده است که محتوی اطلاعاتی است که مشخص می‌کند که چه چیزهایی در commit بعدی قرار می‌گیرند. معمولاً این فایل را index می‌نامند ولی عبارت staging area نیز در حال تبدیل شدن به نامی استاندارد برای چنین فایلی است. + +روند کاری Git عموماً به صورت ذیل است: + +1. ایجاد تغییرات روی فایل‌های واقع در پوشه در حال کار. +2. stage کردن فایل‌ها و اضافه کردن تصاویر لحظه‌ای فایلها به staging area. +3. commit کردن، که به موجب آن وضعیت فعلی فایل‌ها در staging area تحت یک تصویر لحظه‌ای به صورت دائمی در پوشه Git ذخیره می‌گردد. + +اگر نسخه‌ای از یک فایل در پوشه git قرار داشته باشد، commit شده فرض می‌شود. اگر تغییری در فایل ایجاد شده باشد و به staging area اضافه شده باشد، گوییم staged شده است. و اگر در فایل از آخرین مرتبه‌ای که checkout شده است تغییری ایجاد شده باشد ولی staged نشده باشد، گوییم modified شده است. در فصل 2، با این وضعیت‌ها بیشتر آشنا خواهید شد و یاد خواهید گرفت که چگونه می‌توان از آن‌ها به نحو احسنت استفاده کرد و یا حتی به صورت کامل از روی مرحله stage پرش کرد. + +## نصب Git ## + +حال وقت آن است که کار با Git را شروع کنیم. اول از هر چیز می‌بایست Git را نصب کرد. روشهای مختلفی برای این کار وجود دارد؛ دو مورد از رایج‌ترین این روش‌ها نصب از طریق سورس یا نصب به واسطه بسته‌های موجودی است که برای پلتفرم موردنظر شما تهیه شده است. + +### نصب از طریق سورس ### + +اگر امکان نصب از طریق سورس برای شما وجود دارد، این روش مناسب‌ترین روش جهت نصب می‌باشد، زیرا شما بعد از نصب آخرین نسخه نرم‌افزار را در اختیار خواهید داشت. در هر نسخه از Git سعی شده است که تا در رابط کاربری بهبودهایی حاصل شود، بنابراین در اختیار داشتن آخرین نسخه بهترین گزینه است البته اگر با کامپایل سورس نرم‌افزار مشکلی نداشته باشید. همچنین معمولاً مخازن نرم افزاری اکثر توزیعهای لینوکس دربردارنده بسته‌هایی با نسخه‌های قدیمی هستند؛ بنابراین در صورتی که شما توسعه دهنده‌ای به روز هستید یا از backportها استفاده می‌کنید، نصب از طریق سورس بهترین انتخاب برای شما است. + +برای نصب Git نیاز به کتابخانه های curl، zlib، openssl، expat و libiconv است که Git نیازمند آنهاست. به عنوان مثال، اگر روی سیستمی کار می‌کنید که yum (مانند Fedora) یا apt-get (مانند سیستم های مبتنی بر Debian) دارد، می‌توانید برای نصب این بسته‌های نیازمندی از دستورهای ذیل استفاده کنید: + + $ yum install curl-devel expat-devel gettext-devel \ + openssl-devel zlib-devel + + $ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \ + libz-dev libssl-dev + +حال که تمامی نیازمندی‌ها نصب گردید، می‌توان آخرین نسخه Git را از وب سایت آن دانلود کرد: + + http://git-scm.com/download + +و آن را کامپایل و نصب نمود: + + $ tar -zxf git-1.7.2.2.tar.gz + $ cd git-1.7.2.2 + $ make prefix=/usr/local all + $ sudo make prefix=/usr/local install + +بعد از کامل شدن این مراحل می‌توان از خود Git برای دریافت آپدیت‌های Git استفاده کرد: + + $ git clone git://git.kernel.org/pub/scm/git/git.git + +### نصب بر روی لینوکس ### + +اگر قصد نصب Git بر روی لینوکس به واسطه یک نصاب باینری را دارید، می‌توانید این کار را از طریق ابزار مدیریت بسته های نرم‌افزاری که همراه توزیع موردنظر شما ارائه می‌شود انجام دهید. اگر توزیع شما Fedora است، می‌توانید از yum استفاده کنید: + + $ yum install git-core + +یا اگر توزیعی مبتنی بر Debian مانند Ubuntu دارید، می‌توانید از apt-get استفاده کنید: + + $ apt-get install git + +### نصب برروی Mac ### + +برای نصب برروی Mac دو روش آسان وجود دارد. آسان‌ترین روش استفاده از نصاب گرافیکی Git است، که امکان دانلود آن از صفحه Google Code وجود دارد (تصویر 1-7): + + http://code.google.com/p/git-osx-installer + +Insert 18333fig0107.png +تصویر 1-7. نصاب Git OS X + +روش دیگر نصب از طریق MacPortها (`http://www.macports.org`) است. اگر MacPortها را نصب شده روی سیستم خود دارید، می‌توانید Git را با دستور ذیل نصب کنید + + $ sudo port install git-core +svn +doc +bash_completion +gitweb + +نیازی به افزودن تمامی اضافات نیست، ولی شاید برای استفاده از Git به همراه مخازن Subversion، احتمالاً افزودن +svn گزینه مناسبی است. + +### نصب بر روی ویندوز ### + +نصب Git روی ویندوز بسیار آسان است. پروژه msysGit یکی از آسان‌ترین مراحل نصب را دارد. تنها نیاز است که فایل نصاب exe را از صفحه GitHub دانلود، و آن را اجرا کرد: + + http://msysgit.github.com/ + +بعد از اتمام نصب، هم نسخه خط فرمان (شامل SSH client که در ادامه مشاهده خواهد شد که ابزاری کارآمد است) و هم رابط گرافیکی استاندارد را در اختیار خواهید داشت. + +نکته برای کابران ویندوز: کاربر باید جهت کار با Git از پوسته ارائه شده به همراه msysGit (به سبک Unix) استفاده کند، تا بتواند دستورات چند خطی پیچیده‌ای که در این کتاب آورده شده را اجرا کند. اگر به هر دلیلی، نیاز به استفاده از پوسته خود ویندوز/کنسول خط فرمان، شدید باید در عوض تک کوت (simple quote) از دابل کوت (برای پارامترهایی که در بر دارنده فاصله هستند) استفاده کنید و باید پارامترهای موجود در آخرین خط که با circumflex accent (^) به پایان می‌رسند را داخل کوت قرار دهید، زیرا این علامت، نشانگر ادامه دار بودن خط در ویندوز است. + +## تنظیمات شروع به کار Git ## + +حال که Git روی سیستم نصب شده است، نیاز به شخصی‌سازی بعضی از منابع Git است. انجام این تنظیمات فقط برای یک مرتبه انجام می‌پذیرد؛ و بعد از آن با هر بار ارتقاء بدون تغییر باقی می‌مانند. همچنین امکان تغییر آن‌ها در هر زمانی که نیاز باشد به کمک خط فرمان وجود دارد. + +به همراه Git ابزاری ارائه شده است با نام git config که امکان خواندن و اعمال متغیرهای تنظیماتی که تمامی ابعاد ظاهری و عملیاتی Git را کنترل می‌کند فراهم می‌سازد. + +* فایل `/etc/gitconfig`: حاوی مقادیر تمامی کاربران سیستم و مخازن آن‌ها است. اگر به همراه `git config` از گزینه `--system` استفاده شود، خواندن و نوشتن به صورت اختصاصی از این فایل انجام می‌پذیرد. +* فایل `~/.gitconfig`: مختص کاربر مشخصی است. با استفاده از گزینه `--global` خواندن و نوشتن Git به صورت اختصاصی از این فایل انجام می‌پذیرد. +* فایل config موجود در پوشه git (`.git/config`) یا هر مخزنی که در حال استفاده از آن می‌باشید: مختص یک مخزن خاص است. مقادیر هر سطح باعث لغو مقادیر سطح قبلی خود می‌شود. بنابراین مقادیر `.git/config` موجب لغو مقادیر `/etc/gitconfig` خواهد شد. + +در سیستم‌های ویندوزی، Git در پوشه `$HOME` (متغیر محیطی `%USERPROFILE%` در ویندوز) که برای اکثر کاربران با توجه به نسخه سیستم در مسیرهای `C:\Documents and Settings\$USER‍ یا `C:\Users\$USER` (`$USER‍ در ویندوز متغیر محیطی `%USERNAME%`) قرار دارد، فایل `.gitconfig` را جستجو می‌کند. همچنین نسبت به مسیر ریشه MSys که همان مسیر نصب انتخاب شده در هنگام اجرای نصاب Git در ویندوز می‌باشد، به دنبال فایلی با نام /etc/gitconfig می‌گردد. + +### شناسه کاربر ### + +اولین عملی که بعد از نصب Git باید انجام شود، مقداردهی دو متغیر نام کاربری (user name) و آدرس پست الکترونیکی (e-mail address) است. این عمل از آن جهت اهمیت دارد که در هر commit این اطلاعات به‌صورتی تغییر ناپذیر روی commit انجام شده حک می‌شوند. + + $ git config --global user.name "John Doe" + $ git config --global user.email johndoe@example.com + +مجدداً یادآوری می‌شود که انجام این عمل در صورت استفاده از گزینه `--global` فقط یک مرتبه انجام می‌پذیرد، زیرا Git برای هر عملی که در سیستم انجام می‌پذیرد از این اطلاعات استفاده می‌کند. حال اگر فرد نیاز به استفاده از نام و آدرس پست الکترونیکی متفاوتی برای پروژه‌های خاصی دارد، می‌تواند با اجرای همان دستورات البته بدون استفاده از گزینه `--global` هنگامی که در مسیر پروژه مذکور قرار دارد به مقصود خود دست یابد. + +### ویرایشگر کاربر ### + +حال که شناسه تنظیم شد، می‌توان ویرایشگر متن پیش فرضی را معرفی کرد تا هنگامی که نیاز به درج پیغامی در Git است فراخوانی شود. به صورت پیش فرض Git از ویرایشگر پیش فرض سیستم برای این امر استفاده می کند، که معمولاً Vi یا Vim است. اگر نظر شخص به استفاده از ویرایشگر متنی متفاوتی مانند Emacs باشد، می‌توان به صورت ذیل عمل کرد: + + $ git config --global core.editor emacs + +### ابزار Diff ### + +ابزار مفید دیگری که شاید نیاز به تنظیم داشته باشد، ابزار diff پیش فرضی است که برای رفع مغایرت ایجاد شده در هنگام اجرای دستور merge استفاده می‌گردد. به عنوان مثال اگر هدف استفاده از vimdiff باشد خواهیم داشت: + + $ git config --global merge.tool vimdiff + +سGit از ابزارهای kdiff3، tkdiff، meld، xxdiff، emerge، vimdiff، gvimdiff، ecmerge و opendiff جهت merge پشتیبانی می‌کند. با این وجود امکان تعریف ابزاری شخصی نیز وجود دارد؛ برای اطلاعات بیشتر جهت انجام این مورد می‌توانید به فصل 7 مراجعه کنید. + +### بررسی تنظیمات ### + +برای مشاهده و بررسی تنظیمات، می‌توان از دستور `git config --list` استفاده کرد که در نتیجه آن Git تمامی تنظیمات موجود تا آن لحظه را در قالب لیستی نمایش می‌دهد: + + $ git config --list + user.name=Scott Chacon + user.email=schacon@gmail.com + color.status=auto + color.branch=auto + color.interactive=auto + color.diff=auto + ... + +احتمال دارد در این لیست کلیدهایی بیش از یک بار مشاهده شوند، دلیل این امر آن است که Git کلید مشابهی را از فایل‌های مختلفی (مانند `/etc/giconfig` و `~/.gitconfig`) خوانده است. در این‌گونه موارد، Git آخرین مقدار کلید منحصر به فردی که مشاهده می‌کند را جهت استفاده به‌کار می‌گیرد. + +همچنین برای مشاهده مقدار مورد استفاده یک کلید خاص توسط Git، می‌توان از دستور `git config {key}` استفاده کرد: + + $ git config user.name + Scott Chacon + +## دریافت راهنمایی ## + +هرگاه در استفاده از Git نیازمند راهنمایی بودید، سه روش برای مشاهده صفحه راهنما هرگونه دستوری در Git وجود دارد: + + $ git help + $ git --help + $ man git- + +برای مثال، برای مشاهده صفحه راهنما دستور config داریم + + $ git help config + +این دستورات از آن جهت که می‌توان از هر مکانی، حتی در حالت آفلاین، به آن‌ها دسترسی پیدا کرد ابزاری کاربردی می‌باشند. +اگر صفحات راهنما و این کتاب جوابگوی نیاز شما نبودند و نیاز به راهنمایی فردی پیدا کردید، میتوانید به کانالهای `#git` یا `#github` در سرور Freenode IRC (irc.freenode.net) مراجعه کنید. +معمولاً این کانال‌ها مملؤ از افرادی با سطح دانش بالا در زمینه Git هستند که آماده راهنمایی رساندن به شما می‌باشند. + +## خلاصه ## + +با مطالعه این فصل شما باید درک اولیه‌ای از این که Git چیست و چه تفاوتی با دیگر CVCSهایی که احتمالاً از آن استفاده می‌کردید دارد پیدا کرده باشد. همچنین شما باید نسخه آماده به کاری از Git را روی سیستم خود داشته باشید که شناسه شخصی شما برروی آن تنظیم شده است. حال زمان یادگیری اصول اولیه Git است. diff --git a/fa/03-git-branching/01-chapter3.markdown b/fa/03-git-branching/01-chapter3.markdown new file mode 100644 index 000000000..f5e2663bd --- /dev/null +++ b/fa/03-git-branching/01-chapter3.markdown @@ -0,0 +1,608 @@ +# Git Branching # + +تقریبا تمام انواع VCS نوعی از انشعاب را پشتیبانی میکنند. + +Nearly every VCS has some form of branching support. Branching means you diverge from the main line of development and continue to do work without messing with that main line. In many VCS tools, this is a somewhat expensive process, often requiring you to create a new copy of your source code directory, which can take a long time for large projects. + +Some people refer to the branching model in Git as its “killer feature” , and it certainly sets Git apart in the VCS community. Why is it so special? The way Git branches is incredibly lightweight, making branching operations nearly instantaneous and switching back and forth between branches generally just as fast. Unlike many other VCSs, Git encourages a workflow that branches and merges often, even multiple times in a day. Understanding and mastering this feature gives you a powerful and unique tool and can literally change the way that you develop. + +## What a Branch Is ## + +To really understand the way Git does branching, we need to take a step back and examine how Git stores its data. As you may remember from Chapter 1, Git doesn’t store data as a series of changesets or deltas, but instead as a series of snapshots. + +When you commit in Git, Git stores a commit object that contains a pointer to the snapshot of the content you staged, the author and message metadata, and zero or more pointers to the commit or commits that were the direct parents of this commit: zero parents for the first commit, one parent for a normal commit, and multiple parents for a commit that results from a merge of two or more branches. + +To visualize this, let’s assume that you have a directory containing three files, and you stage them all and commit. Staging the files checksums each one (the SHA-1 hash we mentioned in Chapter 1), stores that version of the file in the Git repository (Git refers to them as blobs), and adds that checksum to the staging area: + + $ git add README test.rb LICENSE + $ git commit -m 'initial commit of my project' + +Running `git commit` checksums all project directories and stores them as `tree` objects in the Git repository. Git then creates a `commit` object that has the metadata and a pointer to the root project `tree` object so it can re-create that snapshot when needed. + +Your Git repository now contains five objects: one blob for the contents of each of your three files, one tree that lists the contents of the directory and specifies which file names are stored as which blobs, and one commit with the pointer to that root tree and all the commit metadata. Conceptually, the data in your Git repository looks something like Figure 3-1. + +Insert 18333fig0301.png +Figure 3-1. Single commit repository data. + +If you make some changes and commit again, the next commit stores a pointer to the commit that came immediately before it. After two more commits, your history might look something like Figure 3-2. + +Insert 18333fig0302.png +Figure 3-2. Git object data for multiple commits. + +A branch in Git is simply a lightweight movable pointer to one of these commits. The default branch name in Git is master. As you initially make commits, you’re given a `master` branch that points to the last commit you made. Every time you commit, it moves forward automatically. + +Insert 18333fig0303.png +Figure 3-3. Branch pointing into the commit data’s history. + +What happens if you create a new branch? Well, doing so creates a new pointer for you to move around. Let’s say you create a new branch called testing. You do this with the `git branch` command: + + $ git branch testing + +This creates a new pointer at the same commit you’re currently on (see Figure 3-4). + +Insert 18333fig0304.png +Figure 3-4. Multiple branches pointing into the commit’s data history. + +How does Git know what branch you’re currently on? It keeps a special pointer called HEAD. Note that this is a lot different than the concept of HEAD in other VCSs you may be used to, such as Subversion or CVS. In Git, this is a pointer to the local branch you’re currently on. In this case, you’re still on master. The `git branch` command only created a new branch — it didn’t switch to that branch (see Figure 3-5). + +Insert 18333fig0305.png +Figure 3-5. HEAD file pointing to the branch you’re on. + +To switch to an existing branch, you run the `git checkout` command. Let’s switch to the new testing branch: + + $ git checkout testing + +This moves HEAD to point to the testing branch (see Figure 3-6). + +Insert 18333fig0306.png +Figure 3-6. HEAD points to another branch when you switch branches. + +What is the significance of that? Well, let’s do another commit: + + $ vim test.rb + $ git commit -a -m 'made a change' + +Figure 3-7 illustrates the result. + +Insert 18333fig0307.png +Figure 3-7. The branch that HEAD points to moves forward with each commit. + +This is interesting, because now your testing branch has moved forward, but your `master` branch still points to the commit you were on when you ran `git checkout` to switch branches. Let’s switch back to the `master` branch: + + $ git checkout master + +Figure 3-8 shows the result. + +Insert 18333fig0308.png +Figure 3-8. HEAD moves to another branch on a checkout. + +That command did two things. It moved the HEAD pointer back to point to the `master` branch, and it reverted the files in your working directory back to the snapshot that `master` points to. This also means the changes you make from this point forward will diverge from an older version of the project. It essentially rewinds the work you’ve done in your testing branch temporarily so you can go in a different direction. + +Let’s make a few changes and commit again: + + $ vim test.rb + $ git commit -a -m 'made other changes' + +Now your project history has diverged (see Figure 3-9). You created and switched to a branch, did some work on it, and then switched back to your main branch and did other work. Both of those changes are isolated in separate branches: you can switch back and forth between the branches and merge them together when you’re ready. And you did all that with simple `branch` and `checkout` commands. + +Insert 18333fig0309.png +Figure 3-9. The branch histories have diverged. + +Because a branch in Git is in actuality a simple file that contains the 40 character SHA-1 checksum of the commit it points to, branches are cheap to create and destroy. Creating a new branch is as quick and simple as writing 41 bytes to a file (40 characters and a newline). + +This is in sharp contrast to the way most VCS tools branch, which involves copying all of the project’s files into a second directory. This can take several seconds or even minutes, depending on the size of the project, whereas in Git the process is always instantaneous. Also, because we’re recording the parents when we commit, finding a proper merge base for merging is automatically done for us and is generally very easy to do. These features help encourage developers to create and use branches often. + +Let’s see why you should do so. + +## Basic Branching and Merging ## + +Let’s go through a simple example of branching and merging with a workflow that you might use in the real world. You’ll follow these steps: + +1. Do work on a web site. +2. Create a branch for a new story you’re working on. +3. Do some work in that branch. + +At this stage, you’ll receive a call that another issue is critical and you need a hotfix. You’ll do the following: + +1. Switch back to your production branch. +2. Create a branch to add the hotfix. +3. After it’s tested, merge the hotfix branch, and push to production. +4. Switch back to your original story and continue working. + +### Basic Branching ### + +First, let’s say you’re working on your project and have a couple of commits already (see Figure 3-10). + +Insert 18333fig0310.png +Figure 3-10. A short and simple commit history. + +You’ve decided that you’re going to work on issue #53 in whatever issue-tracking system your company uses. To be clear, Git isn’t tied into any particular issue-tracking system; but because issue #53 is a focused topic that you want to work on, you’ll create a new branch in which to work. To create a branch and switch to it at the same time, you can run the `git checkout` command with the `-b` switch: + + $ git checkout -b iss53 + Switched to a new branch 'iss53' + +This is shorthand for: + + $ git branch iss53 + $ git checkout iss53 + +Figure 3-11 illustrates the result. + +Insert 18333fig0311.png +Figure 3-11. Creating a new branch pointer. + +You work on your web site and do some commits. Doing so moves the `iss53` branch forward, because you have it checked out (that is, your HEAD is pointing to it; see Figure 3-12): + + $ vim index.html + $ git commit -a -m 'added a new footer [issue 53]' + +Insert 18333fig0312.png +Figure 3-12. The iss53 branch has moved forward with your work. + +Now you get the call that there is an issue with the web site, and you need to fix it immediately. With Git, you don’t have to deploy your fix along with the `iss53` changes you’ve made, and you don’t have to put a lot of effort into reverting those changes before you can work on applying your fix to what is in production. All you have to do is switch back to your master branch. + +However, before you do that, note that if your working directory or staging area has uncommitted changes that conflict with the branch you’re checking out, Git won’t let you switch branches. It’s best to have a clean working state when you switch branches. There are ways to get around this (namely, stashing and commit amending) that we’ll cover later. For now, you’ve committed all your changes, so you can switch back to your master branch: + + $ git checkout master + Switched to branch 'master' + +At this point, your project working directory is exactly the way it was before you started working on issue #53, and you can concentrate on your hotfix. This is an important point to remember: Git resets your working directory to look like the snapshot of the commit that the branch you check out points to. It adds, removes, and modifies files automatically to make sure your working copy is what the branch looked like on your last commit to it. + +Next, you have a hotfix to make. Let’s create a hotfix branch on which to work until it’s completed (see Figure 3-13): + + $ git checkout -b hotfix + Switched to a new branch 'hotfix' + $ vim index.html + $ git commit -a -m 'fixed the broken email address' + [hotfix 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. + +You can run your tests, make sure the hotfix is what you want, and merge it back into your master branch to deploy to production. You do this with the `git merge` command: + + $ git checkout master + $ git merge hotfix + Updating f42c576..3a0874c + Fast-forward + README | 1 - + 1 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". + +Your change is now in the snapshot of the commit pointed to by the `master` branch, and you can deploy your change (see Figure 3-14). + +Insert 18333fig0314.png +Figure 3-14. Your master branch points to the same place as your hotfix branch after the merge. + +After your super-important fix is deployed, you’re ready to switch back to the work you were doing before you were interrupted. However, first you’ll delete the `hotfix` branch, because you no longer need it — the `master` branch points at the same place. You can delete it with the `-d` option to `git branch`: + + $ git branch -d hotfix + Deleted branch hotfix (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' + $ vim index.html + $ git commit -a -m 'finished the new footer [issue 53]' + [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. + +It’s worth noting here that the work you did in your `hotfix` branch is not contained in the files in your `iss53` branch. If you need to pull it in, you can merge your `master` branch into your `iss53` branch by running `git merge master`, or you can wait to integrate those changes until you decide to pull the `iss53` branch back into `master` later. + +### Basic Merging ### + +Suppose you’ve decided that your issue #53 work is complete and ready to be merged into your `master` branch. In order to do that, you’ll merge in your `iss53` branch, much like you merged in your `hotfix` branch earlier. All you have to do is check out the branch you wish to merge into and then run the `git merge` command: + + $ git checkout master + $ git merge iss53 + 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. + +Insert 18333fig0316.png +Figure 3-16. Git automatically identifies the best common-ancestor merge base for branch merging. + +Instead of just moving the branch pointer forward, Git creates a new snapshot that results from this three-way merge and automatically creates a new commit that points to it (see Figure 3-17). This is referred to as a merge commit and is special in that it has more than one parent. + +It’s worth pointing out that Git determines the best common ancestor to use for its merge base; this is different than CVS or Subversion (before version 1.5), where the developer doing the merge has to figure out the best merge base for themselves. This makes merging a heck of a lot easier in Git than in these other systems. + +Insert 18333fig0317.png +Figure 3-17. Git automatically creates a new commit object that contains the merged work. + +Now that your work is merged in, you have no further need for the `iss53` branch. You can delete it and then manually close the ticket in your ticket-tracking system: + + $ git branch -d iss53 + +### Basic Merge Conflicts ### + +Occasionally, this process doesn’t go smoothly. If you changed the same part of the same file differently in the two branches you’re merging together, Git won’t be able to merge them cleanly. If your fix for issue #53 modified the same part of a file as the `hotfix`, you’ll get a merge conflict that looks something like this: + + $ git merge iss53 + Auto-merging index.html + CONFLICT (content): Merge conflict in index.html + Automatic merge failed; fix conflicts and then commit the result. + +Git hasn’t automatically created a new merge commit. It has paused the process while you resolve the conflict. If you want to see which files are unmerged at any point after a merge conflict, you can run `git status`: + + $ 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 + + ======= + + >>>>>>> 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: + + + +This resolution has a little of each section, and I’ve fully removed the `<<<<<<<`, `=======`, and `>>>>>>>` lines. After you’ve resolved each of these sections in each conflicted file, run `git add` on each file to mark it as resolved. Staging the file marks it as resolved in Git. +If you want to use a graphical tool to resolve these issues, you can run `git mergetool`, which fires up an appropriate visual merge tool and walks you through the conflicts: + + $ git mergetool + + 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 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 “... one of the following tools:”. Type the name of the tool you’d rather use. In Chapter 7, we’ll discuss how you can change this default value for your environment. + +After you exit the merge tool, Git asks you if the merge was successful. If you tell the script that it was, it stages the file to mark it as resolved for you. + +You can run `git status` again to verify that all conflicts have been resolved: + + $ git status + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + modified: index.html + + +If you’re happy with that, and you verify that everything that had conflicts has been staged, you can type `git commit` to finalize the merge commit. The commit message by default looks something like this: + + Merge branch 'iss53' + + Conflicts: + index.html + # + # It looks like you may be committing a merge. + # If this is not correct, please remove the file + # .git/MERGE_HEAD + # and try again. + # + +You can modify that message with details about how you resolved the merge if you think it would be helpful to others looking at this merge in the future — why you did what you did, if it’s not obvious. + +## Branch Management ## + +Now that you’ve created, merged, and deleted some branches, let’s look at some branch-management tools that will come in handy when you begin using branches all the time. + +The `git branch` command does more than just create and delete branches. If you run it with no arguments, you get a simple listing of your current branches: + + $ git branch + iss53 + * master + testing + +Notice the `*` character that prefixes the `master` branch: it indicates the branch that you currently have checked out. This means that if you commit at this point, the `master` branch will be moved forward with your new work. To see the last commit on each branch, you can run `git branch -v`: + + $ git branch -v + iss53 93b412c fix javascript issue + * master 7a98805 Merge branch 'iss53' + testing 782fd34 add scott to the author list in the readmes + +Another useful option to figure out what state your branches are in is to filter this list to branches that you have or have not yet merged into the branch you’re currently on. There are useful `--merged` and `--no-merged` options available in Git for this purpose. To see which branches are already merged into the branch you’re on, you can run `git branch --merged`: + + $ git branch --merged + iss53 + * master + +Because you already merged in `iss53` earlier, you see it in your list. Branches on this list without the `*` in front of them are generally fine to delete with `git branch -d`; you’ve already incorporated their work into another branch, so you’re not going to lose anything. + +To see all the branches that contain work you haven’t yet merged in, you can run `git branch --no-merged`: + + $ git branch --no-merged + testing + +This shows your other branch. Because it contains work that isn’t merged in yet, trying to delete it with `git branch -d` will fail: + + $ git branch -d testing + error: The branch 'testing' is not 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. + +## Branching Workflows ## + +Now that you have the basics of branching and merging down, what can or should you do with them? In this section, we’ll cover some common workflows that this lightweight branching makes possible, so you can decide if you would like to incorporate it into your own development cycle. + +### Long-Running Branches ### + +Because Git uses a simple three-way merge, merging from one branch into another multiple times over a long period is generally easy to do. This means you can have several branches that are always open and that you use for different stages of your development cycle; you can merge regularly from some of them into others. + +Many Git developers have a workflow that embraces this approach, such as having only code that is entirely stable in their `master` branch — possibly only code that has been or will be released. They have another parallel branch named develop or next that they work from or use to test stability — it isn’t necessarily always stable, but whenever it gets to a stable state, it can be merged into `master`. It’s used to pull in topic branches (short-lived branches, like your earlier `iss53` branch) when they’re ready, to make sure they pass all the tests and don’t introduce bugs. + +In reality, we’re talking about pointers moving up the line of commits you’re making. The stable branches are farther down the line in your commit history, and the bleeding-edge branches are farther up the history (see Figure 3-18). + +Insert 18333fig0318.png +Figure 3-18. More stable branches are generally farther down the commit history. + +It’s generally easier to think about them as work silos, where sets of commits graduate to a more stable silo when they’re fully tested (see Figure 3-19). + +Insert 18333fig0319.png +Figure 3-19. It may be helpful to think of your branches as silos. + +You can keep doing this for several levels of stability. Some larger projects also have a `proposed` or `pu` (proposed updates) branch that has integrated branches that may not be ready to go into the `next` or `master` branch. The idea is that your branches are at various levels of stability; when they reach a more stable level, they’re merged into the branch above them. +Again, having multiple long-running branches isn’t necessary, but it’s often helpful, especially when you’re dealing with very large or complex projects. + +### Topic Branches ### + +Topic branches, however, are useful in projects of any size. A topic branch is a short-lived branch that you create and use for a single particular feature or related work. This is something you’ve likely never done with a VCS before because it’s generally too expensive to create and merge branches. But in Git it’s common to create, work on, merge, and delete branches several times a day. + +You saw this in the last section with the `iss53` and `hotfix` branches you created. You did a few commits on them and deleted them directly after merging them into your main branch. This technique allows you to context-switch quickly and completely — because your work is separated into silos where all the changes in that branch have to do with that topic, it’s easier to see what has happened during code review and such. You can keep the changes there for minutes, days, or months, and merge them in when they’re ready, regardless of the order in which they were created or worked on. + +Consider an example of doing some work (on `master`), branching off for an issue (`iss91`), working on it for a bit, branching off the second branch to try another way of handling the same thing (`iss91v2`), going back to your master branch and working there for a while, and then branching off there to do some work that you’re not sure is a good idea (`dumbidea` branch). Your commit history will look something like Figure 3-20. + +Insert 18333fig0320.png +Figure 3-20. Your commit history with multiple topic branches. + +Now, let’s say you decide you like the second solution to your issue best (`iss91v2`); and you showed the `dumbidea` branch to your coworkers, and it turns out to be genius. You can throw away the original `iss91` branch (losing commits C5 and C6) and merge in the other two. Your history then looks like Figure 3-21. + +Insert 18333fig0321.png +Figure 3-21. Your history after merging in dumbidea and iss91v2. + +It’s important to remember when you’re doing all this that these branches are completely local. When you’re branching and merging, everything is being done only in your Git repository — no server communication is happening. + +## Remote Branches ## + +Remote branches are references to the state of branches on your remote repositories. They’re local branches that you can’t move; they’re moved automatically whenever you do any network communication. Remote branches act as bookmarks to remind you where the branches on your remote repositories were the last time you connected to them. + +They take the form `(remote)/(branch)`. For instance, if you wanted to see what the `master` branch on your `origin` remote looked like as of the last time you communicated with it, you would check the `origin/master` branch. If you were working on an issue with a partner and they pushed up an `iss53` branch, you might have your own local `iss53` branch; but the branch on the server would point to the commit at `origin/iss53`. + +This may be a bit confusing, so let’s look at an example. Let’s say you have a Git server on your network at `git.ourcompany.com`. If you clone from this, Git automatically names it `origin` for you, pulls down all its data, creates a pointer to where its `master` branch is, and names it `origin/master` locally; and you can’t move it. Git also gives you your own `master` branch starting at the same place as origin’s `master` branch, so you have something to work from (see Figure 3-22). + +Insert 18333fig0322.png +Figure 3-22. A Git clone gives you your own master branch and origin/master pointing to origin’s master branch. + +If you do some work on your local master branch, and, in the meantime, someone else pushes to `git.ourcompany.com` and updates its master branch, then your histories move forward differently. Also, as long as you stay out of contact with your origin server, your `origin/master` pointer doesn’t move (see Figure 3-23). + +Insert 18333fig0323.png +Figure 3-23. Working locally and having someone push to your remote server makes each history move forward differently. + +To synchronize your work, you run a `git fetch origin` command. This command looks up which server origin is (in this case, it’s `git.ourcompany.com`), fetches any data from it that you don’t yet have, and updates your local database, moving your `origin/master` pointer to its new, more up-to-date position (see Figure 3-24). + +Insert 18333fig0324.png +Figure 3-24. The `git fetch` command updates your remote references. + +To demonstrate having multiple remote servers and what remote branches for those remote projects look like, let’s assume you have another internal Git server that is used only for development by one of your sprint teams. This server is at `git.team1.ourcompany.com`. You can add it as a new remote reference to the project you’re currently working on by running the `git remote add` command as we covered in Chapter 2. Name this remote `teamone`, which will be your shortname for that whole URL (see Figure 3-25). + +Insert 18333fig0325.png +Figure 3-25. Adding another server as a remote. + +Now, you can run `git fetch teamone` to fetch everything the remote `teamone` server has that you don’t have yet. Because that server has a subset of the data your `origin` server has right now, Git fetches no data but sets a remote branch called `teamone/master` to point to the commit that `teamone` has as its `master` branch (see Figure 3-26). + +Insert 18333fig0326.png +Figure 3-26. You get a reference to teamone’s master branch position locally. + +### Pushing ### + +When you want to share a branch with the world, you need to push it up to a remote that you have write access to. Your local branches aren’t automatically synchronized to the remotes you write to — you have to explicitly push the branches you want to share. That way, you can use private branches for work you don’t want to share, and push up only the topic branches you want to collaborate on. + +If you have a branch named `serverfix` that you want to work on with others, you can push it up the same way you pushed your first branch. Run `git push (remote) (branch)`: + + $ git push origin serverfix + Counting objects: 20, done. + Compressing objects: 100% (14/14), done. + Writing objects: 100% (15/15), 1.74 KiB, done. + Total 15 (delta 5), reused 0 (delta 0) + To git@github.com:schacon/simplegit.git + * [new branch] serverfix -> serverfix + +This is a bit of a shortcut. Git automatically expands the `serverfix` branchname out to `refs/heads/serverfix:refs/heads/serverfix`, which means, “Take my serverfix local branch and push it to update the remote’s serverfix branch.” We’ll go over the `refs/heads/` part in detail in Chapter 9, but you can generally leave it off. You can also do `git push origin serverfix:serverfix`, which does the same thing — it says, “Take my serverfix and make it the remote’s serverfix.” You can use this format to push a local branch into a remote branch that is named differently. If you didn’t want it to be called `serverfix` on the remote, you could instead run `git push origin serverfix:awesomebranch` to push your local `serverfix` branch to the `awesomebranch` branch on the remote project. + +The next time one of your collaborators fetches from the server, they will get a reference to where the server’s version of `serverfix` is under the remote branch `origin/serverfix`: + + $ git fetch origin + remote: Counting objects: 20, done. + remote: Compressing objects: 100% (14/14), done. + remote: Total 15 (delta 5), reused 0 (delta 0) + Unpacking objects: 100% (15/15), done. + From git@github.com:schacon/simplegit + * [new branch] serverfix -> origin/serverfix + +It’s important to note that when you do a fetch that brings down new remote branches, you don’t automatically have local, editable copies of them. In other words, in this case, you don’t have a new `serverfix` branch — you only have an `origin/serverfix` pointer that you can’t modify. + +To merge this work into your current working branch, you can run `git merge origin/serverfix`. If you want your own `serverfix` branch that you can work on, you can base it off your remote branch: + + $ git checkout -b serverfix origin/serverfix + Branch serverfix set up to track remote branch 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. + +### Tracking Branches ### + +Checking out a local branch from a remote branch automatically creates what is called a _tracking branch_. Tracking branches are local branches that have a direct relationship to a remote branch. If you’re on a tracking branch and type `git push`, Git automatically knows which server and branch to push to. Also, running `git pull` while on one of these branches fetches all the remote references and then automatically merges in the corresponding remote branch. + +When you clone a repository, it generally automatically creates a `master` branch that tracks `origin/master`. That’s why `git push` and `git pull` work out of the box with no other arguments. However, you can set up other tracking branches if you wish — ones that don’t track branches on `origin` and don’t track the `master` branch. The simple case is the example you just saw, running `git checkout -b [branch] [remotename]/[branch]`. If you have Git version 1.6.2 or later, you can also use the `--track` shorthand: + + $ git checkout --track origin/serverfix + Branch serverfix set up to track remote branch 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 serverfix from origin. + Switched to a new branch 'sf' + +Now, your local branch `sf` will automatically push to and pull from `origin/serverfix`. + +### Deleting Remote Branches ### + +Suppose you’re done with a remote branch — say, you and your collaborators are finished with a feature and have merged it into your remote’s `master` branch (or whatever branch your stable codeline is in). You can delete a remote branch using the rather obtuse syntax `git push [remotename] :[branch]`. If you want to delete your `serverfix` branch from the server, you run the following: + + $ git push origin :serverfix + To git@github.com:schacon/simplegit.git + - [deleted] serverfix + +Boom. No more branch on your server. You may want to dog-ear this page, because you’ll need that command, and you’ll likely forget the syntax. A way to remember this command is by recalling the `git push [remotename] [localbranch]:[remotebranch]` syntax that we went over a bit earlier. If you leave off the `[localbranch]` portion, then you’re basically saying, “Take nothing on my side and make it be `[remotebranch]`.” + +## Rebasing ## + +In Git, there are two main ways to integrate changes from one branch into another: the `merge` and the `rebase`. In this section you’ll learn what rebasing is, how to do it, why it’s a pretty amazing tool, and in what cases you won’t want to use it. + +### The Basic Rebase ### + +If you go back to an earlier example from the Merge section (see Figure 3-27), you can see that you diverged your work and made commits on two different branches. + +Insert 18333fig0327.png +Figure 3-27. Your initial diverged commit history. + +The easiest way to integrate the branches, as we’ve already covered, is the `merge` command. It performs a three-way merge between the two latest branch snapshots (C3 and C4) and the most recent common ancestor of the two (C2), creating a new snapshot (and commit), as shown in Figure 3-28. + +Insert 18333fig0328.png +Figure 3-28. Merging a branch to integrate the diverged work history. + +However, there is another way: you can take the patch of the change that was introduced in C3 and reapply it on top of C4. In Git, this is called _rebasing_. With the `rebase` command, you can take all the changes that were committed on one branch and replay them on another one. + +In this example, you’d run the following: + + $ git checkout experiment + $ git rebase master + First, rewinding head to replay your work on top of it... + Applying: added staged command + +It works by going to the common ancestor of the two branches (the one you’re on and the one you’re rebasing onto), getting the diff introduced by each commit of the branch you’re on, saving those diffs to temporary files, resetting the current branch to the same commit as the branch you are rebasing onto, and finally applying each change in turn. Figure 3-29 illustrates this process. + +Insert 18333fig0329.png +Figure 3-29. Rebasing the change introduced in C3 onto C4. + +At this point, you can go back to the master branch and do a fast-forward merge (see Figure 3-30). + +Insert 18333fig0330.png +Figure 3-30. Fast-forwarding the master branch. + +Now, the snapshot pointed to by C3' is exactly the same as the one that was pointed to by C5 in the merge example. There is no difference in the end product of the integration, but rebasing makes for a cleaner history. If you examine the log of a rebased branch, it looks like a linear history: it appears that all the work happened in series, even when it originally happened in parallel. + +Often, you’ll do this to make sure your commits apply cleanly on a remote branch — perhaps in a project to which you’re trying to contribute but that you don’t maintain. In this case, you’d do your work in a branch and then rebase your work onto `origin/master` when you were ready to submit your patches to the main project. That way, the maintainer doesn’t have to do any integration work — just a fast-forward or a clean apply. + +Note that the snapshot pointed to by the final commit you end up with, whether it’s the last of the rebased commits for a rebase or the final merge commit after a merge, is the same snapshot — it’s only the history that is different. Rebasing replays changes from one line of work onto another in the order they were introduced, whereas merging takes the endpoints and merges them together. + +### More Interesting Rebases ### + +You can also have your rebase replay on something other than the rebase branch. Take a history like Figure 3-31, for example. You branched a topic branch (`server`) to add some server-side functionality to your project, and made a commit. Then, you branched off that to make the client-side changes (`client`) and committed a few times. Finally, you went back to your server branch and did a few more commits. + +Insert 18333fig0331.png +Figure 3-31. A history with a topic branch off another topic branch. + +Suppose you decide that you want to merge your client-side changes into your mainline for a release, but you want to hold off on the server-side changes until it’s tested further. You can take the changes on client that aren’t on server (C8 and C9) and replay them on your master branch by using the `--onto` option of `git rebase`: + + $ git rebase --onto master server client + +This basically says, “Check out the client branch, figure out the patches from the common ancestor of the `client` and `server` branches, and then replay them onto `master`.” It’s a bit complex; but the result, shown in Figure 3-32, is pretty cool. + +Insert 18333fig0332.png +Figure 3-32. Rebasing a topic branch off another topic branch. + +Now you can fast-forward your master branch (see Figure 3-33): + + $ git checkout master + $ git merge client + +Insert 18333fig0333.png +Figure 3-33. Fast-forwarding your master branch to include the client branch changes. + +Let’s say you decide to pull in your server branch as well. You can rebase the server branch onto the master branch without having to check it out first by running `git rebase [basebranch] [topicbranch]` — which checks out the topic branch (in this case, `server`) for you and replays it onto the base branch (`master`): + + $ git rebase master server + +This replays your `server` work on top of your `master` work, as shown in Figure 3-34. + +Insert 18333fig0334.png +Figure 3-34. Rebasing your server branch on top of your master branch. + +Then, you can fast-forward the base branch (`master`): + + $ git checkout master + $ git merge server + +You can remove the `client` and `server` branches because all the work is integrated and you don’t need them anymore, leaving your history for this entire process looking like Figure 3-35: + + $ git branch -d client + $ git branch -d server + +Insert 18333fig0335.png +Figure 3-35. Final commit history. + +### The Perils of Rebasing ### + +Ahh, but the bliss of rebasing isn’t without its drawbacks, which can be summed up in a single line: + +**Do not rebase commits that you have pushed to a public repository.** + +If you follow that guideline, you’ll be fine. If you don’t, people will hate you, and you’ll be scorned by friends and family. + +When you rebase stuff, you’re abandoning existing commits and creating new ones that are similar but different. If you push commits somewhere and others pull them down and base work on them, and then you rewrite those commits with `git rebase` and push them up again, your collaborators will have to re-merge their work and things will get messy when you try to pull their work back into yours. + +Let’s look at an example of how rebasing work that you’ve made public can cause problems. Suppose you clone from a central server and then do some work off that. Your commit history looks like Figure 3-36. + +Insert 18333fig0336.png +Figure 3-36. Clone a repository, and base some work on it. + +Now, someone else does more work that includes a merge, and pushes that work to the central server. You fetch them and merge the new remote branch into your work, making your history look something like Figure 3-37. + +Insert 18333fig0337.png +Figure 3-37. Fetch more commits, and merge them into your work. + +Next, the person who pushed the merged work decides to go back and rebase their work instead; they do a `git push --force` to overwrite the history on the server. You then fetch from that server, bringing down the new commits. + +Insert 18333fig0338.png +Figure 3-38. Someone pushes rebased commits, abandoning commits you’ve based your work on. + +At this point, you have to merge this work in again, even though you’ve already done so. Rebasing changes the SHA-1 hashes of these commits so to Git they look like new commits, when in fact you already have the C4 work in your history (see Figure 3-39). + +Insert 18333fig0339.png +Figure 3-39. You merge in the same work again into a new merge commit. + +You have to merge that work in at some point so you can keep up with the other developer in the future. After you do that, your commit history will contain both the C4 and C4' commits, which have different SHA-1 hashes but introduce the same work and have the same commit message. If you run a `git log` when your history looks like this, you’ll see two commits that have the same author date and message, which will be confusing. Furthermore, if you push this history back up to the server, you’ll reintroduce all those rebased commits to the central server, which can further confuse people. + +If you treat rebasing as a way to clean up and work with commits before you push them, and if you only rebase commits that have never been available publicly, then you’ll be fine. If you rebase commits that have already been pushed publicly, and people may have based work on those commits, then you may be in for some frustrating trouble. + +## Summary ## + +We’ve covered basic branching and merging in Git. You should feel comfortable creating and switching to new branches, switching between branches and merging local branches together. You should also be able to share your branches by pushing them to a shared server, working with others on shared branches and rebasing your branches before they are shared. diff --git a/fa/04-git-server/01-chapter4.markdown b/fa/04-git-server/01-chapter4.markdown new file mode 100644 index 000000000..538ff671d --- /dev/null +++ b/fa/04-git-server/01-chapter4.markdown @@ -0,0 +1,872 @@ +#Git روی سرور# + در این نقطه، شما باید توانایی انجام کارهای روزانه ای را که قصد دارید با Git انجام دهید، داشته باشید. بااین وجود، برای همکاری با دیگران در Git ، به یک مخزن خارجی Git نیاز دارید. + +At this point, you should be able to do most of the day-to-day tasks for which you’ll be using Git. However, in order to do any collaboration in Git, you’ll need to have a remote Git repository. Although you can technically push changes to and pull changes from individuals’ repositories, doing so is discouraged because you can fairly easily confuse what they’re working on if you’re not careful. Furthermore, you want your collaborators to be able to access the repository even if your computer is offline — having a more reliable common repository is often useful. Therefore, the preferred method for collaborating with someone is to set up an intermediate repository that you both have access to, and push to and pull from that. We’ll refer to this repository as a "Git server"; but you’ll notice that it generally takes a tiny amount of resources to host a Git repository, so you’ll rarely need to use an entire server for it. + +Running a Git server is simple. First, you choose which protocols you want your server to communicate with. The first section of this chapter will cover the available protocols and the pros and cons of each. The next sections will explain some typical setups using those protocols and how to get your server running with them. Last, we’ll go over a few hosted options, if you don’t mind hosting your code on someone else’s server and don’t want to go through the hassle of setting up and maintaining your own server. + +If you have no interest in running your own server, you can skip to the last section of the chapter to see some options for setting up a hosted account and then move on to the next chapter, where we discuss the various ins and outs of working in a distributed source control environment. + +A remote repository is generally a _bare repository_ — a Git repository that has no working directory. Because the repository is only used as a collaboration point, there is no reason to have a snapshot checked out on disk; it’s just the Git data. In the simplest terms, a bare repository is the contents of your project’s `.git` directory and nothing else. + +## The Protocols ## + +Git can use four major network protocols to transfer data: Local, Secure Shell (SSH), Git, and HTTP. Here we’ll discuss what they are and in what basic circumstances you would want (or not want) to use them. + +It’s important to note that with the exception of the HTTP protocols, all of these require Git to be installed and working on the server. + +### Local Protocol ### + +The most basic is the _Local protocol_, in which the remote repository is in another directory on disk. This is often used if everyone on your team has access to a shared filesystem such as an NFS mount, or in the less likely case that everyone logs in to the same computer. The latter wouldn’t be ideal, because all your code repository instances would reside on the same computer, making a catastrophic loss much more likely. + +If you have a shared mounted filesystem, then you can clone, push to, and pull from a local file-based repository. To clone a repository like this or to add one as a remote to an existing project, use the path to the repository as the URL. For example, to clone a local repository, you can run something like this: + + $ git clone /opt/git/project.git + +Or you can do this: + + $ git clone file:///opt/git/project.git + +Git operates slightly differently if you explicitly specify `file://` at the beginning of the URL. If you just specify the path, 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: + + $ git remote add local_proj /opt/git/project.git + +Then, you can push to and pull from that remote as though you were doing so over a network. + +#### The Pros #### + +The pros of file-based repositories are that they’re simple and they use existing file permissions and network access. If you already have a shared filesystem to which your whole team has access, setting up a repository is very easy. You stick the bare repository copy somewhere everyone has shared access to and set the read/write permissions as you would for any other shared directory. We’ll discuss how to export a bare repository copy for this purpose in the next section, “Getting Git on a Server.” + +This is also a nice option for quickly grabbing work from someone else’s working repository. If you and a co-worker are working on the same project and they want you to check something out, running a command like `git pull /home/john/project` is often easier than them pushing to a remote server and you pulling down. + +#### The Cons #### + +The cons of this method are that shared access is generally more difficult to set up and reach from multiple locations than basic network access. If you want to push from your laptop when you’re at home, you have to mount the remote disk, which can be difficult and slow compared to network-based access. + +It’s also important to mention that this isn’t necessarily the fastest option if you’re using a shared mount of some kind. A local repository is fast only if you have fast access to the data. A repository on NFS is often slower than the repository over SSH on the same server, allowing Git to run off local disks on each system. + +### The SSH Protocol ### + +Probably the most common transport protocol for Git is SSH. This is because SSH access to servers is already set up in most places — and if it isn’t, it’s easy to do. SSH is also the only network-based protocol that you can easily read from and write to. The other two network protocols (HTTP and Git) are generally read-only, so even if you have them available for the unwashed masses, you still need SSH for your own write commands. SSH is also an authenticated network protocol; and because it’s ubiquitous, it’s generally easy to set up and use. + +To clone a Git repository over SSH, you can specify ssh:// URL like this: + + $ git clone ssh://user@server/project.git + +Or you can use the shorter scp-like syntax for SSH protocol: + + $ git clone user@server:project.git + +You can also not specify a user, and Git assumes the user you’re currently logged in as. + +#### The Pros #### + +The pros of using SSH are many. First, you basically have to use it if you want authenticated write access to your repository over a network. Second, SSH is relatively easy to set up — SSH daemons are commonplace, many network admins have experience with them, and many OS distributions are set up with them or have tools to manage them. Next, access over SSH is secure — all data transfer is encrypted and authenticated. Last, like the Git and Local protocols, SSH is efficient, making the data as compact as possible before transferring it. + +#### The Cons #### + +The negative aspect of SSH is that you can’t serve anonymous access of your repository over it. People must have access to your machine over SSH to access it, even in a read-only capacity, which doesn’t make SSH access conducive to open source projects. If you’re using it only within your corporate network, SSH may be the only protocol you need to deal with. If you want to allow anonymous read-only access to your projects, you’ll have to set up SSH for you to push over but something else for others to pull over. + +### The Git Protocol ### + +Next is the Git protocol. This is a special daemon that comes packaged with Git; it listens on a dedicated port (9418) that provides a service similar to the SSH protocol, but with absolutely no authentication. In order for a repository to be served over the Git protocol, you must create the `git-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 #### + +The Git protocol is the fastest transfer protocol available. If you’re serving a lot of traffic for a public project or serving a very large project that doesn’t require user authentication for read access, it’s likely that you’ll want to set up a Git daemon to serve your project. It uses the same data-transfer mechanism as the SSH protocol but without the encryption and authentication overhead. + +#### The Cons #### + +The downside of the Git protocol is the lack of authentication. It’s generally undesirable for the Git protocol to be the only access to your project. Generally, you’ll pair it with SSH access for the few developers who have push (write) access and have everyone else use `git://` for read-only access. +It’s also probably the most difficult protocol to set up. It must run its own daemon, which is custom — we’ll look at setting one up in the “Gitosis” section of this chapter — it requires `xinetd` configuration or the like, which isn’t always a walk in the park. It also requires firewall access to port 9418, which isn’t a standard port that corporate firewalls always allow. Behind big corporate firewalls, this obscure port is commonly blocked. + +### The HTTP/S Protocol ### + +Last we have the HTTP protocol. The beauty of the HTTP or HTTPS protocol is the simplicity of setting it up. Basically, all you have to do is put the bare Git repository under your HTTP document root and set up a specific `post-update` hook, and you’re done (See Chapter 7 for details on Git hooks). At that point, anyone who can access the web server under which you put the repository can also clone your repository. To allow read access to your repository over HTTP, do something like this: + + $ cd /var/www/htdocs/ + $ git clone --bare /path/to/git_project gitproject.git + $ cd gitproject.git + $ mv hooks/post-update.sample hooks/post-update + $ chmod a+x hooks/post-update + +That’s all. The `post-update` hook that comes with Git by default runs the appropriate command (`git update-server-info`) to make HTTP fetching and cloning work properly. This command is run when you push to this repository over SSH; then, other people can clone via something like + + $ git clone http://example.com/gitproject.git + +In this particular case, we’re using the `/var/www/htdocs` path that is common for Apache setups, but you can use any static web server — just put the bare repository in its path. The Git data is served as basic static files (see Chapter 9 for details about exactly how it’s served). + +It’s possible to make Git push over HTTP as well, although that technique isn’t as widely used and requires you to set up complex WebDAV requirements. Because it’s rarely used, we won’t cover it in this book. If you’re interested in using the HTTP-push protocols, you can read about preparing a repository for this purpose at `http://www.kernel.org/pub/software/scm/git/docs/howto/setup-git-server-over-http.txt`. One nice thing about making Git push over HTTP is that you can use any WebDAV server, without specific Git features; so, you can use this functionality if your web-hosting provider supports WebDAV for writing updates to your web site. + +#### The Pros #### + +The upside of using the HTTP protocol is that it’s easy to set up. Running the handful of required commands gives you a simple way to give the world read access to your Git repository. It takes only a few minutes to do. The HTTP protocol also isn’t very resource intensive on your server. Because it generally uses a static HTTP server to serve all the data, a normal Apache server can serve thousands of files per second on average — it’s difficult to overload even a small server. + +You can also serve your repositories read-only over HTTPS, which means you can encrypt the content transfer; or you can go so far as to make the clients use specific signed SSL certificates. Generally, if you’re going to these lengths, it’s easier to use SSH public keys; but it may be a better solution in your specific case to use signed SSL certificates or other HTTP-based authentication methods for read-only access over HTTPS. + +Another nice thing is that HTTP is such a commonly used protocol that corporate firewalls are often set up to allow traffic through this port. + +#### The Cons #### + +The downside of serving your repository over HTTP is that it’s relatively inefficient for the client. It generally takes a lot longer to clone or fetch from the repository, and you often have a lot more network overhead and transfer volume over HTTP than with any of the other network protocols. Because it’s not as intelligent about transferring only the data you need — there is no dynamic work on the part of the server in these transactions — the HTTP protocol is often referred to as a _dumb_ protocol. For more information about the differences in efficiency between the HTTP protocol and the other protocols, see Chapter 9. + +## Getting Git on a Server ## + +In order to initially set up any Git server, you have to export an existing repository into a new bare repository — a repository that doesn’t contain a working directory. This is generally straightforward to do. +In order to clone your repository to create a new bare repository, you run the clone command with the `--bare` option. By convention, bare repository directories end in `.git`, like so: + + $ git clone --bare my_project my_project.git + Cloning into bare repository 'my_project.git'... + done. + +You should now have a copy of the Git directory data in your `my_project.git` directory. + +This is roughly equivalent to something like + + $ cp -Rf my_project/.git my_project.git + +There are a couple of minor differences in the configuration file; but for your purpose, this is close to the same thing. It takes the Git repository by itself, without a working directory, and creates a directory specifically for it alone. + +### Putting the Bare Repository on a Server ### + +Now that you have a bare copy of your repository, all you need to do is put it on a server and set up your protocols. Let’s say you’ve set up a server called `git.example.com` that you have SSH access to, and you want to store all your Git repositories under the `/opt/git` directory. You can set up your new repository by copying your bare repository over: + + $ scp -r my_project.git user@git.example.com:/opt/git + +At this point, other users who have SSH access to the same server which has read-access to the `/opt/git` directory can clone your repository by running + + $ git clone user@git.example.com:/opt/git/my_project.git + +If a user SSHs into a server and has write access to the `/opt/git/my_project.git` directory, they will also automatically have push access. Git will automatically add group write permissions to a repository properly if you run the `git init` command with the `--shared` option. + + $ ssh user@git.example.com + $ cd /opt/git/my_project.git + $ git init --bare --shared + +You see how easy it is to take a Git repository, create a bare version, and place it on a server to which you and your collaborators have SSH access. Now you’re ready to collaborate on the same project. + +It’s important to note that this is literally all you need to do to run a useful Git server to which several people have access — just add SSH-able accounts on a server, and stick a bare repository somewhere that all those users have read and write access to. You’re ready to go — nothing else needed. + +In the next few sections, you’ll see how to expand to more sophisticated setups. This discussion will include not having to create user accounts for each user, adding public read access to repositories, setting up web UIs, using the Gitosis tool, and more. However, keep in mind that to collaborate with a couple of people on a private project, all you _need_ is an SSH server and a bare repository. + +### Small Setups ### + +If you’re a small outfit or are just trying out Git in your organization and have only a few developers, things can be simple for you. One of the most complicated aspects of setting up a Git server is user management. If you want some repositories to be read-only to certain users and read/write to others, access and permissions can be a bit difficult to arrange. + +#### SSH Access #### + +If you already have a server to which all your developers have SSH access, it’s generally easiest to set up your first repository there, because you have to do almost no work (as we covered in the last section). If you want more complex access control type permissions on your repositories, you can handle them with the normal filesystem permissions of the operating system your server runs. + +If you want to place your repositories on a server that doesn’t have accounts for everyone on your team whom you want to have write access, then you must set up SSH access for them. We assume that if you have a server with which to do this, you already have an SSH server installed, and that’s how you’re accessing the server. + +There are a few ways you can give access to everyone on your team. The first is to set up accounts for everybody, which is straightforward but can be cumbersome. You may not want to run `adduser` and set temporary passwords for every user. + +A second method is to create a single 'git' user on the machine, ask every user who is to have write access to send you an SSH public key, and add that key to the `~/.ssh/authorized_keys` file of your new 'git' user. At that point, everyone will be able to access that machine via the 'git' user. This doesn’t affect the commit data in any way — the SSH user you connect as doesn’t affect the commits you’ve recorded. + +Another way to do it is to have your SSH server authenticate from an LDAP server or some other centralized authentication source that you may already have set up. As long as each user can get shell access on the machine, any SSH authentication mechanism you can think of should work. + +## Generating Your SSH Public Key ## + +That being said, many Git servers authenticate using SSH public keys. In order to provide a public key, each user in your system must generate one if they don’t already have one. This process is similar across all operating systems. +First, you should check to make sure you don’t already have a key. By default, a user’s SSH keys are stored in that user’s `~/.ssh` directory. You can easily check to see if you have a key already by going to that directory and listing the contents: + + $ cd ~/.ssh + $ ls + authorized_keys2 id_dsa known_hosts + config id_dsa.pub + +You’re looking for a pair of files named something and something.pub, where the something is usually `id_dsa` or `id_rsa`. The `.pub` file is your public key, and the other file is your private key. If you don’t have these files (or you don’t even have a `.ssh` directory), you can create them by running a program called `ssh-keygen`, which is provided with the SSH package on Linux/Mac systems and comes with the MSysGit package on Windows: + + $ ssh-keygen + Generating public/private rsa key pair. + Enter file in which to save the key (/Users/schacon/.ssh/id_rsa): + Enter passphrase (empty for no passphrase): + Enter same passphrase again: + Your identification has been saved in /Users/schacon/.ssh/id_rsa. + Your public key has been saved in /Users/schacon/.ssh/id_rsa.pub. + The key fingerprint is: + 43:c5:5b:5f:b1:f1:50:43:ad:20:a6:92:6a:1f:9a:3a schacon@agadorlaptop.local + +First it confirms where you want to save the key (`.ssh/id_rsa`), and then it asks twice for a passphrase, which you can leave empty if you don’t want to type a password when you use the key. + +Now, each user that does this has to send their public key to you or whoever is administrating the Git server (assuming you’re using an SSH server setup that requires public keys). All they have to do is copy the contents of the `.pub` file and e-mail it. The public keys look something like this: + + $ cat ~/.ssh/id_rsa.pub + ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU + GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3 + Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA + t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En + mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx + NrRFi9wrf+M7Q== schacon@agadorlaptop.local + +For a more in-depth tutorial on creating an SSH key on multiple operating systems, see the GitHub guide on SSH keys at `http://github.com/guides/providing-your-ssh-key`. + +## Setting Up the Server ## + +Let’s walk through setting up SSH access on the server side. In this example, you’ll use the `authorized_keys` method for authenticating your users. We also assume you’re running a standard Linux distribution like Ubuntu. First, you create a 'git' user and a `.ssh` directory for that user. + + $ sudo adduser git + $ su git + $ cd + $ mkdir .ssh + +Next, you need to add some developer SSH public keys to the `authorized_keys` file for that user. Let’s assume you’ve received a few keys by e-mail and saved them to temporary files. Again, the public keys look something like this: + + $ cat /tmp/id_rsa.john.pub + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCB007n/ww+ouN4gSLKssMxXnBOvf9LGt4L + ojG6rs6hPB09j9R/T17/x4lhJA0F3FR1rP6kYBRsWj2aThGw6HXLm9/5zytK6Ztg3RPKK+4k + Yjh6541NYsnEAZuXz0jTTyAUfrtU3Z5E003C4oxOj6H0rfIF1kKI9MAQLMdpGW1GYEIgS9Ez + Sdfd8AcCIicTDWbqLAcU4UpkaX8KyGlLwsNuuGztobF8m72ALC/nLF6JLtPofwFBlgc+myiv + O7TCUSBdLQlgMVOFq1I2uPWQOkOWQAHukEOmfjy2jctxSDBQ220ymjaNsHT4kgtZg2AYYgPq + dAv8JggJICUvax2T9va5 gsg-keypair + +You just append them to your `authorized_keys` file: + + $ cat /tmp/id_rsa.john.pub >> ~/.ssh/authorized_keys + $ cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys + $ cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys + +Key-based SSH authentication usually enforces security by requiring restricted rights on the involved files. To prevent SSH from refusing to work, type this: + + $ chmod -R go= ~/.ssh + +Now, you can set up an empty repository for your users by running `git init` with the `--bare` option, which initializes the repository without a working directory: + + $ cd /opt/git + $ mkdir project.git + $ cd project.git + $ git --bare init + +Then, John, Josie, or Jessica can push the first version of their project into that repository by adding it as a remote and pushing up a branch. Note that someone must shell onto the machine and create a bare repository every time you want to add a project. Let’s use `gitserver` as the hostname of the server on which you’ve set up your 'git' user and repository. If you’re running it internally, and you set up DNS for `gitserver` to point to that server, then you can use the commands pretty much as is: + + # on Johns computer + $ cd myproject + $ git init + $ git add . + $ git commit -m 'initial commit' + $ git remote add origin git@gitserver:/opt/git/project.git + $ git push origin master + +At this point, the others can clone it down and push changes back up just as easily: + + $ git clone git@gitserver:/opt/git/project.git + $ cd project + $ vim README + $ git commit -am 'fix for the README file' + $ git push origin master + +With this method, you can quickly get a read/write Git server up and running for a handful of developers. + +As an extra precaution, you can easily restrict the 'git' user to only doing Git activities with a limited shell tool called `git-shell` that comes with Git. If you set this as your 'git' user’s login shell, then the 'git' user can’t have normal shell access to your server. To use this, specify `git-shell` instead of bash or csh for your user’s login shell. To do so, you’ll likely have to edit your `/etc/passwd` file: + + $ sudo vim /etc/passwd + +At the bottom, you should find a line that looks something like this: + + git:x:1000:1000::/home/git:/bin/sh + +Change `/bin/sh` to `/usr/bin/git-shell` (or run `which git-shell` to see where it’s installed). The line should look something like this: + + git:x:1000:1000::/home/git:/usr/bin/git-shell + +Now, the 'git' user can only use the SSH connection to push and pull Git repositories and can’t shell onto the machine. If you try, you’ll see a login rejection like this: + + $ ssh git@gitserver + fatal: What do you think I am? A shell? + Connection to gitserver closed. + +## Public Access ## + +What if you want anonymous read access to your project? Perhaps instead of hosting an internal private project, you want to host an open source project. Or maybe you have a bunch of automated build servers or continuous integration servers that change a lot, and you don’t want to have to generate SSH keys all the time — you just want to add simple anonymous read access. + +Probably the simplest way for smaller setups is to run a static web server with its document root where your Git repositories are, and then enable that `post-update` hook we mentioned in the first section of this chapter. Let’s work from the previous example. Say you have your repositories in the `/opt/git` directory, and an Apache server is running on your machine. Again, you can use any web server for this; but as an example, we’ll demonstrate some basic Apache configurations that should give you an idea of what you might need. + +First you need to enable the hook: + + $ cd project.git + $ mv hooks/post-update.sample hooks/post-update + $ chmod a+x hooks/post-update + +What does this `post-update` hook do? It looks basically like this: + + $ cat .git/hooks/post-update + #!/bin/sh + # + # 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. + +Next, you need to add a VirtualHost entry to your Apache configuration with the document root as the root directory of your Git projects. Here, we’re assuming that you have wildcard DNS set up to send `*.gitserver` to whatever box you’re using to run all this: + + + ServerName git.gitserver + DocumentRoot /opt/git + + Order allow, deny + allow from all + + + +You’ll also need to set the Unix user group of the `/opt/git` directories to `www-data` so your web server can read-access the repositories, because the Apache instance running the CGI script will (by default) be running as that user: + + $ chgrp -R www-data /opt/git + +When you restart Apache, you should be able to clone your repositories under that directory by specifying the URL for your project: + + $ git clone http://git.gitserver/project.git + +This way, you can set up HTTP-based read access to any of your projects for a fair number of users in a few minutes. Another simple option for public unauthenticated access is to start a Git daemon, although that requires you to daemonize the process - we’ll cover this option in the next section, if you prefer that route. + +## GitWeb ## + +Now that you have basic read/write and read-only access to your project, you may want to set up a simple web-based visualizer. Git comes with a CGI script called GitWeb that is commonly used for this. You can see GitWeb in use at sites like `http://git.kernel.org` (see Figure 4-1). + +Insert 18333fig0401.png +Figure 4-1. The GitWeb web-based user interface. + +If you want to check out what GitWeb would look like for your project, Git comes with a command to fire up a temporary instance if you have a lightweight server on your system like `lighttpd` or `webrick`. On Linux machines, `lighttpd` is often installed, so you may be able to get it to run by typing `git instaweb` in your project directory. If you’re running a Mac, Leopard comes preinstalled with Ruby, so `webrick` may be your best bet. To start `instaweb` with a non-lighttpd handler, you can run it with the `--httpd` option. + + $ git instaweb --httpd=webrick + [2009-02-21 10:02:21] INFO WEBrick 1.3.1 + [2009-02-21 10:02:21] INFO ruby 1.8.6 (2008-03-03) [universal-darwin9.0] + +That starts up an HTTPD server on port 1234 and then automatically starts a web browser that opens on that page. It’s pretty easy on your part. When you’re done and want to shut down the server, you can run the same command with the `--stop` option: + + $ git instaweb --httpd=webrick --stop + +If you want to run the web interface on a server all the time for your team or for an open source project you’re hosting, you’ll need to set up the CGI script to be served by your normal web server. Some Linux distributions have a `gitweb` package that you may be able to install via `apt` or `yum`, so you may want to try that first. We’ll walk though installing GitWeb manually very quickly. First, you need to get the Git source code, which GitWeb comes with, and generate the custom CGI script: + + $ git clone git://git.kernel.org/pub/scm/git/git.git + $ cd git/ + $ make GITWEB_PROJECTROOT="/opt/git" \ + prefix=/usr gitweb + $ sudo cp -Rf gitweb /var/www/ + +Notice that you have to tell the command where to find your Git repositories with the `GITWEB_PROJECTROOT` variable. Now, you need to make Apache use CGI for that script, for which you can add a VirtualHost: + + + ServerName gitserver + DocumentRoot /var/www/gitweb + + Options ExecCGI +FollowSymLinks +SymLinksIfOwnerMatch + AllowOverride All + order allow,deny + Allow from all + AddHandler cgi-script cgi + DirectoryIndex gitweb.cgi + + + +Again, GitWeb can be served with any CGI capable web server; if you prefer to use something else, it shouldn’t be difficult to set up. At this point, you should be able to visit `http://gitserver/` to view your repositories online, and you can use `http://git.gitserver` to clone and fetch your repositories over HTTP. + +## Gitosis ## + +Keeping all users’ public keys in the `authorized_keys` file for access works well only for a while. When you have hundreds of users, it’s much more of a pain to manage that process. You have to shell onto the server each time, and there is no access control — everyone in the file has read and write access to every project. + +At this point, you may want to turn to a widely used software project called Gitosis. Gitosis is basically a set of scripts that help you manage the `authorized_keys` file as well as implement some simple access controls. The really interesting part is that the UI for this tool for adding people and determining access isn’t a web interface but a special Git repository. You set up the information in that project; and when you push it, Gitosis reconfigures the server based on that, which is cool. + +Installing Gitosis isn’t the simplest task ever, but it’s not too difficult. It’s easiest to use a Linux server for it — these examples use a stock Ubuntu 8.10 server. + +Gitosis requires some Python tools, so first you have to install the Python setuptools package, which Ubuntu provides as python-setuptools: + + $ apt-get install python-setuptools + +Next, you clone and install Gitosis from the project’s main site: + + $ git clone https://github.com/tv42/gitosis.git + $ cd gitosis + $ sudo python setup.py install + +That installs a couple of executables that Gitosis will use. Next, Gitosis wants to put its repositories under `/home/git`, which is fine. But you have already set up your repositories in `/opt/git`, so instead of reconfiguring everything, you create a symlink: + + $ ln -s /opt/git /home/git/repositories + +Gitosis is going to manage your keys for you, so you need to remove the current file, re-add the keys later, and let Gitosis control the `authorized_keys` file automatically. For now, move the `authorized_keys` file out of the way: + + $ mv /home/git/.ssh/authorized_keys /home/git/.ssh/ak.bak + +Next you need to turn your shell back on for the 'git' user, if you changed it to the `git-shell` command. People still won’t be able to log in, but Gitosis will control that for you. So, let’s change this line in your `/etc/passwd` file + + git:x:1000:1000::/home/git:/usr/bin/git-shell + +back to this: + + git:x:1000:1000::/home/git:/bin/sh + +Now it’s time to initialize Gitosis. You do this by running the `gitosis-init` command with your personal public key. If your public key isn’t on the server, you’ll have to copy it there: + + $ sudo -H -u git gitosis-init < /tmp/id_dsa.pub + Initialized empty Git repository in /opt/git/gitosis-admin.git/ + Reinitialized existing Git repository in /opt/git/gitosis-admin.git/ + +This lets the user with that key modify the main Git repository that controls the Gitosis setup. Next, you have to manually set the execute bit on the `post-update` script for your new control repository. + + $ sudo chmod 755 /opt/git/gitosis-admin.git/hooks/post-update + +You’re ready to roll. If you’re set up correctly, you can try to SSH into your server as the user for which you added the public key to initialize Gitosis. You should see something like this: + + $ ssh git@gitserver + PTY allocation request failed on channel 0 + 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: + + # on your local computer + $ git clone git@gitserver:gitosis-admin.git + +Now you have a directory named `gitosis-admin`, which has two major parts: + + $ cd gitosis-admin + $ find . + ./gitosis.conf + ./keydir + ./keydir/scott.pub + +The `gitosis.conf` file is the control file you use to specify users, repositories, and permissions. The `keydir` directory is where you store the public keys of all the users who have any sort of access to your repositories — one file per user. The name of the file in `keydir` (in the previous example, `scott.pub`) will be different for you — Gitosis takes that name from the description at the end of the public key that was imported with the `gitosis-init` script. + +If you look at the `gitosis.conf` file, it should only specify information about the `gitosis-admin` project that you just cloned: + + $ cat gitosis.conf + [gitosis] + + [group gitosis-admin] + 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] + 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 8962da8] add iphone_project and mobile group + 1 file changed, 4 insertions(+) + $ git push origin master + Counting objects: 5, done. + 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: + + $ git remote add origin git@gitserver:iphone_project.git + $ git push origin master + Initialized empty Git repository in /opt/git/iphone_project.git/ + Counting objects: 3, done. + Writing objects: 100% (3/3), 230 bytes | 0 bytes/s, done. + Total 3 (delta 0), reused 0 (delta 0) + To git@gitserver:iphone_project.git + * [new branch] master -> master + +Notice that you don’t need to specify the path (in fact, doing so won’t work), just a colon and then the name of the project — Gitosis finds it for you. + +You want to work on this project with your friends, so you’ll have to re-add their public keys. But instead of appending them manually to the `~/.ssh/authorized_keys` file on your server, you’ll add them, one key per file, into the `keydir` directory. How you name the keys determines how you refer to the users in the `gitosis.conf` file. Let’s re-add the public keys for John, Josie, and Jessica: + + $ cp /tmp/id_rsa.john.pub keydir/john.pub + $ cp /tmp/id_rsa.josie.pub keydir/josie.pub + $ cp /tmp/id_rsa.jessica.pub keydir/jessica.pub + +Now you can add them all to your 'mobile' team so they have read and write access to `iphone_project`: + + [group mobile] + 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] + members = scott josie jessica + writable = iphone_project + + [group mobile_ro] + 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: + + [group mobile_committers] + members = scott josie jessica + + [group mobile] + members = @mobile_committers + writable = iphone_project + + [group mobile_2] + 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. + +## Gitolite ## + +This section serves as a quick introduction to Gitolite, and provides basic installation and setup instructions. It cannot, however, replace the enormous amount of [documentation][gltoc] that Gitolite comes with. There may also be occasional changes to this section itself, so you may also want to look at the latest version [here][gldpg]. + +[gldpg]: http://sitaramc.github.com/gitolite/progit.html +[gltoc]: http://sitaramc.github.com/gitolite/master-toc.html + +Gitolite is an authorization layer on top of Git, relying on `sshd` or `httpd` for authentication. (Recap: authentication is identifying who the user is, authorization is deciding if he is allowed to do what he is attempting to). + +Gitolite allows you to specify permissions not just by repository, but also by branch or tag names within each repository. That is, you can specify that certain people (or groups of people) can only push certain "refs" (branches or tags) but not others. + +### Installing ### + +Installing Gitolite is very easy, even if you don’t read the extensive documentation that comes with it. You need an account on a Unix server of some kind. You do not need root access, assuming Git, Perl, and an OpenSSH compatible SSH server are already installed. In the examples below, we will use the `git` account on a host called `gitserver`. + +Gitolite is somewhat unusual as far as "server" software goes — access is via SSH, and so every userid on the server is a potential "gitolite host". We will describe the simplest install method in this article; for the other methods please see the documentation. + +To begin, create a user called `git` on your server and login to this user. Copy your SSH public key (a file called `~/.ssh/id_rsa.pub` if you did a plain `ssh-keygen` with all the defaults) from your workstation, renaming it to `.pub` (we'll use `scott.pub` in our examples). Then run these commands: + + $ git clone git://github.com/sitaramc/gitolite + $ gitolite/install -ln + # assumes $HOME/bin exists and is in your $PATH + $ gitolite setup -pk $HOME/scott.pub + +That last command creates new Git repository called `gitolite-admin` on the server. + +Finally, back on your workstation, run `git clone git@gitserver:gitolite-admin`. And you’re done! Gitolite has now been installed on the server, and you now have a brand new repository called `gitolite-admin` in your workstation. You administer your Gitolite setup by making changes to this repository and pushing. + +### Customising the Install ### + +While the default, quick, install works for most people, there are some ways to customise the install if you need to. Some changes can be made simply by editing the rc file, but if that is not sufficient, there’s documentation on customising Gitolite. + +### Config File and Access Control Rules ### + +Once the install is done, you switch to the `gitolite-admin` clone you just made on your workstation, and poke around to see what you got: + + $ cd ~/gitolite-admin/ + $ ls + conf/ keydir/ + $ find conf keydir -type f + conf/gitolite.conf + keydir/scott.pub + $ cat conf/gitolite.conf + + repo gitolite-admin + RW+ = scott + + repo testing + RW+ = @all + +Notice that "scott" (the name of the pubkey in the `gitolite setup` command you used earlier) has read-write permissions on the `gitolite-admin` repository as well as a public key file of the same name. + +Adding users is easy. To add a user called "alice", obtain her public key, name it `alice.pub`, and put it in the `keydir` directory of the clone of the `gitolite-admin` repo you just made on your workstation. Add, commit, and push the change, and the user has been added. + +The config file syntax for Gitolite is well documented, so we’ll only mention some highlights here. + +You can group users or repos for convenience. The group names are just like macros; when defining them, it doesn’t even matter whether they are projects or users; that distinction is only made when you *use* the "macro". + + @oss_repos = linux perl rakudo git gitolite + @secret_repos = fenestra pear + + @admins = scott + @interns = ashok + @engineers = sitaram dilbert wally alice + @staff = @admins @engineers @interns + +You can control permissions at the "ref" level. In the following example, interns can only push the "int" branch. Engineers can push any branch whose name starts with "eng-", and tags that start with "rc" followed by a digit. And the admins can do anything (including rewind) to any ref. + + repo @oss_repos + RW int$ = @interns + RW eng- = @engineers + RW refs/tags/rc[0-9] = @engineers + RW+ = @admins + +The expression after the `RW` or `RW+` is a regular expression (regex) that the refname (ref) being pushed is matched against. So we call it a "refex"! Of course, a refex can be far more powerful than shown here, so don’t overdo it if you’re not comfortable with Perl regexes. + +Also, as you probably guessed, Gitolite prefixes `refs/heads/` as a syntactic convenience if the refex does not begin with `refs/`. + +An important feature of the config file’s syntax is that all the rules for a repository need not be in one place. You can keep all the common stuff together, like the rules for all `oss_repos` shown above, then add specific rules for specific cases later on, like so: + + repo gitolite + RW+ = sitaram + +That rule will just get added to the ruleset for the `gitolite` repository. + +At this point you might be wondering how the access control rules are actually applied, so let’s go over that briefly. + +There are two levels of access control in Gitolite. The first is at the repository level; if you have read (or write) access to *any* ref in the repository, then you have read (or write) access to the repository. This is the only access control that Gitosis had. + +The second level, applicable only to "write" access, is by branch or tag within a repository. The username, the access being attempted (`W` or `+`), and the refname being updated are known. The access rules are checked in order of appearance in the config file, looking for a match for this combination (but remember that the refname is regex-matched, not merely string-matched). If a match is found, the push succeeds. A fallthrough results in access being denied. + +### Advanced Access Control with "deny" rules ### + +So far, we’ve only seen permissions to be one of `R`, `RW`, or `RW+`. However, Gitolite allows another permission: `-`, standing for "deny". This gives you a lot more power, at the expense of some complexity, because now fallthrough is not the *only* way for access to be denied, so the *order of the rules now matters*! + +Let us say, in the situation above, we want engineers to be able to rewind any branch *except* master and integ. Here’s how to do that: + + RW master integ = @engineers + - master integ = @engineers + RW+ = @engineers + +Again, you simply follow the rules top down until you hit a match for your access mode, or a deny. Non-rewind push to master or integ is allowed by the first rule. A rewind push to those refs does not match the first rule, drops down to the second, and is therefore denied. Any push (rewind or non-rewind) to refs other than master or integ won’t match the first two rules anyway, and the third rule allows it. + +### Restricting pushes by files changed ### + +In addition to restricting what branches a user can push changes to, you can also restrict what files they are allowed to touch. For example, perhaps the Makefile (or some other program) is really not supposed to be changed by just anyone, because a lot of things depend on it or would break if the changes are not done *just right*. You can tell Gitolite: + + repo foo + RW = @junior_devs @senior_devs + + - VREF/NAME/Makefile = @junior_devs + +Users who are migrating from the older Gitolite should note that there is a significant change in behaviour with regard to this feature; please see the migration guide for details. + +### Personal Branches ### + +Gitolite also has a feature called "personal branches" (or rather, "personal branch namespace") that can be very useful in a corporate environment. + +A lot of code exchange in the Git world happens by "please pull" requests. In a corporate environment, however, unauthenticated access is a no-no, and a developer workstation cannot do authentication, so you have to push to the central server and ask someone to pull from there. + +This would normally cause the same branch name clutter as in a centralised VCS, plus setting up permissions for this becomes a chore for the admin. + +Gitolite lets you define a "personal" or "scratch" namespace prefix for each developer (for example, `refs/personal//*`); please see the documentation for details. + +### "Wildcard" repositories ### + +Gitolite allows you to specify repositories with wildcards (actually Perl regexes), like, for example `assignments/s[0-9][0-9]/a[0-9][0-9]`, to pick a random example. It also allows you to assign a new permission mode (`C`) which enables users to create repositories based on such wild cards, automatically assigns ownership to the specific user who created it, allows him/her to hand out `R` and `RW` permissions to other users to collaborate, etc. Again, please see the documentation for details. + +### Other Features ### + +We’ll round off this discussion with a sampling of other features, all of which, and many more, are described in great detail in the documentation. + +**Logging**: Gitolite logs all successful accesses. If you were somewhat relaxed about giving people rewind permissions (`RW+`) and some kid blew away `master`, the log file is a life saver, in terms of easily and quickly finding the SHA that got hosed. + +**Access rights reporting**: Another convenient feature is what happens when you try and just ssh to the server. Gitolite shows you what repos you have access to, and what that access may be. Here’s an example: + + hello scott, this is git@git running gitolite3 v3.01-18-g9609868 on git 1.7.4.4 + + R anu-wsd + R entrans + R W git-notes + R W gitolite + R W gitolite-admin + R indic_web_input + R shreelipi_converter + +**Delegation**: For really large installations, you can delegate responsibility for groups of repositories to various people and have them manage those pieces independently. This reduces the load on the main admin, and makes him less of a bottleneck. + +**Mirroring**: Gitolite can help you maintain multiple mirrors, and switch between them easily if the primary server goes down. + +## Git Daemon ## + +For public, unauthenticated read access to your projects, you’ll want to move past the HTTP protocol and start using the Git protocol. The main reason is speed. The Git protocol is far more efficient and thus faster than the HTTP protocol, so using it will save your users time. + +Again, this is for unauthenticated read-only access. If you’re running this on a server outside your firewall, it should only be used for projects that are publicly visible to the world. If the server you’re running it on is inside your firewall, you might use it for projects that a large number of people or computers (continuous integration or build servers) have read-only access to, when you don’t want to have to add an SSH key for each. + +In any case, the Git protocol is relatively easy to set up. Basically, you need to run this command in a daemonized manner: + + git daemon --reuseaddr --base-path=/opt/git/ /opt/git/ + +`--reuseaddr` allows the server to restart without waiting for old connections to time out, the `--base-path` option allows people to clone projects without specifying the entire path, and the path at the end tells the Git daemon where to look for repositories to export. If you’re running a firewall, you’ll also need to punch a hole in it at port 9418 on the box you’re setting this up on. + +You can daemonize this process a number of ways, depending on the operating system you’re running. On an Ubuntu machine, you use an Upstart script. So, in the following file + + /etc/event.d/local-git-daemon + +you put this script: + + start on startup + stop on shutdown + exec /usr/bin/git daemon \ + --user=git --group=git \ + --reuseaddr \ + --base-path=/opt/git/ \ + /opt/git/ + respawn + +For security reasons, it is strongly encouraged to have this daemon run as a user with read-only permissions to the repositories — you can easily do this by creating a new user 'git-ro' and running the daemon as them. For the sake of simplicity we’ll simply run it as the same 'git' user that Gitosis is running as. + +When you restart your machine, your Git daemon will start automatically and respawn if it goes down. To get it running without having to reboot, you can run this: + + initctl start local-git-daemon + +On other systems, you may want to use `xinetd`, a script in your `sysvinit` system, or something else — as long as you get that command daemonized and watched somehow. + +Next, you have to tell your Gitosis server which repositories to allow unauthenticated Git server-based access to. If you add a section for each repository, you can specify the ones from which you want your Git daemon to allow reading. If you want to allow Git protocol access for the `iphone_project`, you add this to the end of the `gitosis.conf` file: + + [repo iphone_project] + daemon = yes + +When that is committed and pushed up, your running daemon should start serving requests for the project to anyone who has access to port 9418 on your server. + +If you decide not to use Gitosis, but you want to set up a Git daemon, you’ll have to run this on each project you want the Git daemon to serve: + + $ cd /path/to/project.git + $ touch git-daemon-export-ok + +The presence of that file tells Git that it’s OK to serve this project without authentication. + +Gitosis can also control which projects GitWeb shows. First, you need to add something like the following to the `/etc/gitweb.conf` file: + + $projects_list = "/home/git/gitosis/projects.list"; + $projectroot = "/home/git/repositories"; + $export_ok = "git-daemon-export-ok"; + @git_base_url_list = ('git://gitserver'); + +You can control which projects GitWeb lets users browse by adding or removing a `gitweb` setting in the Gitosis configuration file. For instance, if you want the `iphone_project` to show up on GitWeb, you make the `repo` setting look like this: + + [repo iphone_project] + daemon = yes + gitweb = yes + +Now, if you commit and push the project, GitWeb will automatically start showing the `iphone_project`. + +## Hosted Git ## + +If you don’t want to go through all of the work involved in setting up your own Git server, you have several options for hosting your Git projects on an external dedicated hosting site. Doing so offers a number of advantages: a hosting site is generally quick to set up and easy to start projects on, and no server maintenance or monitoring is involved. Even if you set up and run your own server internally, you may still want to use a public hosting site for your open source code — it’s generally easier for the open source community to find and help you with. + +These days, you have a huge number of hosting options to choose from, each with different advantages and disadvantages. To see an up-to-date list, check out the following page: + + https://git.wiki.kernel.org/index.php/GitHosting + +Because we can’t cover all of them, and because I happen to work at one of them, we’ll use this section to walk through setting up an account and creating a new project at GitHub. This will give you an idea of what is involved. + +GitHub is by far the largest open source Git hosting site and it’s also one of the very few that offers both public and private hosting options so you can keep your open source and private commercial code in the same place. In fact, we used GitHub to privately collaborate on this book. + +### GitHub ### + +GitHub is slightly different than most code-hosting sites in the way that it namespaces projects. Instead of being primarily based on the project, GitHub is user-centric. That means when I host my `grit` project on GitHub, you won’t find it at `github.com/grit` but instead at `github.com/schacon/grit`. There is no canonical version of any project, which allows a project to move from one user to another seamlessly if the first author abandons the project. + +GitHub is also a commercial company that charges for accounts that maintain private repositories, but anyone can quickly get a free account to host as many open source projects as they want. We’ll quickly go over how that is done. + +### Setting Up a User Account ### + +The first thing you need to do is set up a free user account. If you visit the "Plans and pricing" page at `https://github.com/pricing` and click the "Sign Up" button on the Free account (see Figure 4-2), you’re taken to the signup page. + +Insert 18333fig0402.png +Figure 4-2. The GitHub plan page. + +Here you must choose a username that isn’t yet taken in the system and enter an e-mail address that will be associated with the account and a password (see Figure 4-3). + +Insert 18333fig0403.png +Figure 4-3. The GitHub user signup form. + +If you have it available, this is a good time to add your public SSH key as well. We covered how to generate a new key earlier, in the "Simple Setups" section. Take the contents of the public key of that pair, and paste it into the SSH Public Key text box. Clicking the "explain ssh keys" link takes you to detailed instructions on how to do so on all major operating systems. +Clicking the "I agree, sign me up" button takes you to your new user dashboard (see Figure 4-4). + +Insert 18333fig0404.png +Figure 4-4. The GitHub user dashboard. + +Next you can create a new repository. + +### Creating a New Repository ### + +Start by clicking the "create a new one" link next to Your Repositories on the user dashboard. You’re taken to the Create a New Repository form (see Figure 4-5). + +Insert 18333fig0405.png +Figure 4-5. Creating a new repository on GitHub. + +All you really have to do is provide a project name, but you can also add a description. When that is done, click the "Create Repository" button. Now you have a new repository on GitHub (see Figure 4-6). + +Insert 18333fig0406.png +Figure 4-6. GitHub project header information. + +Since you have no code there yet, GitHub will show you instructions for how create a brand-new project, push an existing Git project up, or import a project from a public Subversion repository (see Figure 4-7). + +Insert 18333fig0407.png +Figure 4-7. Instructions for a new repository. + +These instructions are similar to what we’ve already gone over. To initialize a project if it isn’t already a Git project, you use + + $ git init + $ git add . + $ git commit -m 'initial commit' + +When you have a Git repository locally, add GitHub as a remote and push up your master branch: + + $ git remote add origin git@github.com:testinguser/iphone_project.git + $ git push origin master + +Now your project is hosted on GitHub, and you can give the URL to anyone you want to share your project with. In this case, it’s `http://github.com/testinguser/iphone_project`. You can also see from the header on each of your project’s pages that you have two Git URLs (see Figure 4-8). + +Insert 18333fig0408.png +Figure 4-8. Project header with a public URL and a private URL. + +The Public Clone URL is a public, read-only Git URL over which anyone can clone the project. Feel free to give out that URL and post it on your web site or what have you. + +The Your Clone URL is a read/write SSH-based URL that you can read or write over only if you connect with the SSH private key associated with the public key you uploaded for your user. When other users visit this project page, they won’t see that URL—only the public one. + +### Importing from Subversion ### + +If you have an existing public Subversion project that you want to import into Git, GitHub can often do that for you. At the bottom of the instructions page is a link to a Subversion import. If you click it, you see a form with information about the import process and a text box where you can paste in the URL of your public Subversion project (see Figure 4-9). + +Insert 18333fig0409.png +Figure 4-9. Subversion importing interface. + +If your project is very large, nonstandard, or private, this process probably won’t work for you. In Chapter 7, you’ll learn how to do more complicated manual project imports. + +### Adding Collaborators ### + +Let’s add the rest of the team. If John, Josie, and Jessica all sign up for accounts on GitHub, and you want to give them push access to your repository, you can add them to your project as collaborators. Doing so will allow pushes from their public keys to work. + +Click the "edit" button in the project header or the Admin tab at the top of the project to reach the Admin page of your GitHub project (see Figure 4-10). + +Insert 18333fig0410.png +Figure 4-10. GitHub administration page. + +To give another user write access to your project, click the “Add another collaborator” link. A new text box appears, into which you can type a username. As you type, a helper pops up, showing you possible username matches. When you find the correct user, click the Add button to add that user as a collaborator on your project (see Figure 4-11). + +Insert 18333fig0411.png +Figure 4-11. Adding a collaborator to your project. + +When you’re finished adding collaborators, you should see a list of them in the Repository Collaborators box (see Figure 4-12). + +Insert 18333fig0412.png +Figure 4-12. A list of collaborators on your project. + +If you need to revoke access to individuals, you can click the "revoke" link, and their push access will be removed. For future projects, you can also copy collaborator groups by copying the permissions of an existing project. + +### Your Project ### + +After you push your project up or have it imported from Subversion, you have a main project page that looks something like Figure 4-13. + +Insert 18333fig0413.png +Figure 4-13. A GitHub main project page. + +When people visit your project, they see this page. It contains tabs to different aspects of your projects. The Commits tab shows a list of commits in reverse chronological order, similar to the output of the `git log` command. The Network tab shows all the people who have forked your project and contributed back. The Downloads tab allows you to upload project binaries and link to tarballs and zipped versions of any tagged points in your project. The Wiki tab provides a wiki where you can write documentation or other information about your project. The Graphs tab has some contribution visualizations and statistics about your project. The main Source tab that you land on shows your project’s main directory listing and automatically renders the README file below it if you have one. This tab also shows a box with the latest commit information. + +### Forking Projects ### + +If you want to contribute to an existing project to which you don’t have push access, GitHub encourages forking the project. When you land on a project page that looks interesting and you want to hack on it a bit, you can click the "fork" button in the project header to have GitHub copy that project to your user so you can push to it. + +This way, projects don’t have to worry about adding users as collaborators to give them push access. People can fork a project and push to it, and the main project maintainer can pull in those changes by adding them as remotes and merging in their work. + +To fork a project, visit the project page (in this case, mojombo/chronic) and click the "fork" button in the header (see Figure 4-14). + +Insert 18333fig0414.png +Figure 4-14. Get a writable copy of any repository by clicking the "fork" button. + +After a few seconds, you’re taken to your new project page, which indicates that this project is a fork of another one (see Figure 4-15). + +Insert 18333fig0415.png +Figure 4-15. Your fork of a project. + +### GitHub Summary ### + +That’s all we’ll cover about GitHub, but it’s important to note how quickly you can do all this. You can create an account, add a new project, and push to it in a matter of minutes. If your project is open source, you also get a huge community of developers who now have visibility into your project and may well fork it and help contribute to it. At the very least, this may be a way to get up and running with Git and try it out quickly. + +## Summary ## + +You have several options to get a remote Git repository up and running so that you can collaborate with others or share your work. + +Running your own server gives you a lot of control and allows you to run the server within your own firewall, but such a server generally requires a fair amount of your time to set up and maintain. If you place your data on a hosted server, it’s easy to set up and maintain; however, you have to be able to keep your code on someone else’s servers, and some organizations don’t allow that. + +It should be fairly straightforward to determine which solution or combination of solutions is appropriate for you and your organization. diff --git a/fa/NOTES.en-fa.md b/fa/NOTES.en-fa.md new file mode 100644 index 000000000..aef4537e1 --- /dev/null +++ b/fa/NOTES.en-fa.md @@ -0,0 +1,143 @@ +نکاتی در رابطه با ترجمه کتاب +====================== + +همان‌طور که اطلاع دارید کلمات تخصصی اکثر رشته‌ها در زبان فارسی مورد کم لطفی واقع شده‌اند و معمولاً معادل فارسی آن‌ها به صورت رسمی و مدون تعیین نشده‌اند. باالاجبار مترجمان جهت ترجمه این لغات به رای و نظر شخصی خود رجوع می‌کنند. بدین دلیل است که ممکن است برای یک عبارت تخصصی معادل‌های گوناگونی در کتب مختلف یافت شود. + +از آن جهت که ترجمه این کتاب به صورت گروهی انجام می‌پذیرد، برای جلوگیری از سردرگمی خواننده بعد از ترجمه کامل اثر سعی شده است تا لغت‌نامه کوچکی از کلمات کلیدی که در این کتاب به‌کار رفته شده است تهیه شود تا تمامی افرادی که در این کار گروهی شرکت می‌کنند از یک الگوی یکسان در ترجمه پیروی کنند. + +لذا از تمامی افرادی که در ترجمه این کتاب شرکت می‌کنند خواهشمندیم تا از این الگو پیروی کنند و همچنین اگر خود به کلمه کلیدی جدیدی برخورد کردند که در این لیست وجود ندارد، آن را به لیست اضافه کرده و حتی اگر جایگزین مناسبتری برای کلمه خاصی در نظر داشتند با هماهنگی دیگر مترجمان آن را جایگزین کنند. + +توجه: کلماتی که جایگزین مناسبی هنوز برای آن‌ها یافت نشده است، در قسمت معادل فارسی،همان عبارت انگلیسی کلمه آورده شده است. + + +archive +------- + + بایگانی + +branch +------ + + انشعاب + +checkout +-------- + + checkout + +checksum +-------- + + checksum + +clone +----- + + clone + + +commit +------ + + commit + +customize +--------- + + شخصی‌سازی + +diff +---- + + diff + +link +---- + + پیوند + +manpage +------- + + صفحه راهنما + +merge +----- + + merge + +metadata +-------- + + metadata + +option +------ + + گزینه + +package +------- + + بسته + + +patch +----- + +وصله + +platform +-------- + + platform + +push +---- + + push + +remote repository +----------------- + + مخزن خارجی + +repository +---------- + + مخزن + +revision +-------- + + نسخه + +snapshot +-------- + + تصویر لحظه‌ای + +staging area +------------ + + staging area + +state +----- + +وضعیت + +version +------- + +نسخه + +workflow +-------- + +جریان کاری + +working directory +----------------- + +پوشه در حال کار \ No newline at end of file diff --git a/fa/README.md b/fa/README.md new file mode 100644 index 000000000..95dab6b2c --- /dev/null +++ b/fa/README.md @@ -0,0 +1,7 @@ +# تلاش برای ترجمه فارسی # + +## لیست افراد حاضر در این پروژه ## +Oxtay +mxamin + +اگر شما هم برروی این ترجمه کار می‌کنید یا در نظر دارید که این کار را شروع کنید لطفآ به ما اطلاع دهید تا از دوباره کاری پرهیز شود. \ No newline at end of file diff --git a/fi/01-introduction/01-chapter1.markdown b/fi/01-introduction/01-chapter1.markdown index 8ca8f2b98..2c562dca0 100644 --- a/fi/01-introduction/01-chapter1.markdown +++ b/fi/01-introduction/01-chapter1.markdown @@ -97,26 +97,26 @@ Tämä tekee Gitin käyttämisestä hauskaa, koska me tiedämme, että voimme ko ### Kolme tilaa ### -Lue nyt huolellisesti. Tämä on pääasia muistaa Gitistä, jos sinä haluat lopun opiskeluprosessistasi menevän sulavasti. Gitillä on kolme pääasiallista tilaa, joissa tiedostosi voivat olla: pysyvästi muutettu (commited), muutettu (modified), ja lavastettu (staged). Pysyvästi muutettu tarkoittaa, että data on turvallisesti varastoitu sinun paikalliseen tietokantaasi. Muutettu tarkoittaa, että olet muuttanut tiedostoa, mutta et ole tehnyt vielä pysyvää muutosta tietokantaasi. Lavastettu tarkoittaa, että olet merkannut muutetun tiedoston nykyisessä versiossaan menemään seuraavaan pysyvään tilannekuvaan. +Lue nyt huolellisesti. Tämä on pääasia muistaa Gitistä, jos sinä haluat lopun opiskeluprosessistasi menevän sulavasti. Gitillä on kolme pääasiallista tilaa, joissa tiedostosi voivat olla: pysyvästi muutettu (commited), muutettu (modified), ja valmisteltu (staged). Pysyvästi muutettu tarkoittaa, että data on turvallisesti varastoitu sinun paikalliseen tietokantaasi. Muutettu tarkoittaa, että olet muuttanut tiedostoa, mutta et ole tehnyt vielä pysyvää muutosta tietokantaasi. Valmisteltu tarkoittaa, että olet merkannut muutetun tiedoston nykyisessä versiossaan menemään seuraavaan pysyvään tilannekuvaan. -Tämä johdattaa meidät kolmeen seuraavaan osaan Git-projektia: Git-hakemisto, työskentelyhakemisto, ja lavastusalue. +Tämä johdattaa meidät kolmeen seuraavaan osaan Git-projektia: Git-hakemisto, työskentelyhakemisto, ja valmistelualue. Insert 18333fig0106.png -Kuva 1-6. Työskentelyhakemisto, lavastusalue, ja Git-hakemisto. +Kuva 1-6. Työskentelyhakemisto, valmistelualue, ja Git-hakemisto. Git-hakemisto on paikka, johon Git varastoi metadatan ja oliotietokannan projektillesi. Tämä on kaikkein tärkein osa Gitiä, ja se sisältää sen, mitä kopioidaan, kun kloonaat tietovaraston toiselta tietokoneelta. Työskentelyhakemisto on yksittäinen tiedonhaku yhdestä projektin versiosta. Nämä tiedostot vedetään ulos pakatusta tietokannasta Git-hakemistosta ja sijoitetaan levylle sinun käytettäväksesi tai muokattavaksesi. -Lavastusalue on yksinkertainen tiedosto, yleensä se sisältyy Git-hakemistoosi, joka varastoi informaatiota siitä, mitä menee seuraavaan pysyvään muutokseen. Sitä viitataan joskus indeksiksi, mutta on tulossa standardiksi viitata sitä lavastusalueeksi. +Valmistelualue on yksinkertainen tiedosto, yleensä se sisältyy Git-hakemistoosi, joka varastoi informaatiota siitä, mitä menee seuraavaan pysyvään muutokseen. Sitä viitataan joskus indeksiksi, mutta on tulossa standardiksi viitata sitä valmistelualueeksi. Normaali Git-työnkulku menee jokseenkin näin: 1. Muokkaat tiedostoja työskentelyhakemistossasi. -2. Lavastat tiedostosi, lisäten niistä tilannekuvia lavastusalueellesi. -3. Teet pysyvän muutoksen, joka ottaa tiedostot sellaisina, kuin ne ovat lavastusalueella, ja varastoi tämän tilannekuvan pysyvästi sinun Git-tietolähteeseesi. +2. Valmistelet tiedostosi, lisäten niistä tilannekuvia valmistelualueellesi. +3. Teet pysyvän muutoksen, joka ottaa tiedostot sellaisina, kuin ne ovat valmistelualueella, ja varastoi tämän tilannekuvan pysyvästi sinun Git-tietolähteeseesi. -Jos tietty versio tiedostosta on Git-hakemistossa, se on yhtä kuin pysyvä muutos. Jos sitä on muokattu, mutta se on lisätty lavastusalueelle, se on lavastettu. Ja jos se on muuttunut siitä, kun se on haettu, mutta sitä ei ole lavastettu, se on muutettu. Luvussa 2 opit enemmän näistä tiloista ja kuinka voit hyödyntää niitä tai ohittaa lavastusosan kokonaan. +Jos tietty versio tiedostosta on Git-hakemistossa, se on yhtä kuin pysyvä muutos. Jos sitä on muokattu, mutta se on lisätty valmistelualueelle, se on valmisteltu. Ja jos se on muuttunut siitä, kun se on haettu, mutta sitä ei ole valmisteltu, se on muutettu. Luvussa 2 opit enemmän näistä tiloista ja kuinka voit hyödyntää niitä tai ohittaa valmisteluvaiheen kokonaan. ## Gitin asennus ## @@ -163,7 +163,7 @@ Tai jos olet Debian-pohjaisessa julkaisussa kuten Ubuntussa, kokeile apt-getiä: On olemassa kaksi helppoa tapaa asentaa Git Macissä. Helpoin on käyttää graafista Git-asennusohjelmaa, jonka voit ladata Googlen Code -verkkosivuilta (katso Kuva 1-7): - http://code.google.com/p/git-osx-installer + http://sourceforge.net/projects/git-osx-installer/ Insert 18333fig0107.png Kuva 1-7. Git OS X -asennusohjelma. diff --git a/fi/02-git-basics/01-chapter2.markdown b/fi/02-git-basics/01-chapter2.markdown index f5c7f1ab0..259e0b2cb 100644 --- a/fi/02-git-basics/01-chapter2.markdown +++ b/fi/02-git-basics/01-chapter2.markdown @@ -1,6 +1,6 @@ # Gitin perusteet # -Jos voit lukea vain yhden kappaleen päästäksesi vauhtiin Gitin kanssa, se on tämä kappale. Tämä kappale sisältää jokaisen peruskomennon, jonka tarvitset tehdäksesi valtavan määrän asioita, joiden kanssa viimein tulet käyttämään aikaasi Gitillä työskennellessäsi. Tämän kappaleen lopussa, sinun tulisi pystyä konfiguroimaan ja alustamaan tietolähde, aloittamaan ja lopettamaan tiedostojen jäljitys sekä lavastaa ja tehdä pysyviä muutoksia. Me myös näytämme sinulle kuinka asettaa Git niin, että se jättää tietyt tiedostot ja tiedostomallit huomioimatta, kuinka kumota virheet nopeasti ja helposti, kuinka selata projektisi historiaa ja tarkastella muutoksia pysyvien muutosten välillä sekä kuinka työntää ja vetää etätietolähteistä. +Jos voit lukea vain yhden kappaleen päästäksesi vauhtiin Gitin kanssa, se on tämä kappale. Tämä kappale sisältää jokaisen peruskomennon, jonka tarvitset tehdäksesi valtavan määrän asioita, joiden kanssa viimein tulet käyttämään aikaasi Gitillä työskennellessäsi. Tämän kappaleen lopussa, sinun tulisi pystyä konfiguroimaan ja alustamaan tietolähde, aloittamaan ja lopettamaan tiedostojen jäljitys sekä valmistelemaan ja tehdä pysyviä muutoksia. Me myös näytämme sinulle kuinka asettaa Git niin, että se jättää tietyt tiedostot ja tiedostomallit huomioimatta, kuinka kumota virheet nopeasti ja helposti, kuinka selata projektisi historiaa ja tarkastella muutoksia pysyvien muutosten välillä sekä kuinka työntää ja vetää etätietolähteistä. ## Git-tietolähteen hankinta ## @@ -42,9 +42,9 @@ Gitissä on monta erilaista siirtoprotokollaa, joita voit käyttää. Edellinen Sinulla on oikea Git-tietolähde ja tiedonhaku (checkout) tai työkopio projektin tiedostoista. Sinun täytyy tehdä joitain muutoksia ja pysyviä tilannekuvia näistä muutoksista sinun tietolähteeseesi joka kerta, kun projekti saavuttaa tilan, jonka haluat tallentaa. -Muista, että jokainen tiedosto työhakemistossasi voi olla yhdessä kahdesta tilasta: *jäljitetty* tai *jäljittämätön*. *Jäljitetyt* tiedostot ovat tiedostoja, jotka olivat viimeisimmässä tilannekuvassa; ne voivat olla *muokkaamattomia*, *muokattuja* tai *lavastettuja*. *Jäljittämättömät* tiedostot ovat kaikkea muuta - mitkä tahansa tiedostoja työhakemistossasi, jotka eivät olleet viimeisimmässä tilannekuvassa ja jotka eivät ole lavastusalueella. Kun ensimmäisen kerran kloonaat tietolähteen, kaikki tiedostoistasi tulevat olemaan jäljitettyjä ja muokkaamattomia, koska sinä juuri hait ne etkä ole muokannut vielä mitään. +Muista, että jokainen tiedosto työhakemistossasi voi olla yhdessä kahdesta tilasta: *jäljitetty* tai *jäljittämätön*. *Jäljitetyt* tiedostot ovat tiedostoja, jotka olivat viimeisimmässä tilannekuvassa; ne voivat olla *muokkaamattomia*, *muokattuja* tai *valmisteltuja*. *Jäljittämättömät* tiedostot ovat kaikkea muuta - mitkä tahansa tiedostoja työhakemistossasi, jotka eivät olleet viimeisimmässä tilannekuvassa ja jotka eivät ole valmistelualueella. Kun ensimmäisen kerran kloonaat tietolähteen, kaikki tiedostoistasi tulevat olemaan jäljitettyjä ja muokkaamattomia, koska sinä juuri hait ne etkä ole muokannut vielä mitään. -Editoidessasi tiedostoja Git näkee ne muokattuina, koska olet muuttanut niitä viimeisimmän pysyvän muutoksen jälkeen. *Lavastat* nämä muutetut tiedostot, jonka jälkeen muutat kaikki lavastetut muutokset pysyvästi, ja sykli toistuu. Tämä elämänsykli on kuvattu Kuvassa 2-1. +Editoidessasi tiedostoja Git näkee ne muokattuina, koska olet muuttanut niitä viimeisimmän pysyvän muutoksen jälkeen. *Valmistelet* nämä muutetut tiedostot, jonka jälkeen muutat kaikki valmistellut muutokset pysyvästi, ja sykli toistuu. Tämä elämänsykli on kuvattu Kuvassa 2-1. Insert 18333fig0201.png Kuva 2-1. Tiedostojesi tilan elämänsykli. @@ -55,7 +55,7 @@ Päätyökalu tiedostojesi eri tilojen selvittämiseen on `git status` -komento. $ git status # On branch master - nothing to commit (working directory clean) + nothing to commit, working directory clean Tämä tarkoittaa, että sinulla on puhdas työhakemisto - toisin sanoen, jäljitettyjä tiedostoja ei ole muutettu. Git ei myöskään näe yhtään jäljittämätöntä tiedostoa, muuten ne olisi listattu näkymään. Lopuksi komento kertoo sinulle missä haarassa olet. Tällä hetkellä se on aina `master`-haara, joka on oletusarvo; sinun ei tarvitse huolehtia siitä nyt. Seuraava luku käy läpi haarautumiset ja viittaukset yksityiskohtaisesti. @@ -78,7 +78,7 @@ Jotta voisit jäljittää uusia tiedostoja, sinun täytyy käyttää `git add` - $ git add README -Jos ajat status-komennon uudestaan, näet että `README`-tiedostosi on nyt jäljitetty ja lavastettu: +Jos ajat status-komennon uudestaan, näet että `README`-tiedostosi on nyt jäljitetty ja valmisteltu: $ git status # On branch master @@ -88,9 +88,9 @@ Jos ajat status-komennon uudestaan, näet että `README`-tiedostosi on nyt jälj # new file: README # -Voit nähdä, että se on lavastettu, koska se on otsikon ”Changes to be committed” alla. Jos teet pysyvän muutoksen tässä kohtaa, versio tiedostosta sillä hetkellä kun ajoit `git add` -komennon on se, joka tulee olemaan historian tilannekuvassa. Voit palauttaa mieleen hetken, jolloin ajoit `git init` -komennon aikaisemmin, ajoit sen jälkeen `git add (tiedostot)` -komennon - tämä komento aloitti tiedostojen jäljittämisen hakemistossa. `Git add` -komento ottaa polun nimen joko tiedostolle tai hakemistolle; jos se on hakemisto, komento lisää kaikki tiedostot hakemiston alta rekursiivisesti. +Voit nähdä, että se on valmisteltu, koska se on otsikon ”Changes to be committed” alla. Jos teet pysyvän muutoksen tässä kohtaa, versio tiedostosta sillä hetkellä kun ajoit `git add` -komennon on se, joka tulee olemaan historian tilannekuvassa. Voit palauttaa mieleen hetken, jolloin ajoit `git init` -komennon aikaisemmin, ajoit sen jälkeen `git add (tiedostot)` -komennon - tämä komento aloitti tiedostojen jäljittämisen hakemistossa. `Git add` -komento ottaa polun nimen joko tiedostolle tai hakemistolle; jos se on hakemisto, komento lisää kaikki tiedostot hakemiston alta rekursiivisesti. -### Muutettujen tiedostojen lavastus ### +### Muutettujen tiedostojen valmistelu ### Muutetaanpa tiedostoa, joka on jo jäljitetty. Jos muutat aikaisemmin jäljitettyä `benchmarks.rb`-tiedostoa ja sen jälkeen ajat `status`-komennon uudestaan, saat suunnilleen tämän näköisen tulosteen: @@ -107,7 +107,7 @@ Muutetaanpa tiedostoa, joka on jo jäljitetty. Jos muutat aikaisemmin jäljitett # modified: benchmarks.rb # -`Benchmarks.rb`-tiedosto näkyy kohdan ”Changes not staged for commit” alla - mikä tarkoittaa, että tiedostoa, jota jäljitetään, on muokattu työskentelyhakemistossa, mutta sitä ei vielä ole lavastettu. Lavastaaksesi sen, ajat `git add` -komennon (se on monitoimikomento - käytät sitä aloittaaksesi uusien tiedostojen jäljittämisen, lavastaaksesi tiedostoja, ja tehdäksesi muita asioita, kuten merkataksesi liitoskonfliktitiedostot ratkaistuksi). Ajetaanpa nyt `git add` -komento lavastaaksemme `benchmarks.rb`-tiedoston, ja ajetaan sitten `git status` -komento uudestaan: +`Benchmarks.rb`-tiedosto näkyy kohdan ”Changes not staged for commit” alla - mikä tarkoittaa, että tiedostoa, jota jäljitetään, on muokattu työskentelyhakemistossa, mutta sitä ei vielä ole valmisteltu. Valmistellaksesi sen, ajat `git add` -komennon (se on monitoimikomento - käytät sitä aloittaaksesi uusien tiedostojen jäljittämisen, valmistellaksesi tiedostoja, ja tehdäksesi muita asioita, kuten merkataksesi liitoskonfliktitiedostot ratkaistuksi). Ajetaanpa nyt `git add` -komento valmistellaksemme `benchmarks.rb`-tiedoston, ja ajetaan sitten `git status` -komento uudestaan: $ git add benchmarks.rb $ git status @@ -119,7 +119,7 @@ Muutetaanpa tiedostoa, joka on jo jäljitetty. Jos muutat aikaisemmin jäljitett # modified: benchmarks.rb # -Kummatkin tiedostot ovat lavastettuja ja tulevat menemään seuraavaan pysyvään muutokseen. Oletetaan, että tässä kohdassa muistat pienen muutoksen, jonka haluat tehdä `benchmarks.rb`-tiedostoon, ennen kuin teet pysyvää muutosta. Avaat tiedoston uudestaan ja muutat sitä, jonka jälkeen olet valmis tekemään pysyvän muutoksen. Ajetaan silti `git status` -komento vielä kerran: +Kummatkin tiedostot ovat valmisteltuja ja tulevat menemään seuraavaan pysyvään muutokseen. Oletetaan, että tässä kohdassa muistat pienen muutoksen, jonka haluat tehdä `benchmarks.rb`-tiedostoon, ennen kuin teet pysyvää muutosta. Avaat tiedoston uudestaan ja muutat sitä, jonka jälkeen olet valmis tekemään pysyvän muutoksen. Ajetaan silti `git status` -komento vielä kerran: $ vim benchmarks.rb $ git status @@ -136,7 +136,7 @@ Kummatkin tiedostot ovat lavastettuja ja tulevat menemään seuraavaan pysyvää # modified: benchmarks.rb # -Mitä ihmettä? Nyt `benchmarks.rb` on listattu sekä lavastettuna että lavastamattomana. Miten se on mahdollista? Tapahtuu niin, että Git lavastaa tiedoston juuri sellaisena kuin se on, kun ajat `git add` -komennon. Jos teet pysyvän muutoksen nyt, `benchmark.rb`-tiedoston versio sillä hetkellä, kun ajoit `git add` -komennon, on se, joka menee tähän pysyvään muutokseen, eikä se tiedoston versio, joka on työskentelyhakemistossasi sillä hetkellä, kun ajat `git commit` -komennon. Jos muutat tiedostoa sen jälkeen, kun olet ajanut `git add` -komennon, sinun täytyy ajaa `git add` uudestaan lavastaaksesi uusimman version tiedostosta: +Mitä ihmettä? Nyt `benchmarks.rb` on listattu sekä valmisteltuna että valmistelemattomana. Miten se on mahdollista? Tapahtuu niin, että Git valmistelee tiedoston juuri sellaisena kuin se on, kun ajat `git add` -komennon. Jos teet pysyvän muutoksen nyt, `benchmark.rb`-tiedoston versio sillä hetkellä, kun ajoit `git add` -komennon, on se, joka menee tähän pysyvään muutokseen, eikä se tiedoston versio, joka on työskentelyhakemistossasi sillä hetkellä, kun ajat `git commit` -komennon. Jos muutat tiedostoa sen jälkeen, kun olet ajanut `git add` -komennon, sinun täytyy ajaa `git add` uudestaan valmistellaksesi uusimman version tiedostosta: $ git add benchmarks.rb $ git status @@ -185,11 +185,11 @@ Tässä toinen esimerkki .gitignore-tiedostosta: `**/`-malli on saatavilla Gitin versiosta 1.8.2 lähtien. -### Lavastettujen ja lavastamattomien muutosten tarkastelu ### +### Valmisteltujen ja valmistelemattomien muutosten tarkastelu ### -Jos `git status` -komento on liian epämääräinen sinulle - haluat tietää tarkalleen mitä on muutettu, et ainoastaan sitä, mitkä tiedostot ovat muuttuneet - voit käyttää `git diff` -komentoa. Me käsittelemme `git diff` -kommenon yksityiskohtaisesti myöhemmin; mutta sinä tulet mahdollisesti käyttämään sitä useasti, vastataksesi näihin kahteen kysymykseen: Mitä olet muuttanut, mutta et ole vielä lavastanut? Ja mitä sellaista olet lavastanut, josta olet tekemässä pysyvän muutoksen? Vaikkakin `git status` vastaa näihin kysymyksiin yleisesti, `git diff` näyttää sinulle tarkalleen ne rivit, jotka on lisätty ja poistettu - vähän niin kuin pätsi. +Jos `git status` -komento on liian epämääräinen sinulle - haluat tietää tarkalleen mitä on muutettu, et ainoastaan sitä, mitkä tiedostot ovat muuttuneet - voit käyttää `git diff` -komentoa. Me käsittelemme `git diff` -kommenon yksityiskohtaisesti myöhemmin; mutta sinä tulet mahdollisesti käyttämään sitä useasti, vastataksesi näihin kahteen kysymykseen: Mitä olet muuttanut, mutta et ole vielä valmistellut? Ja mitä sellaista olet valmistellut, josta olet tekemässä pysyvän muutoksen? Vaikkakin `git status` vastaa näihin kysymyksiin yleisesti, `git diff` näyttää sinulle tarkalleen ne rivit, jotka on lisätty ja poistettu - vähän niin kuin pätsi. -Sanotaan vaikka, että muokkaat ja lavastat `README`-tiedostoa uudestaan, jonka jälkeen muokkaat `benchmarks.rb`-tiedostoa, ilman että lavastat sitä. Jos ajat `status`-komennon, näet jälleen kerran jotain tällaista: +Sanotaan vaikka, että muokkaat ja valmistelet `README`-tiedostoa uudestaan, jonka jälkeen muokkaat `benchmarks.rb`-tiedostoa, ilman että valmistelet sitä. Jos ajat `status`-komennon, näet jälleen kerran jotain tällaista: $ git status # On branch master @@ -204,7 +204,7 @@ Sanotaan vaikka, että muokkaat ja lavastat `README`-tiedostoa uudestaan, jonka # modified: benchmarks.rb # -Nähdäksesi, mitä olet muuttanut, mutta et vielä lavastanut, kirjoita `git diff` ilman mitään muita argumentteja: +Nähdäksesi, mitä olet muuttanut, mutta et vielä valmistellut, kirjoita `git diff` ilman mitään muita argumentteja: $ git diff diff --git a/benchmarks.rb b/benchmarks.rb @@ -223,9 +223,9 @@ Nähdäksesi, mitä olet muuttanut, mutta et vielä lavastanut, kirjoita `git di log = git.commits('master', 15) log.size -Tämä komento vertailee sitä, mitä sinun työskentelyhakemistossa on verrattuna siihen, mitä sinun lavastusalueellasi on. Tulos kertoo tekemäsi muutokset, joita et ole vielä lavastanut. +Tämä komento vertailee sitä, mitä sinun työskentelyhakemistossa on verrattuna siihen, mitä sinun valmistelualueellasi on. Tulos kertoo tekemäsi muutokset, joita et ole vielä valmistellut. -Jos haluat nähdä, mitä sellaista olet lavastanut, joka menee seuraavaan pysyvään muutokseen, voit käyttää `git diff --cached` -komentoa. (Gitin versiosta 1.6.1 lähtien voit käyttää myös `git diff --staged` -komentoa, joka on helpompi muistaa.) Tämä komento vertailee lavastettuja muutoksia viimeisimpään pysyvään muutokseen. +Jos haluat nähdä, mitä sellaista olet valmistellut, joka menee seuraavaan pysyvään muutokseen, voit käyttää `git diff --cached` -komentoa. (Gitin versiosta 1.6.1 lähtien voit käyttää myös `git diff --staged` -komentoa, joka on helpompi muistaa.) Tämä komento vertailee valmisteltuja muutoksia viimeisimpään pysyvään muutokseen. $ git diff --cached diff --git a/README b/README @@ -240,9 +240,9 @@ Jos haluat nähdä, mitä sellaista olet lavastanut, joka menee seuraavaan pysyv + +Grit is a Ruby library for extracting information from a Git repository -On tärkeää ottaa huomioon, että `git diff` itsessään ei näytä kaikkia muutoksia viimeisimmästä pysyvästä muutoksesta lähtien - vain muutokset, jotka ovat yhä lavastamattomia. Tämä voi olla sekavaa, koska kun olet lavastanut kaikki muutoksesi, `git diff` ei anna ollenkaan tulostetta. +On tärkeää ottaa huomioon, että `git diff` itsessään ei näytä kaikkia muutoksia viimeisimmästä pysyvästä muutoksesta lähtien - vain muutokset, jotka ovat yhä valmistelemattomia. Tämä voi olla sekavaa, koska kun olet valmistellut kaikki muutoksesi, `git diff` ei anna ollenkaan tulostetta. -Toisena esimerkkinä, jos lavastat `benchmarks.rb`-tiedoston ja sitten muokkaat sitä, voit käyttää `git diff` -komentoa nähdäksesi tiedoston lavastetut muutokset ja lavastamattomat muutokset: +Toisena esimerkkinä, jos valmistelet `benchmarks.rb`-tiedoston ja sitten muokkaat sitä, voit käyttää `git diff` -komentoa nähdäksesi tiedoston valmistellut muutokset ja valmistelemattomat muutokset: $ git add benchmarks.rb $ echo '# test line' >> benchmarks.rb @@ -258,7 +258,7 @@ Toisena esimerkkinä, jos lavastat `benchmarks.rb`-tiedoston ja sitten muokkaat # modified: benchmarks.rb # -Nyt voit käyttää `git diff` -komentoa nähdäksesi, mitä on yhä lavastamatta: +Nyt voit käyttää `git diff` -komentoa nähdäksesi, mitä on yhä valmistelematta: $ git diff diff --git a/benchmarks.rb b/benchmarks.rb @@ -271,7 +271,7 @@ Nyt voit käyttää `git diff` -komentoa nähdäksesi, mitä on yhä lavastamatt ##pp Grit::GitRuby.cache_client.stats +# test line -Ja `git diff --cached` -komentoa nähdäksesi, mitä olet lavastanut tähän mennessä: +Ja `git diff --cached` -komentoa nähdäksesi, mitä olet valmistellut tähän mennessä: $ git diff --cached diff --git a/benchmarks.rb b/benchmarks.rb @@ -292,8 +292,8 @@ Ja `git diff --cached` -komentoa nähdäksesi, mitä olet lavastanut tähän men ### Pysyvien muutoksien tekeminen ### -Nyt, kun lavastusalueesi on asetettu niin kuin sen haluat, voit tehdä muutoksistasi pysyviä. Muista, että kaikki, mikä vielä on lavastamatta - mitkä tahansa tiedostot, jotka olet luonut tai joita olet muokannut, joihin et ole ajanut `git add` -komentoa editoinnin jälkeen - eivät mene pysyvään muutokseen. Ne pysyvät muokattuina tiedostoina levylläsi. -Tässä tapauksessa oletamme, että viime kerran, kun ajoit `git status` -komennon, näit, että kaikki oli lavastettu, joten olet valmis tekemään pysyvän muutoksen. Helpoin tapa pysyvän muutoksen tekoon on kirjoittaa `git commit`: +Nyt, kun valmistelualueesi on asetettu niin kuin sen haluat, voit tehdä muutoksistasi pysyviä. Muista, että kaikki, mikä vielä on valmistelematta - mitkä tahansa tiedostot, jotka olet luonut tai joita olet muokannut, joihin et ole ajanut `git add` -komentoa editoinnin jälkeen - eivät mene pysyvään muutokseen. Ne pysyvät muokattuina tiedostoina levylläsi. +Tässä tapauksessa oletamme, että viime kerran, kun ajoit `git status` -komennon, näit, että kaikki oli valmisteltu, joten olet valmis tekemään pysyvän muutoksen. Helpoin tapa pysyvän muutoksen tekoon on kirjoittaa `git commit`: $ git commit @@ -325,11 +325,11 @@ Vaihtoehtoisesti, voit kirjoittaa pysyvän muutoksen viestin suoraan `commit`-ko Nyt olet luonut ensimmäisen pysyvän muutoksen! Voit nähdä, että pysyvä muutos on antanut sinulle tulosteen itsestään: kertoen mihin haaraan teit pysyvän muutoksen (`master`), mikä SHA-1 tarkistussumma pysyvällä muutoksella on (`463dc4f`), kuinka monta tiedostoa muutettiin ja tilastoja pysyvän muutoksen rivien lisäyksistä ja poistoista. -Muista, että pysyvä muutos tallentaa tilannekuvan lavastusalueestasi. Kaikki, mitä et lavastanut on yhä istumassa projektissasi muokattuna; voit tehdä toisen pysyvän muutoksen lisätäksesi ne historiaasi. Joka kerta, kun teet pysyvän muutoksen, olet tallentamassa tilannekuvaa projektistasi. Tilannekuvaa, johon voit palata tai jota voit vertailla myöhemmin. +Muista, että pysyvä muutos tallentaa tilannekuvan valmistelualueestasi. Kaikki, mitä et valmistellut on yhä istumassa projektissasi muokattuna; voit tehdä toisen pysyvän muutoksen lisätäksesi ne historiaasi. Joka kerta, kun teet pysyvän muutoksen, olet tallentamassa tilannekuvaa projektistasi. Tilannekuvaa, johon voit palata tai jota voit vertailla myöhemmin. -### Lavastusalueen ohittaminen ### +### Valmistelualueen ohittaminen ### -Vaikka lavastusalue voi olla uskomattoman hyödyllinen pysyvien muutoksien tekoon tarkalleen niin kuin ne haluat, on lavastusalue joskus hieman liian monimutkainen, kuin mitä työnkulussasi tarvitsisit. Jos haluat ohittaa lavastusalueen, Git tarjoaa siihen helpon oikoreitin. Antamalla `-a`-option `git commit` -komennolle, asettaa Gitin automaattisesti lavastamaan jokaisen jo jäljitetyn tiedoston ennen pysyvää muutosta, antaen sinun ohittaa `git add` -osan: +Vaikka valmistelualue voi olla uskomattoman hyödyllinen pysyvien muutoksien tekoon tarkalleen niin kuin ne haluat, on valmistelualue joskus hieman liian monimutkainen, kuin mitä työnkulussasi tarvitsisit. Jos haluat ohittaa valmistelualueen, Git tarjoaa siihen helpon oikoreitin. Antamalla `-a`-option `git commit` -komennolle, asettaa Gitin automaattisesti valmistelemaan jokaisen jo jäljitetyn tiedoston ennen pysyvää muutosta, antaen sinun ohittaa `git add` -osan: $ git status # On branch master @@ -346,9 +346,9 @@ Huomaa, miten sinun ei tarvitse ajaa `git add` -komentoa `benchmarks.rb`-tiedost ### Tiedostojen poistaminen ### -Poistaaksesi tiedoston Gitistä, sinun täytyy poistaa se sinun jäljitetyistä tiedostoistasi (tarkemmin sanoen, poistaa se lavastusalueeltasi) ja sitten tehdä pysyvä muutos. Komento `git rm` tekee tämän ja myös poistaa tiedoston työskentelyhakemistostasi, joten et näe sitä enää jäljittämättömänä tiedostona. +Poistaaksesi tiedoston Gitistä, sinun täytyy poistaa se sinun jäljitetyistä tiedostoistasi (tarkemmin sanoen, poistaa se valmistelualueeltasi) ja sitten tehdä pysyvä muutos. Komento `git rm` tekee tämän ja myös poistaa tiedoston työskentelyhakemistostasi, joten et näe sitä enää jäljittämättömänä tiedostona. -Jos yksinkertaisesti poistat tiedoston työskentelyhakemistostasi, näkyy se ”Changes not staged for commit” otsikon alla (se on, _lavastamaton_) `git status` -tulosteessasi: +Jos yksinkertaisesti poistat tiedoston työskentelyhakemistostasi, näkyy se ”Changes not staged for commit” otsikon alla (se on, _valmistelematon_) `git status` -tulosteessasi: $ rm grit.gemspec $ git status @@ -360,7 +360,7 @@ Jos yksinkertaisesti poistat tiedoston työskentelyhakemistostasi, näkyy se ” # deleted: grit.gemspec # -Jos ajat tämän jälkeen `git rm` -komennon, se lavastaa tiedostot poistoon: +Jos ajat tämän jälkeen `git rm` -komennon, se valmistelee tiedostot poistoon: $ git rm grit.gemspec rm 'grit.gemspec' @@ -375,7 +375,7 @@ Jos ajat tämän jälkeen `git rm` -komennon, se lavastaa tiedostot poistoon: Seuraavan kerran, kun teet pysyvän muutoksen, tiedosto katoaa ja sitä ei jäljitetä enää. Jos muokkasit tiedostoa ja lisäsit sen jo indeksiin, täytyy sinun pakottaa poisto `-f`-optiolla. Tämä on turvallisuusominaisuus, joka estää vahingossa tapahtuvan datan poistamisen, datan, jota ei ole vielä tallennettu tilannekuvaksi ja jota ei voida palauttaa Gitistä. -Toinen hyödyllinen asia, jonka saatat haluta tehdä, on tiedoston pitäminen työskentelypuussa, mutta samalla sen poistaminen lavastusalueelta. Toisin sanoen, voit haluta pitää tiedoston kovalevylläsi, mutta et halua, että Git jäljittää sitä enää. Tämä on erityisesti hyödyllinen, jos unohdit lisätä jotain `.gitignore`-tiedostoosi ja vahingossa lavastit sellaisen, kuten suuri lokitiedosto tai joukko `.a`-muotoon käännettyjä tiedostoja. Tehdäksesi tämän, käytä `--cached`-optiota: +Toinen hyödyllinen asia, jonka saatat haluta tehdä, on tiedoston pitäminen työskentelypuussa, mutta samalla sen poistaminen valmistelualueelta. Toisin sanoen, voit haluta pitää tiedoston kovalevylläsi, mutta et halua, että Git jäljittää sitä enää. Tämä on erityisesti hyödyllinen, jos unohdit lisätä jotain `.gitignore`-tiedostoosi ja vahingossa valmistelit sellaisen, kuten suuri lokitiedosto tai joukko `.a`-muotoon käännettyjä tiedostoja. Tehdäksesi tämän, käytä `--cached`-optiota: $ git rm --cached readme.txt @@ -682,11 +682,11 @@ Yksi yleinen kumoaminen tapahtuu, kun teet pysyvän muutoksen liian aikaisin ja $ git commit --amend -Tämä komento ottaa lavastusalueesi ja käyttää sitä pysyvään muutokseen. Jos et ole tehnyt muutoksia viimeisimmän pysyvän muutoksesi jälkeen (esimerkiksi, jos ajat tämän komennon heti edellisen pysyvän muutoksesi jälkeen), tilannekuvasi näyttää tarkalleen samalta ja kaikki, mitä muutat, on pysyvän muutoksesi viesti. +Tämä komento ottaa valmistelualueesi ja käyttää sitä pysyvään muutokseen. Jos et ole tehnyt muutoksia viimeisimmän pysyvän muutoksesi jälkeen (esimerkiksi, jos ajat tämän komennon heti edellisen pysyvän muutoksesi jälkeen), tilannekuvasi näyttää tarkalleen samalta ja kaikki, mitä muutat, on pysyvän muutoksesi viesti. Sama pysyvän muutoksen viestin editori aktivoituu, mutta se sisältää jo viestin edellisestä pysyvästä muutoksesta. Voit muokata viestiä samoin kuin aina, mutta se korvaa edellisen pysyvän muutoksesi. -Esimerkkinä, jos teet pysyvän muutoksen ja sitten huomaat unohtaneesi lavastaa muutokset tiedostossa, jonka haluat lisätä tähän pysyvään muutokseen, voit tehdä jotakuinkin seuraavasti: +Esimerkkinä, jos teet pysyvän muutoksen ja sitten huomaat unohtaneesi valmistelee muutokset tiedostossa, jonka haluat lisätä tähän pysyvään muutokseen, voit tehdä jotakuinkin seuraavasti: $ git commit -m 'initial commit' $ git add unohtunut_tiedosto @@ -694,9 +694,9 @@ Esimerkkinä, jos teet pysyvän muutoksen ja sitten huomaat unohtaneesi lavastaa Näiden kolmen komennon jälkeen päädyt yhteen pysyvään muutokseen — toinen pysyvä muutos korvaa ensimmäisen. -### Lavastetun tiedoston lavastuksen purkaminen ### +### Valmistellun tiedoston valmistelun purkaminen ### -Kaksi seuraavaa kappaletta havainnollistavat, kuinka paimentaa muutoksia lavastusalueellasi ja työskentelyhakemistossasi. Mukava osa on, että komento, jota käytät selvittääksesi näiden kahden alueen tilan, muistuttaa sinua myös, kuinka peruuttaa muutokset niihin. Sanokaamme, esimerkiksi, että olet muuttanut kahta tiedostoa ja haluat tehdä niistä kaksi erillistä pysyvää muutosta, mutta kirjoitit vahingossa `git add *` ja lavastit ne molemmat. Kuinka voit purkaa toisen lavastuksen? `Git status` -komento muistuttaa sinua: +Kaksi seuraavaa kappaletta havainnollistavat, kuinka paimentaa muutoksia valmistelualueellasi ja työskentelyhakemistossasi. Mukava osa on, että komento, jota käytät selvittääksesi näiden kahden alueen tilan, muistuttaa sinua myös, kuinka peruuttaa muutokset niihin. Sanokaamme, esimerkiksi, että olet muuttanut kahta tiedostoa ja haluat tehdä niistä kaksi erillistä pysyvää muutosta, mutta kirjoitit vahingossa `git add *` ja valmistelit ne molemmat. Kuinka voit purkaa toisen valmistelun? `Git status` -komento muistuttaa sinua: $ git add . $ git status @@ -708,7 +708,7 @@ Kaksi seuraavaa kappaletta havainnollistavat, kuinka paimentaa muutoksia lavastu # modified: benchmarks.rb # -Heti ”Changes to be committed” -tekstin alla, sanotaan "use `git reset HEAD ...` to unstage". Joten, käyttäkäämme tätä neuvoa purkaaksemme `benchmarks.rb`-tiedoston lavastuksen: +Heti ”Changes to be committed” -tekstin alla, sanotaan "use `git reset HEAD ...` to unstage". Joten, käyttäkäämme tätä neuvoa purkaaksemme `benchmarks.rb`-tiedoston valmistelun: $ git reset HEAD benchmarks.rb benchmarks.rb: locally modified @@ -726,11 +726,11 @@ Heti ”Changes to be committed” -tekstin alla, sanotaan "use `git reset HEAD # modified: benchmarks.rb # -Komento on hieman kummallinen, mutta se toimii. `Benchmarks.rb`-tiedosto on muokattu mutta lavastamaton jälleen. +Komento on hieman kummallinen, mutta se toimii. `Benchmarks.rb`-tiedosto on muokattu mutta valmistelematon jälleen. ### Muutetun tiedoston muutosten kumoaminen ### -Mitä, jos tajuat, ettet halua säilyttää muutoksiasi `benchmarks.rb`-tiedostoon? Kuinka voit helposti kumota sen muutokset — palauttaa sen takaisin sellaiseksi, miltä se näytti, kun teit viimeksi pysyvän muutoksen (tai alun perin kloonasit tai miten saitkaan sen työskentelyhakemistoosi)? Onneksi `git status` kertoo sinulle myös, miten tämä tehdään. Edellisessä esimerkkitulosteessa lavastamaton alue näyttää tältä: +Mitä, jos tajuat, ettet halua säilyttää muutoksiasi `benchmarks.rb`-tiedostoon? Kuinka voit helposti kumota sen muutokset — palauttaa sen takaisin sellaiseksi, miltä se näytti, kun teit viimeksi pysyvän muutoksen (tai alun perin kloonasit tai miten saitkaan sen työskentelyhakemistoosi)? Onneksi `git status` kertoo sinulle myös, miten tämä tehdään. Edellisessä esimerkkitulosteessa valmistelematon alue näyttää tältä: # Changes not staged for commit: # (use "git add ..." to update what will be committed) diff --git a/fi/NOTES b/fi/NOTES index fef3c2fe5..84cb89f3c 100644 --- a/fi/NOTES +++ b/fi/NOTES @@ -1,4 +1,5 @@ Chapter 1 - Line 56: What is a proper finnish translation for the word "snapshot" in this case? Translated now as 'tilannekuvat'. Multiline: What is a proper finnish translation for the word "commit" in this case? Or do we need it, is permanen change (like it is now) enought to tell what it is about? - Chapter "The Three Stages" ("Kolme tilaa") has mentioned the "staged" word, what is correct translation for this in finnish? Now translated as "lavastettu". + Chapter "The Three Stages" ("Kolme tilaa") has mentioned the "staged" word, what is correct translation for this in finnish? Was translated as "lavastettu". + -> "lavastettu" is an obvious but bad choice, because it's based on another meaning of "stage", not the one that Git uses. Now translated as "valmisteltu". Line 230: Translation for a word "Backports" diff --git a/fr/01-introduction/01-chapter1.markdown b/fr/01-introduction/01-chapter1.markdown index 73cb6bee2..9985aa6f0 100644 --- a/fr/01-introduction/01-chapter1.markdown +++ b/fr/01-introduction/01-chapter1.markdown @@ -118,7 +118,7 @@ Nous explorerons les bénéfices qu'il y a à penser les données de cette mani ### Presque toutes les opérations sont locales ### -La plupart des opérations de Git ne nécessite que des fichiers et ressources locaux — généralement aucune information venant d'un autre ordinateur du réseau n'est nécessaire. +La plupart des opérations de Git ne nécessitent que des fichiers et ressources locaux — généralement aucune information venant d'un autre ordinateur du réseau n'est nécessaire. Si vous êtes habitué à un CVCS où toutes les opérations sont ralenties par la latence des échanges réseau, cet aspect de Git vous fera penser que les dieux de la vitesse ont octroyé leurs pouvoirs à Git. Comme vous disposez de l'historique complet du projet localement sur votre disque dur, la plupart des opérations semblent instantanées. @@ -239,7 +239,7 @@ Après ceci, vous pouvez obtenir Git par Git lui-même pour les mises à jour : Si vous souhaitez installer Git sur Linux via un installateur d'application, vous pouvez généralement le faire via le système de gestion de paquets de base fourni avec votre distribution. Si vous êtes sur Fedora, vous pouvez utiliser yum : - $ yum install git-core + $ yum install git Si vous êtes sur un système basé sur Debian, tel qu'Ubuntu, essayez apt-get : @@ -248,9 +248,9 @@ Si vous êtes sur un système basé sur Debian, tel qu'Ubuntu, essayez apt-get  ### Installation sur Mac ### Il y a deux moyens simples d'installer Git sur Mac. -Le plus simple et d'utiliser l'installateur graphique de Git que vous pouvez télécharger depuis les pages Google Code (voir figure 1-7) : +Le plus simple et d'utiliser l'installateur graphique de Git que vous pouvez télécharger depuis les pages SourceForge (voir figure 1-7) : - http://code.google.com/p/git-osx-installer + http://sourceforge.net/projects/git-osx-installer/ Insert 18333fig0107.png Figure 1-7. Installateur OS X de Git. @@ -268,7 +268,7 @@ Installer Git sur Windows est très facile. Le projet msysGit fournit une des procédures d'installation les plus simples. Téléchargez simplement le fichier exe d'installateur depuis la page GitHub, et lancez-le : - http://msysgit.github.com/ + http://msysgit.github.io Après son installation, vous avez à la fois la version en ligne de commande (avec un client SSH utile pour la suite) et l'interface graphique standard. @@ -291,10 +291,10 @@ Ces variables peuvent être stockées dans trois endroits différents : Si vous passez l'option `--system` à `git config`, il lit et écrit ce fichier spécifiquement. * Fichier `~/.gitconfig` : Spécifique à votre utilisateur. Vous pouvez forcer Git à lire et écrire ce fichier en passant l'option `--global`. -* Fichier `config` dans le répertoire Git (c'est à dire `.git/config`) du dépôt en cours d'utilisation : spécifique au seul dépôt en cours. +* Fichier `config` dans le répertoire Git (c'est-à-dire `.git/config`) du dépôt en cours d'utilisation : spécifique au seul dépôt en cours. Chaque niveau surcharge le niveau précédent, donc les valeurs dans `.git/config` surchargent celles de `/etc/gitconfig`. -Sur les systèmes Windows, Git recherche le fichier `.gitconfig` dans le répertoire `$HOME` (`%USERPROFILE%` dans l'environement natif de Windows) qui est `C:\Documents and Settings\$USER` ou `C:\Users\$USER` la plupart du temps, selon la version (`$USER` devient `%USERNAME%` dans l'environement de Windows). +Sur les systèmes Windows, Git recherche le fichier `.gitconfig` dans le répertoire `$HOME` (`%USERPROFILE%` dans l’environnement natif de Windows) qui est `C:\Documents and Settings\$USER` ou `C:\Users\$USER` la plupart du temps, selon la version (`$USER` devient `%USERNAME%` dans l’environnement de Windows). Il recherche tout de même `/etc/gitconfig`, bien qu'il soit relatif à la racine MSys, qui se trouve où vous aurez décidé d'installer Git sur votre système Windows. ### Votre identité ### diff --git a/fr/02-git-basics/01-chapter2.markdown b/fr/02-git-basics/01-chapter2.markdown index 1ed5f012e..c7742c88d 100644 --- a/fr/02-git-basics/01-chapter2.markdown +++ b/fr/02-git-basics/01-chapter2.markdown @@ -80,8 +80,8 @@ L'outil principal pour déterminer quels fichiers sont dans quel état est la co Si vous lancez cette commande juste après un clonage, vous devriez voir ce qui suit : $ git status - # On branch master - nothing to commit (working directory clean) + On branch master + nothing to commit, working directory clean Ce message signifie que votre copie de travail est propre, en d'autres mots, aucun fichier suivi n'a été modifié. Git ne voit pas non plus de fichiers non-suivis, sinon ils seraient listés ici. @@ -94,11 +94,12 @@ Si ce fichier n'existait pas auparavant, et que vous lancez la commande `git sta $ vim LISEZMOI $ git status - # On branch master - # Untracked files: - # (use "git add ..." to include in what will be committed) - # - # LISEZMOI + On branch master + Untracked files: + (use "git add ..." to include in what will be committed) + + LISEZMOI + nothing added to commit but untracked files present (use "git add" to track) Vous pouvez constater que votre nouveau fichier `LISEZMOI` n'est pas en suivi de version, car il apparaît dans la section « Untracked files » de l'état de la copie de travail. @@ -116,12 +117,12 @@ Pour commencer à suivre le fichier `LISEZMOI`, vous pouvez entrer ceci : Si vous lancez à nouveau la commande `git status`, vous pouvez constater que votre fichier `LISEZMOI` est maintenant suivi et indexé : $ git status - # On branch master - # Changes to be committed: - # (use "git reset HEAD ..." to unstage) - # - # new file: LISEZMOI - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + new file: LISEZMOI + Vous pouvez affirmer qu'il est indexé car il apparaît dans la section « Changes to be committed » (Modifications à valider). Si vous enregistrez à ce moment, la version du fichier à l'instant où vous lancez `git add` est celle qui appartiendra à l'instantané. @@ -134,17 +135,18 @@ Maintenant, modifions un fichier qui est déjà sous suivi de version. Si vous modifiez le fichier sous suivi de version appelé `benchmarks.rb` et que vous lancez à nouveau votre commande `git status`, vous verrez ceci : $ git status - # On branch master - # Changes to be committed: - # (use "git reset HEAD ..." to unstage) - # - # new file: LISEZMOI - # - # 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: LISEZMOI + + 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 + Le fichier `benchmarks.rb` apparaît sous la section nommée « Changes not staged for commit » ce qui signifie que le fichier sous suivi de version a été modifié dans la copie de travail mais n'est pas encore indexé. Pour l'indexer, il faut lancer la commande `git add` (qui est une commande multi-usage — elle peut être utilisée pour placer un fichier sous suivi de version, pour indexer un fichier ou pour d'autres actions telles que marquer comme résolus des conflits de fusion de fichiers). @@ -152,13 +154,13 @@ Lançons maintenant `git add` pour indexer le fichier `benchmarks.rb`, et relan $ git add benchmarks.rb $ git status - # On branch master - # Changes to be committed: - # (use "git reset HEAD ..." to unstage) - # - # new file: LISEZMOI - # modified: benchmarks.rb - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + new file: LISEZMOI + modified: benchmarks.rb + À présent, les deux fichiers sont indexés et feront partie de la prochaine validation. Mais supposons que vous souhaitiez apporter encore une petite modification au fichier `benchmarks.rb` avant de réellement valider la nouvelle version. @@ -167,18 +169,19 @@ Néanmoins, vous lancez `git status` une dernière fois : $ vim benchmarks.rb $ git status - # On branch master - # Changes to be committed: - # (use "git reset HEAD ..." to unstage) - # - # new file: LISEZMOI - # 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: LISEZMOI + 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 + Que s'est-il donc passé ? À présent, `benchmarks.rb` apparaît à la fois comme indexé et non indexé. En fait, Git indexe un fichier dans son état au moment où la commande `git add` est lancée. @@ -187,13 +190,13 @@ Si le fichier est modifié après un `git add`, il faut relancer `git add` pour $ git add benchmarks.rb $ git status - # On branch master - # Changes to be committed: - # (use "git reset HEAD ..." to unstage) - # - # new file: LISEZMOI - # modified: benchmarks.rb - # + On branch master + Changes to be committed: + (use "git reset HEAD ..." to unstage) + + new file: LISEZMOI + modified: benchmarks.rb + ### Ignorer des fichiers ### @@ -248,17 +251,18 @@ Supposons que vous éditez et indexez le fichier `LISEZMOI` et que vous éditez Si vous lancez la commande `git status`, vous verrez ceci : $ git status - # On branch master - # Changes to be committed: - # (use "git reset HEAD ..." to unstage) - # - # new file: LISEZMOI - # - # 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: LISEZMOI + + 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 + Pour visualiser ce qui a été modifié mais pas encore indexé, tapez `git diff` sans autre argument : @@ -738,7 +742,9 @@ Cette commande fonctionne avec de nombreux formats — vous pouvez indiquer une Vous pouvez aussi restreindre la liste aux *commits* vérifiant certains critères de recherche. L'option `--author` permet de filtrer sur un auteur spécifique, et l'option `--grep` permet de chercher des mots clés dans les messages de validation. -Notez que si vous cherchez seulement des *commits* correspondant simultanément aux deux critères, vous devez ajouter l'option `--all-match`, car par défaut ces commandes retournent les *commits* vérifiant au moins un critère lors de recherche. +Notez que si vous spécifiez à la fois `--author` et `--grep`, la commande retournera seulement des *commits* correspondant simultanément aux deux critères. + +Si vous souhaitez spécifier plusieurs options `--grep`, vous devez ajouter l'option `--all-match`, car par défaut ces commandes retournent les *commits* vérifiant au moins un critère de recherche. La dernière option vraiment utile à `git log` est la spécification d'un chemin. Si un répertoire ou un nom de fichier est spécifié, le journal est limité aux *commits* qui ont introduit des modifications aux fichiers concernés. @@ -924,7 +930,7 @@ Par exemple, mon dépôt Grit ressemble à ceci. koke git://github.com/koke/grit.git origin git@github.com:mojombo/grit.git -Cela signifie que nous pouvons tirer très facilement des contributions depuis certains utilisateurs. +Cela signifie que je peux tirer très facilement des contributions depuis certains utilisateurs. Mais il est à noter que seul le dépôt distant `origin` utilise une URL SSH, ce qui signifie que c'est le seul sur lequel je peux pousser (nous traiterons de ceci au chapitre 4). ### Ajouter des dépôts distants ### @@ -1289,9 +1295,8 @@ De nombreuses personnes utilisent parfaitement Git sans connaître aucun de ces ### Auto-Complétion ### Si vous utilisez le shell Bash, Git est livré avec un script d'auto-complétion utile. -Téléchargez le code source de Git, et jetez un œil dans le répertoire `contrib/completion`. -Il devrait y avoir un fichier nommé `git-completion.bash`. -Copiez ce fichier dans votre répertoire personnel et ajoutez cette ligne à votre fichier `.bashrc` : +Téléchargez le directement depuis le code source de Git à https://github.com/git/git/blob/master/contrib/git-completion.bash . +Copiez ce fichier dans votre répertoire personnel sous le nom `.git-completion.bash` et ajoutez cette ligne à votre fichier `.bashrc` : source ~/.git-completion.bash diff --git a/fr/03-git-branching/01-chapter3.markdown b/fr/03-git-branching/01-chapter3.markdown index 6768e4a02..c6c7f1246 100644 --- a/fr/03-git-branching/01-chapter3.markdown +++ b/fr/03-git-branching/01-chapter3.markdown @@ -336,15 +336,20 @@ Placer le fichier dans l'index marque le conflit comme résolu pour Git. Si vous souhaitez utiliser un outil graphique pour résoudre ces problèmes, vous pouvez lancer `git mergetool` qui démarre l'outil graphique de fusion approprié et vous permet de naviguer dans les conflits : $ 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): -Si vous souhaitez utiliser un outil de fusion autre que celui par défaut (Git a choisi `opendiff` pour moi dans ce cas car j'utilise la commande sous Mac), vous pouvez voir tous les outils supportés après l'indication « merge tool candidates ». +Si vous souhaitez utiliser un outil de fusion autre que celui par défaut (Git a choisi `opendiff` pour moi dans ce cas car j'utilise la commande sous Mac), vous pouvez voir tous les outils supportés après l'indication « *of the following tools:* ». Tapez le nom de l'outil que vous préfèreriez utiliser. Au chapitre 7, nous expliquerons comment changer cette valeur par défaut dans votre environnement. @@ -579,7 +584,7 @@ Cette commande vous fournit une branche locale modifiable basée sur l'état act L'extraction d'une branche locale à partir d'une branche distante crée automatiquement ce qu'on appelle une _branche de suivi_. Les branches de suivi sont des branches locales qui sont en relation directe avec une branche distante. Si vous vous trouvez sur une branche de suivi et que vous tapez `git push`, Git sélectionne automatiquement le serveur vers lequel pousser vos modifications. -De même, `git pull` sur une de ces branches récupère toutes les références distantes et les fusionne automatiquement dans la branche distante correspondante. +De même, `git pull` sur une de ces branches récupère toutes les références distantes et fusionne automatiquement la branche distante correspondante dans la branche actuelle. Lorsque vous clonez un dépôt, il crée généralement automatiquement une branche `master` qui suit `origin/master`. C'est pourquoi les commandes `git push` et `git pull` fonctionnent directement sans plus de paramétrage. @@ -597,7 +602,7 @@ Pour créer une branche locale avec un nom différent de celui de la branche dis Branch sf set up to track remote branch refs/remotes/origin/correctionserveur. Switched to a new branch "sf" -À présent, votre branche locale sf poussera vers et tirera automatiquement depuis origin/correctionserveur. +À présent, votre branche locale `sf` poussera vers et tirera automatiquement depuis `origin/correctionserveur`. ### Effacer des branches distantes ### diff --git a/fr/04-git-server/01-chapter4.markdown b/fr/04-git-server/01-chapter4.markdown index 698952413..5d68cb7bb 100644 --- a/fr/04-git-server/01-chapter4.markdown +++ b/fr/04-git-server/01-chapter4.markdown @@ -43,7 +43,8 @@ Ou bien cela : $ git clone file:///opt/git/projet.git Git opère légèrement différemment si vous spécifiez explicitement le protocole `file://` au début de l'URL. -Si vous spécifiez simplement le chemin, Git tente d'utiliser des liens durs ou une copie des fichiers nécessaires. +Si vous spécifiez simplement le chemin et si la destination se trouve sur le même système de fichiers, Git tente d'utiliser des liens physiques pour le fichiers communs. +Si la destination se trouve sur un autre système de fichiers, Git fait une copie des fichiers nécessaires. Si vous spécifiez le protocole `file://`, Git lance un processus d'accès au travers du réseau, ce qui est généralement moins efficace. La raison d'utiliser spécifiquement le préfixe `file://` est la volonté d'obtenir une copie propre du dépôt, sans aucune référence ou aucun objet supplémentaire qui pourraient résulter d'un import depuis un autre système de gestion de version ou d'une action similaire (voir chapitre 9 pour les tâches de maintenance). Nous utiliserons les chemins normaux par la suite car c'est la méthode la plus efficace. @@ -982,7 +983,7 @@ Nous allons détailler comment faire. ### Création d'un compte utilisateur ### La première chose à faire, c'est de créer un compte utilisateur gratuit. -Visitez la page « Plans & Pricing » (plans et prix) à `http://github.com/plans` et cliquez sur le bouton « Create a free account » (créer un compte gratuit) de la zone « Free for open source » (gratuit pour l'open source) (voir figure 4-2) qui vous amène à la page d'enregistrement. +Visitez la page « Plans and pricing » (plans et prix) à `https://github.com/pricing` et cliquez sur le bouton « Create a free account » (créer un compte gratuit) de la zone « Free for open source » (gratuit pour l'open source) (voir figure 4-2) qui vous amène à la page d'enregistrement. Insert 18333fig0402.png Figure 4-2. La page des différents plans de GitHub. diff --git a/fr/05-distributed-git/01-chapter5.markdown b/fr/05-distributed-git/01-chapter5.markdown index 19716edfd..8b0ac0a35 100644 --- a/fr/05-distributed-git/01-chapter5.markdown +++ b/fr/05-distributed-git/01-chapter5.markdown @@ -255,7 +255,7 @@ John a une référence aux modifications que Jessica a poussées, mais il doit l Cette fusion se passe sans problème — l'historique de *commits* de John ressemble à présent à la figure 5-5. Insert 18333fig0505.png -Figure 5-5. Le dépôt local de John après la fusion d'origin/master. +Figure 5-5. Le dépôt local de John après la fusion d'`origin/master`. Maintenant, John peut tester son code pour s'assurer qu'il fonctionne encore correctement et peut pousser son travail nouvellement fusionné sur le serveur : @@ -678,11 +678,31 @@ Vous pouvez positionner ces valeurs séparément avec une série de commandes `g sslverify = false Si votre serveur IMAP n'utilise pas SSL, les deux dernières lignes ne sont probablement pas nécessaires et le paramètre `host` commencera par `imap://` au lieu de `imaps://`. -Quand c'est fait, vous pouvez utiliser la commande `git send-email` pour placer la série de patchs dans le répertoire *Drafts* du serveur IMAP spécifié : +Quand c'est fait, vous pouvez utiliser la commande `git imap-send` pour placer la série de patchs dans le répertoire *Drafts* du serveur IMAP spécifié : + + $ 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 + +À présent, vous devriez pouvoir vous rendre dans le répertoire *Drafts*, changer le champ destinataire pour celui de la liste de diffusion, y ajouter optionnellement en copie le mainteneur du projet ou le responsable et l'envoyer. + +Une autre méthode consiste à envoyer vos patchs par un serveur SMTP. +Comme précédemment, vous pouvez régler chaque paramètre séparément avec une série de commandes `git config` ou vous pouvez les ajouter directement dans la section `sendemail` de votre fichier `~/.gitconfig` : + + [sendemail] + smtpencryption = tls + smtpserver = smtp.gmail.com + smtpuser = user@gmail.com + smtpserverport = 587 + +Après ceci, vous pouvez utiliser la commande `git send-email` pour envoyer vos patchs : $ git send-email *.patch - 0001-Ajout-d-une-limite-la-fonction-de-log.patch - 0002-change-la-largeur-du-log-de-25-a-30.patch + 0001-added-limit-to-log-function.patch + 0002-changed-log-output-to-30-from-25.patch Who should the emails appear to be from? [Jessica Smith ] Emails will be sent from: Jessica Smith Who should the emails be sent to? jessica@example.com @@ -707,8 +727,6 @@ Ensuite, Git crache un certain nombre d'informations qui ressemblent à ceci pou Result: OK -À présent, vous devriez pouvoir vous rendre dans le répertoire Drafts, changer le champ destinataire pour celui de la liste de diffusion, y ajouter optionnellement en copie le mainteneur du projet ou le responsable et l'envoyer. - ### Résumé ### Ce chapitre a traité quelques-unes des méthodes communes de gestion de types différents de projets Git que vous pourrez rencontrer et a introduit un certain nombre de nouveaux outils pour vous aider à gérer ces processus. diff --git a/fr/06-git-tools/01-chapter6.markdown b/fr/06-git-tools/01-chapter6.markdown index 1fe8e5f19..07adf11d4 100644 --- a/fr/06-git-tools/01-chapter6.markdown +++ b/fr/06-git-tools/01-chapter6.markdown @@ -70,7 +70,7 @@ Si vous essayez de récupérer l'objet de nouveau à un moment donné, vous auri Quoi qu'il en soit, vous devriez être conscient à quel point ce scénario est ridiculement improbable. Une empreinte SHA-1 porte sur 20 octets soit 160 bits. -Le nombre d'objets aléatoires à hacher requis pour assurer une probabilité de collision de 50 % vaut environ 2^80 (la formule pour calculer la probabilité de collision est `p = (n(n-1)/2) * (1/2^160))`. +Le nombre d'objets aléatoires à hacher requis pour assurer une probabilité de collision de 50 % vaut environ 2^80 (la formule pour calculer la probabilité de collision est `p = (n(n-1)/2) * (1/2^160)`). 2^80 vaut 1,2 × 10^24 soit 1 million de milliards de milliards. Cela représente 1200 fois le nombre de grains de sable sur Terre. @@ -504,7 +504,7 @@ Votre répertoire de travail est propre : $ git status # On branch master - nothing to commit (working directory clean) + nothing to commit, working directory clean À ce moment, vous pouvez facilement changer de branche et travailler autre part ; vos modifications sont conservées dans votre pile. Pour voir quelles remises vous avez sauvegardées, vous pouvez utiliser la commande `git stash list` : @@ -577,7 +577,7 @@ La création d'un alias permettra d'ajouter effectivement la commande `stash-una Par exemple : $ git config --global alias.stash-unapply '!git stash show -p | git apply -R' - $ git stash + $ git stash apply $ #... work work work $ git stash-unapply @@ -1316,7 +1316,7 @@ Si vous récupérez l'une puis l'autre branche, vous pouvez voir que vous avez d Pour tirer le projet Rack dans votre projet `master` comme un sous-répertoire, vous pouvez utiliser la commande `git read-tree`. Vous apprendrez davantage sur `read-tree` et compagnie dans le chapitre 9, mais pour le moment, sachez qu'il lit la racine d'une de vos branches et l'inscrit dans votre index et votre répertoire de travail. -Vous venez juste de commuter vers votre branche `master` et vous tirez la branche `rack` vers le sous-répertoire `rack` de votre branche `master` de votre projet principal : +Vous venez juste de commuter vers votre branche `master` et vous tirez la branche `rack_branch` vers le sous-répertoire `rack` de votre branche `master` de votre projet principal : $ git read-tree --prefix=rack/ -u rack_branch diff --git a/fr/07-customizing-git/01-chapter7.markdown b/fr/07-customizing-git/01-chapter7.markdown index e7248a28a..8adb59f99 100644 --- a/fr/07-customizing-git/01-chapter7.markdown +++ b/fr/07-customizing-git/01-chapter7.markdown @@ -177,7 +177,7 @@ Pour Windows, vous devrez changer `/usr/local/bin` en un chemin d'exécution d'u Vous pouvez télécharger P4Merge ici : - http://www.perforce.com/perforce/downloads/component.html + http://www.perforce.com/product/components/perforce-visual-merge-and-diff-tools Pour commencer, créez un script d'appel externe pour lancer vos commandes. Je vais utiliser le chemin Mac pour l'exécutable ; dans d'autres systèmes, il résidera où votre binaire `p4merge` a été installé. @@ -385,12 +385,23 @@ Dans la branche 1.6 de Git, vous pouvez aussi utiliser une macro fournie qui sig #### Comparaison de fichiers binaires #### -Dans la branche 1.6 de Git, vous pouvez utiliser la fonctionnalité des attributs Git pour effectivement comparer les fichiers binaires. +Dans Git, vous pouvez utiliser la fonctionnalité des attributs pour comparer efficacement les fichiers binaires. Pour ce faire, indiquez à Git comment convertir vos données binaires en format texte qui peut être comparé via un diff normal. +Mais le question revient alors à savoir comment convertir les données binaires en texte. +La meilleure solution consiste à trouver un outil qui réalise pour vous la conversion des données binaires en représentation textuelle (imaginez par exemple comment convertir un fichier audio en texte). +Si c'est impossible et qur vous ne parvenez pas à obtenir une réprésentation du contenu sous forme de texte, il reste relativement facile d'obtenir une description dans un format humainement lisible de ce contenu. +Les métadonnées ne vous donneront pas une représentation complète du contenu du fichier, mais c'est en tout cas mieux que rien. + +Nous allons utiliser les deux méthodes précédentes pour obtenir des comparaisons de formats binaires largement utilisés. + +Note : il existe de nombreux types de formats binaires avec du contenu textuel pour lesquels il est difficile de trouver une convertisseur vers du texte. +Dans ces cas, il reste toujours possible d'extraire le texte au moyen du programme `strings`. +Certains de ces fichiers peuvent aussi utiliser une encodage spécifique du texte, comme UTF-16, et `strings` ne trouvera alors rien de probant. +Les résultats sont très variables. +Dans tous les cas, `strings` est disponible sur la plupart des systèmes Mac et Linux, et constitue une bonne option pour un premier essai. ##### Fichiers MS Word ##### -Comme c'est une fonctionnalité plutôt cool et peu connue, nous allons en voir quelques exemples. Premièrement, nous utiliserons cette technique pour résoudre un des problèmes les plus ennuyeux de l'humanité : gérer en contrôle de version les documents Word. Tout le monde convient que Word est l'éditeur de texte le plus horrible qui existe, mais bizarrement, tout le monde persiste à l'utiliser. Si vous voulez gérer en version des documents Word, vous pouvez les coller dans un dépôt Git et les valider de temps à autre. @@ -411,20 +422,17 @@ Ajoutez la ligne suivante dans votre fichier `.gitattributes` : Cette ligne indique à Git que tout fichier correspondant au patron (.doc) doit utiliser le filtre `word` pour visualiser le diff des modifications. Qu'est-ce que le filtre « word » ? Nous devons le définir. -Vous allez configurer Git à utiliser le programme `strings` pour convertir les documents Word en fichiers texte lisibles qu'il pourra alors comparer correctement : +Vous allez indiquer à Git d'utiliser le programme `catdoc` qui a été écrit spécifiquement pour extraire le texte d'un document MS Word. +Vous pouvez l'obtenir depuis `http://www.wagner.pp.ru/~vitus/software/catdoc`. - $ git config diff.word.textconv strings + $ git config diff.word.textconv catdoc Cette commande ajoute à votre fichier `.git/config` une section qui ressemble à ceci : [diff "word"] - textconv = strings - -Note : il existe différents types de fichiers `.doc`. -Certains utilisent un codage UTF-16 ou d'autres pages de codes plus exotiques dans lesquels `strings` ne trouvera aucune chaîne utile. -Le résultat de ce filtre pour vos fichiers dépendra de ces conditions. + textconv = catdoc -À présent, Git sait que s'il essaie de faire un diff entre deux instantanés et qu'un des fichiers finit en `.doc`, il devrait faire passer ces fichiers par le filtre `word` défini comme le programme `strings`. +À présent, Git sait que s'il essaie de faire un diff entre deux instantanés et qu'un des fichiers finit en `.doc`, il devrait faire passer ces fichiers par le filtre `word` défini comme le programme `catdoc`. Cette méthode fait effectivement des jolies versions texte de vos fichiers Word avant d'essayer de les comparer. Voici un exemple. @@ -436,18 +444,14 @@ Puis, j'ai lancé `git diff` pour visualiser ce qui a changé : 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. - -Git réussit à m'indiquer succinctement que j'ai ajouté la chaîne « *Let's see if this works* », ce qui est correct. -Ce n'est pas parfait car il y a toujours un tas de données aléatoires à la fin, mais c'est suffisant. -Si vous êtes capable d'écrire un convertisseur Word vers texte qui fonctionne suffisamment bien, cette solution peut s'avérer très efficace. -Cependant, `strings` est disponible sur la plupart des systèmes Mac et Linux et peut donc constituer un bon début pour de nombreux formats binaires. + @@ -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 m'indique succinctement que j'ai ajouté la chaîne « (see Chapter 3) », ce qui est correct. ##### Fichiers OpenDocument texte ##### diff --git a/fr/08-git-and-other-scms/01-chapter8.markdown b/fr/08-git-and-other-scms/01-chapter8.markdown index e7e3ad7ac..f31bf8d22 100644 --- a/fr/08-git-and-other-scms/01-chapter8.markdown +++ b/fr/08-git-and-other-scms/01-chapter8.markdown @@ -456,7 +456,7 @@ Vous pouvez alors fournir ce fichier à `git svn` pour l'aider à convertir les Vous pouvez aussi indiquer à `git svn` de ne pas inclure les méta-données que Subversion importe habituellement en passant l'option `--no-metadata` à la commande `clone` ou `init`. Au final, votre commande d'import ressemble à ceci : - $ git-svn clone http://mon-projet.googlecode.com/svn/ \ + $ git svn clone http://mon-projet.googlecode.com/svn/ \ --authors-file=users.txt --no-metadata -s my_project Maintenant, l'import depuis Subversion dans le répertoire `my_project` est plus présentable. diff --git a/fr/09-git-internals/01-chapter9.markdown b/fr/09-git-internals/01-chapter9.markdown index ccf9eb886..9e881901d 100644 --- a/fr/09-git-internals/01-chapter9.markdown +++ b/fr/09-git-internals/01-chapter9.markdown @@ -544,7 +544,7 @@ Ajoutons de plus gros contenu au dépôt pour montrer une fonctionnalité intér Ajoutez le fichier `repo.rb` de la bibliothèque Grit que vous avez manipulé plus tôt. Il représente environ 12 Kio de code source : - $ curl https://raw.github.com/mojombo/grit/master/lib/grit/repo.rb > repo.rb + $ curl -L 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 diff --git a/hi/01-introduction/01-chapter1.markdown b/hi/01-introduction/01-chapter1.markdown new file mode 100644 index 000000000..1c3a27f67 --- /dev/null +++ b/hi/01-introduction/01-chapter1.markdown @@ -0,0 +1,7 @@ +# शुरुआत # + +यह अध्याय गिट के साथ कैसे शुरुआत की जाए की व्याख्या करेगा। सर्वप्रथम हम संस्करण नियंत्रण (version control) के साधनों की पृष्ठभूमि पे एक नज़र डालेंगे, इसके बाद गिट को कैसे किसी सिस्टम में इंस्टॉल करना है ये बताया जायेगा और फिर कैसे सेटअप पूरा कर इसके साथ काम करना है बताया जाएगा। इस अध्याय के आखिरी हिस्से से स्पष्टीकरण मिलेगा कि गिट क्यों बनाया गया और आपको इसका इस्तेमाल क्यों करना चाहिए, जिसके समर्थ आप तब तक हो चुके होंगे। + +## संस्करण नियंत्रण ## + +संस्करण नियंत्रण (version control) क्या है और इसके बारे में पता होना किसलिए मददगार है? संस्करण नियंत्रण (version control) एक पद्धति है जो समय के साथ किसी फ़ाइल या फ़ाइल समूह में होने वाले परिवर्तनों को याद रखती है जिसका प्रयोग करके आप उनकी किसी पूर्ण अवस्था का बाद में परीक्षण कर सकते हैं। यद्यपि इस पुस्तक के उदाहरण सॉफ्टवेयर फाइल्स का प्रयोग करके संस्करण नियंत्रण का प्रदर्शन करते हैं, वास्तविकता में किसी भी प्रकार की फ़ाइल ऐसे सिस्टम में रखी जा सकती है। diff --git a/hu/01-introduction/01-chapter1.markdown b/hu/01-introduction/01-chapter1.markdown index c3cef723a..7f314fc2b 100644 --- a/hu/01-introduction/01-chapter1.markdown +++ b/hu/01-introduction/01-chapter1.markdown @@ -161,9 +161,9 @@ Or if you’re on a Debian-based distribution like Ubuntu, try apt-get: ### Installing on Mac ### -There are two easy ways to install Git on a Mac. The easiest is to use the graphical Git installer, which you can download from the Google Code page (see Figure 1-7): +There are two easy ways to install Git on a Mac. The easiest is to use the graphical Git installer, which you can download from the SourceForge page (see Figure 1-7): - http://code.google.com/p/git-osx-installer + http://sourceforge.net/projects/git-osx-installer/ Insert 18333fig0107.png Figure 1-7. Git OS X installer. diff --git a/id/01-introduction/01-chapter1.markdown b/id/01-introduction/01-chapter1.markdown index af9b8cfc3..8fe56b1e6 100644 --- a/id/01-introduction/01-chapter1.markdown +++ b/id/01-introduction/01-chapter1.markdown @@ -161,9 +161,9 @@ Atau jika anda menggunakan distro berbasis Debian seperti Ubuntu, coba gunakan a ### Menginstall Git pada Mac ### -Terdapat dua cara mudah untuk menginstal Git pada sebuah komputer Mac. Cara termudah adalah menggunakan installer Git berbasis GUI, yang dapat anda peroleh dari halaman Google Code (lihat Gambar 1-7): +Terdapat dua cara mudah untuk menginstal Git pada sebuah komputer Mac. Cara termudah adalah menggunakan installer Git berbasis GUI, yang dapat anda peroleh dari halaman SourceForge (lihat Gambar 1-7): - http://code.google.com/p/git-osx-installer + http://sourceforge.net/projects/git-osx-installer/ Insert 18333fig0107.png Gambar 1-7. Git OS X installer. diff --git a/id/02-git-basics/01-chapter2.markdown b/id/02-git-basics/01-chapter2.markdown index dd67c0367..428e91669 100644 --- a/id/02-git-basics/01-chapter2.markdown +++ b/id/02-git-basics/01-chapter2.markdown @@ -55,7 +55,7 @@ Alat utama yang Anda gunakan untuk menentukan berkas-berkas mana yang berada dal $ git status # On branch master - nothing to commit (working directory clean) + nothing to commit, working directory clean Ini berarti Anda memiliki direktori kerja yang bersih-dengan kata lain, tidak ada berkas terpantau yang terubah. Git juga tidak melihat berkas-berkas yang tak terpantau, karena pasti akan dilaporkan oleh alat ini. Juga, perintah ini memberitahu Anda tentang cabang tempat Anda berada. Pada saat ini, cabang akan selalu berada di master, karena sudah menjadi default-nya; Anda tidak perlu khawatir tentang cabang dulu. Bab berikutnya akan membahas tentang percabangan dan referensi secara lebih detil. diff --git a/id/03-git-branching/01-chapter3.markdown b/id/03-git-branching/01-chapter3.markdown index 3762d0418..db3b55e30 100644 --- a/id/03-git-branching/01-chapter3.markdown +++ b/id/03-git-branching/01-chapter3.markdown @@ -92,61 +92,61 @@ Hal ini kontras dengan cara yang dilakukan banyak VCS dalam branch, yang butuh m Mari kita lihat mengapa anda harus melakukannya. -## Basic Branching and Merging ## +## Dasar Pencabangan (Branching) dan Penggabungan (Merging) ## -Let’s go through a simple example of branching and merging with a workflow that you might use in the real world. You’ll follow these steps: +Mari kita lihat contoh sederhana dari Pencabangan dan Penggabungan dengan diagram alir yang biasa kita gunakan secara nyata. Anda akan mengikut tahapan berikut : -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. Bekerja di jejaring (website). +2. Buat pencabangan untuk hal baru yang sedang dikerjakan. +3. Bekerja di pencabangan tersebut. -At this stage, you’ll receive a call that another issue is critical and you need a hotfix. You’ll do the following: +Pada tahap ini, anda akan menerima pesan bahwa ada masalah yang kritis dan anda perlu memperbaikinya. Anda akan melakukan tahapan berikut : -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. Kembali ke pencabangan saat produksi. +2. Membuat pencabangan untuk memperbaiki masalah. +3. Setelah diuji, gabungkan pencabangan perbaikan tadi, dan tempatkan di bagian produksi. +4. Kembali ke kasus sebelumnya dan kembali bekerja. -### Basic Branching ### +### Dasar Pencabangan ### -First, let’s say you’re working on your project and have a couple of commits already (see Figure 3-10). +Pertama, katakan anda sedang mengerjakan sebuah proyek dan telah melakukan *commits* (lihat Gambar 3-10). Insert 18333fig0310.png -Figure 3-10. A short and simple commit history. +Gambar 3-10. Sejarah *commit* yang pendek dan sederhana. -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: +Anda memutuskan untuk mengerjakan masalah #53 pada apapun jenis sistem pelacak-masalah yang digunakan perusahaan. Untuk memperjelas, Git tidak terikat dengan sistem pelacak-masalah apapun; tapi karena masalah #53 adalah inti topik yang akan dikerjakan, anda akan membuat pencabangan dimana anda bekerja. Untuk membuat pencabangan dan berpindah kesana dalam satu waktu, anda dapat menjalankan perintah `git checkout` dengan tanda `-b` : $ git checkout -b iss53 Switched to a new branch "iss53" -This is shorthand for: +Ini adalah bentuk singkat untuk : $ git branch iss53 $ git checkout iss53 -Figure 3-11 illustrates the result. +Gambar 3-11 menjelaskan hasilnya. Insert 18333fig0311.png -Figure 3-11. Creating a new branch pointer. +Gambar 3-11. Membuat penunjuk baru pencabangan. -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): +Anda bekerja di jejaring *website* dan melakukan beberapa *commits*. Dengan melakukannya, menggeser cabang `iss53` kedepan, karena anda menyelesaikannya (demikianlah, HEAD anda penunjuk ke sana; lihat Gambar 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. +Gambar 3-12. Cabang iss53 telah bergerak kedepan sesuai pekerjaan anda. -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. +Lalu kemudian, saat kita melihat ada permasalahan dalam situs jejaring, dan kita perlu untuk memperbaikinya segera. Dengan Git, anda tidak perlu memasang pembetulannya bersama dengan perubahan di `iss53`, dan anda tidak perlu melakukan cara yang sulit untuk kembali ke pekerjaan anda sebelumnya di tahap produksi. Yang anda perlukan hanya kembali ke pencabangan *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: +Bagaimanapun, sebelum anda melakukannya, perhatikan bahwa jika dalam kandar kerja anda atau kondisi *staging* memiliki perubahan yang bertentangan dengan pencabangan yang akan anda tinggalkan, Git tidak akan memperbolehkan anda berpindah. Ini adalah cara terbaik untuk meninggalkan pekerjaan dalam keadaan bersih ketika anda akan berpindah pencabangan. Ada beberapa cara untuk melakukan ini (*namely*, *stashing*, dan merubah *commit*) yang akan kita bahas berikutnya. Untuk saat ini, anda telah *commit* seluruh perubahan, sehingga anda dapat kembali ke pencabangan *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. +Saat ini, anda berada dalam kandar kerja dalam kondisi tepat seperti anda belum mengerjakan masalah #53, dan anda dapat konsentrasi mengerjakan perbaikannya. Hal yang perlu diingat adalah: Git mengkondisikan kandar kerja anda agar terlihat sebagaimana anda kembali ke titik pencabangan yang anda tuju. Git menambahkan, menghapus, dan mengubah berkas secara otomatis untuk memastikan bahwa anda bekerja pada pencabangan terakhir yang anda *commit*. -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): +Selanjutnya, ada dapat membuat cabang *hotfix*. Mari kita buat cabang *hotfix* tempat kita bekerja sampai kondisinya selesai (lihat Gambar 3-13): $ git checkout -b 'hotfix' Switched to a new branch "hotfix" diff --git a/it/01-introduction/01-chapter1.markdown b/it/01-introduction/01-chapter1.markdown index 2806f937b..18a222ff6 100644 --- a/it/01-introduction/01-chapter1.markdown +++ b/it/01-introduction/01-chapter1.markdown @@ -41,7 +41,7 @@ Inoltre, molti di questi sistemi trattano bene l'avere più repository remoti su ## Una Breve Storia di Git ## -Come per molte grandi cose della vita, Git è nato con un po' di distruzione creativa e polemiche infuocate. Il kernel di Linux è un progetto software open source di grande portata abbastanza. Per buona parte del tempo (1991-2002) della manutenzione del kernel Linux le modifiche al software venivano passate sotto forma di patch e file compressi. Nel 2002, il progetto del kernel Linux iniziò ad utilizzare un sistema DVCS proprietario chiamato BitKeeper. +Come per molte grandi cose della vita, Git è nato con un po' di distruzione creativa e polemiche infuocate. Il kernel di Linux è un progetto software open source di grande portata. Per buona parte del tempo (1991-2002) della manutenzione del kernel Linux le modifiche al software venivano passate sotto forma di patch e file compressi. Nel 2002, il progetto del kernel Linux iniziò ad utilizzare un sistema DVCS proprietario chiamato BitKeeper. Nel 2005 il rapporto tra la comunità che sviluppa il kernel Linux e la società commerciale che aveva sviluppato BitKeeper si ruppe, e fu revocato l'uso gratuito di BitKeeper. Ciò indusse la comunità di sviluppo di Linux (e in particolare Linus Torvalds, il creatore di Linux) a sviluppare uno strumento proprio, basandosi su alcune delle lezioni apprese durante l'utilizzo di BitKeeper. Alcuni degli obiettivi del nuovo sistema erano i seguenti: @@ -69,35 +69,35 @@ Git non considera i dati né li registra in questo modo. Git considera i propri Insert 18333fig0105.png Figura 1-5. Git immagazzina i dati come snapshot del progetto nel tempo. -Questa è una distinzione importante tra Git e pressocché tutti gli altri VCS. Git riconsidera quasi tutti gli aspetti del controllo di versione che la maggior parte degli altri sistemi ha copiato dalle generazioni precedenti. Questo rende Git più simile a un mini filesystem con a dispoizione strumenti incredibilmente potenti che un semplice VCS. Esploreremo alcuni benefici che ottieni pensando in questo modo ai tuoi dati vedremo le ramificazioni (i _branch_) in Git nel Capitolo 3. +Questa è una distinzione importante tra Git e pressocché tutti gli altri VCS. Git riconsidera quasi tutti gli aspetti del controllo di versione che la maggior parte degli altri sistemi ha copiato dalle generazioni precedenti. Questo rende Git più simile a un mini filesystem con a disposizione strumenti incredibilmente potenti che un semplice VCS. Esploreremo alcuni benefici che ottieni pensando in questo modo ai tuoi dati e vedremo le ramificazioni (i _branch_) in Git nel Capitolo 3. ### Quasi Tutte le Operazioni Sono Locali ### La maggior parte delle operazioni in Git, necessitano solo di file e risorse locali per operare — generalmente non occorrono informazioni da altri computer della rete. Se sei abituato ad un CVCS in cui la maggior parte delle operazioni sono soggette alle latenze di rete, questo aspetto di Git ti farà pensare che gli Dei della velocità abbiano benedetto Git con poteri soprannaturali. Poiché hai l'intera storia del progetto sul tuo disco locale, molte operazioni sembrano quasi istantanee. -Per esempio, per scorrere la storia di un progetto, Git non ha bisogno di connettersi al server per scaricarla e per poi visualizzarla — la legge direttamente dal database locale. Questo significa che puoi vedere la storia del progetto quasi istantaneamente. Se vuoi vedere i cambiamenti introdotti tra la versione corrente di un file e la versione di un mese fa, Git può consultare il file di un mese fa e calcolare localmente le differenze, invece di richiedere di farlo ad un server remoto o di estrarre una precedente versione del file dal server remoto, per poi farlo in locale. +Per esempio, per navigare la storia di un progetto, Git non ha bisogno di connettersi al server per scaricarla e per poi mostrarla: la legge direttamente dal tuo database locale. Questo significa che puoi vedere la storia del progetto quasi istantaneamente. Se vuoi vedere le modifiche introdotte tra la versione corrente e la versione di un mese fa di un file, Git può accedere al file com'era un mese fa e calcolare le differenze localmente, invece di dover chiedere a un server remoto di farlo o di scaricare dal server remoto una versione precedente del file, per poi farlo in locale. -Questo significa anche che sono minime le cose che non si possono fare se si è offline o non connesso alla VPN. Se sei in aereo o sul treno e vuoi fare un po' di lavoro, puoi eseguire tranquillamente il commit, anche se non sei connesso alla rete per fare l'upload. Se tornando a casa, trovi che il tuo client VPN non funziona correttamente, puoi comunque lavorare. In molti altri sistemi, fare questo è quasi impossibile o penoso. Con Perforce, per esempio, puoi fare ben poco se non sei connesso al server; e con Subversion e CVS, puoi modificare i file, ma non puoi inviare i cambiamenti al tuo database (perché il database è offline). Tutto ciò non ti può sembrare una gran cosa, tuttavia potresti rimanere di stucco dalla differenza che Git può fare. +Questo significa anche che sono pochissime le cose che non puoi fare se sei offline o non sei connesso alla VPN. Se sei in aereo o sul treno e vuoi fare un po' di lavoro, puoi committare tranquillamente in attesa di essere di nuovo connesso per fare l'upload. Se vai a casa e il tuo client VPN non funziona correttamente, puoi lavorare ugualmente. In molti altri sistemi questo è impossibile o molto penoso. Con Perforce, per esempio, puoi fare ben poco se non sei connesso al server; e con Subversion e CVS, puoi modificare i file, ma non puoi inviare le modifiche al tuo database (perché il database è offline). Tutto ciò potrebbe non sembrarti una gran cosa, ma potrebbe sorprenderti quanta differenza possa fare. ### Git Ha Integrità ### -Qualsiasi cosa in Git è controllata, tramite checksum, prima di essere salvata ed è referenziata da un checksum. Questo significa che è impossibile cambiare il contenuto di qualsiasi file o directory senza che Git lo sappia. Questa è una funzionalità interna di Git al più basso livello ed è intrinseco nella sua filosofia. Non puoi perdere informazioni nel transito o avere corruzioni di file senza che Git non sia in grado di accorgersene. +Qualsiasi cosa in Git è controllata, tramite checksum, prima di essere salvata ed è referenziata da un checksum. Questo significa che è impossibile cambiare il contenuto di qualsiasi file o directory senza che Git lo sappia. Questa è una funzionalità interna di basso livello di Git ed è intrinseco della sua filosofia. Non può capitare che delle informazioni in transito si perdano o che un file si corrompa senza che Git non sia in grado di accorgersene. -Il meccanismo che Git usa per fare questo checksum, è un hash, denominato SHA-1. Si tratta di una stringa di 40-caratteri, composta da caratteri esadecimali (0–9 ed a–f) e calcolata in base al contenuto di file o della struttura della directory in Git. Un hash SHA-1 assomiglia a qualcosa come: +Il meccanismo che Git usa per fare questo checksum è un hash chiamato SHA-1. Si tratta di una stringa di 40-caratteri, composta da caratteri esadecimali (0–9 ed a–f) e calcolata in base al contenuto di file o della struttura della directory in Git. Un hash SHA-1 assomiglia a qualcosa come: 24b9da6552252987aa493b52f8696cd6d3b00373 -in Git, questi valori di hash si vedono dappertutto, perché Git li usa tantissimo. Infatti, Git immagazzina ogni cosa, nel proprio database indirizzabile, non per nome di file, ma per il valore di hash del suo contenuto. +Vedrai questi hash dappertutto in Git perché li usa tantissimo. Infatti Git salva qualsiasi cosa nel suo database, e il riferimento ad un file non è basato sul nome del file, ma sull'hash del suo contenuto. ### Git Generalmente Aggiunge Solo Dati ### -Quando si fanno delle azioni in Git, quasi tutte aggiungono solo dati al database di Git. E' piuttosto difficile che si porti il sistema a fare qualcosa che non sia annullabile o a cancellare i dati in una qualche maniera. Come in altri VCS, si possono perdere o confondere le modifiche, di cui non si è ancora fatto il commit; ma dopo aver fatto il commit di uno snapshot in Git, è veramente difficile perderle, specialmente se si esegue regolarmente, il push del proprio database su di un altro repository. +Quasi tutte le azioni in Git aggiungono dati al database di Git. È piuttosto difficile fare qualcosa che non sia annullabile o che cancelli i dati in una qualche maniera. Come negli altri VCS, puoi perdere o fare confusione con le modifiche che non hai ancora committato, ma dopo aver committato uno snapshot in Git, è veramente difficile perderle, specialmente se regolarmente fai il push del tuo database su un altro repository. -Questo rende l'uso di Git un piacere perché sappiamo che possiamo sperimentare senza il pericolo di perdere seriamente le cose. Per un maggior approfondimento su come Git salva i dati e come puoi recuperare i dati che sembrano persi, vedi "Sotto il Cofano" nel Capitolo 9. +Questo rende piaceole l'uso di Git perché sappiamo che possiamo sperimentare senza il pericolo di causare danni pesanti. Per un maggior approfondimento su come Git salvi i dati e come tu possa recuperare quelli che sembrino persi, consulta il Capitolo 9. ### I Tre Stati ### -Ora, presta attenzione. La prima cosa da ricordare sempre di Git se vuoi affrontare al meglio il processo di apprendimento. I tuoi file in Git possono essere in tre stati: _committed_ (committati), _modified_ (modificati) e _staged_ (in stage). Committato significa che il file è al sicuro nel database locale. Modificato significa che il file è stato modificato, ma non è ancora stato committato nel database. In stage significa che hai contrassegnato un file, modificato nella versione corrente, perché venga inserito nello snapshot alla prossima commit. +Ora, presta attenzione. La prima cosa da ricordare sempre di Git se vuoi affrontare al meglio il processo di apprendimento è che i tuoi file in Git possono essere in tre stati: _committed_ (committati), _modified_ (modificati) e _staged_ (in stage). Committato significa che il file è al sicuro nel database locale. Modificato significa che il file è stato modificato, ma non è ancora stato committato nel database. In stage significa che hai contrassegnato un file, modificato nella versione corrente, perché venga inserito nello snapshot alla prossima commit. Questo ci porta alle tre sezioni principali di un progetto Git: la directory di Git, la directory di lavoro e l'area di stage. @@ -113,8 +113,8 @@ L'area di stage è un file, contenuto generalmente nella directory di Git, con t Il flusso di lavoro (_workflow_) di base in Git funziona così: 1. Modifica i file nella tua directory di lavoro -2. Fanno lo stage, aggiungendone le istantanee all'area di stage -3. Committa, che salva i file nell'area di stage in un'istantanea (_snapshot_) permanente nella tua directory di Git. +2. Fanne lo stage, aggiungendone le istantanee all'area di stage +3. Committa, ovvero salva i file nell'area di stage in un'istantanea (_snapshot_) permanente nella tua directory di Git. Se una particolare versione di un file è nella directory git, viene considerata già committata. Se il file è stato modificato, ma è stato aggiunto all'area di staging, è _in stage_. E se è stato modificato da quando è stata estratto, ma non è _in stage_, è modificato. Nel Capitolo 2, imparerai di più su questi stati e come trarne vantaggio o saltare la parte di staging. @@ -153,36 +153,40 @@ Dopo aver fatto questo, puoi scaricare gli aggiornamenti di Git con lo stesso Gi Se vuoi installare Git su Linux, tramite una installazione da binario, generalmente puoi farlo con lo strumento base di amministrazione dei pacchetti della tua distribuzione. Se usi Fedora, puoi usare yum: - $ yum install git-core + $ yum install git -O se sei su una distribuzione basata su Debian, come Ubuntu, prova apt-get: +O, se usi una distribuzione basata su Debian (come Ubuntu) prova apt-get: $ apt-get install git ### Installazione su Mac ### -Ci sono due metodi per installare Git su Mac. Il più semplice è usare l'installer grafico di Git, che puoi scaricare dalla pagina di Google Code (vedi Figura 1-7): +Ci sono due metodi per installare facilmente Git su Mac. Il più semplice è usare l'installazione l'installer grafico di Git, che puoi scaricare da SourceForge (vedi Figura 1-7): - http://code.google.com/p/git-osx-installer + http://sourceforge.net/projects/git-osx-installer/ Insert 18333fig0107.png Figura 1-7. Installer di Git per OS X. -L'altro metodo è installare Git con MacPorts (`http://www.macports.org`). Se hai MacPorts installato puoi farlo con: +La prima alternativa è usando MacPorts (`http://www.macports.org`). Se hai già installato MacPorts puoi installare Git con: - $ sudo port install git-core +svn +doc +bash_completion +gitweb + $ sudo port install git +svn +doc +bash_completion +gitweb Non ti occorre aggiungere tutti i pacchetti extra, ma probabilmente vorrai includere +svn, nel caso tu debba usare Git con i repository di Subversion (vedi Capitolo 8). +La seconda alternativa è Homebrew (`http://brew.sh/`). Se hai già installato Homebrew puoi installare Git con: + + $ brew install git + ### Installare su Windows ### Installare Git su Windows è davvero facile. Il progetto msysGit ha una delle procedure di installazione più facili. Semplicemente scarica l'eseguibile dalla pagina di GitHub e lancialo: - http://msysgit.github.com/ + http://msysgit.github.io/ Una volta installato avrai a disposizione sia la versione da riga di comando (incluso un client SSH ti servirà in seguito) sia l'interfaccia grafica (_GUI_) standard. -Nota sull'uso su Windows: dovresti usare Git con la shell msysGit fornita (stile Unix) perché permette di usare le complesse linee di comando di questo libro. Se hai bisogno, per qualche ragione, di usare la shell nativa di Windows / la console a linea di comando, devi usare le doppie virgolette invece delle virgolette semplici (per i parametri con che contengono spazi) e devi virgolettare i parametri che terminano con l'accento circonflesso (^) se questi sono al termine della linea, poiché in Windows è uno dei simboli di proseguimento. +Nota sull'uso su Windows: dovresti usare Git con la shell msysGit fornita (stile Unix) perché permette di usare le complesse linee di comando di questo libro. Se hai bisogno, per qualche ragione, di usare la shell nativa di Windows / la console a linea di comando, devi usare le doppie virgolette invece delle virgolette singole (per i parametri con che contengono spazi) e devi virgolettare i parametri che terminano con l'accento circonflesso (^) se questi sono al termine della linea, poiché in Windows è uno dei simboli di proseguimento. ## Prima Configurazione di Git ## diff --git a/it/02-git-basics/01-chapter2.markdown b/it/02-git-basics/01-chapter2.markdown index 25de9ca5e..c2512d22b 100644 --- a/it/02-git-basics/01-chapter2.markdown +++ b/it/02-git-basics/01-chapter2.markdown @@ -1,180 +1,183 @@ # Basi di Git # -Se puoi leggere solo un capitolo per capire l'uso di Git, questo fa per te. Questo capitolo illustra tutti i comandi base per fare la stragrande maggioranza delle cose impiegando al meglio il tuo tempo con Git. Alla fine del capitolo, dovresti essere in grado di configurare ed inizializzare un repository, avviare e fermare il tracciamento dei file e mettere in stage o eseguire il commit dei cambiamenti. Vedremo come impostare Git per ignorare certi file o pattern di file, come correggere gli errori velocemente e facilmente, come navigare nella storia del tuo progetto e vedere i cambiamenti tra i vari commit e come fare il push ed il pull da repository remoti. +Se puoi leggere un solo capitolo per imparare Git, leggi questo. Questo capitolo illustra tutti i comandi base di cui hai bisogno per la stragrande maggioranza delle cose che farai con Git. Alla fine del capitolo sarai in grado di configurare e creare un repository, iniziare e interrompere il tracciamento dei file e mettere in stage e committare le modifiche. Vedremo come impostare Git per ignorare certi file o pattern, come annullare velocemente e facilmente gli errori, come navigare la cronologia del tuo progetto e vedere le modifiche tra le varie commit e come fare il push ed il pull da repository remoti. -## Ottenere un Repository Git ## +## Repository Git ## -Puoi creare un progetto Git usando due approcci principali. Il primo prende un progetto esistente o una directory e la importa in Git. Il secondo clona un repository Git esistente da un altro server. +Puoi creare un progetto Git principalmente con due approcci. Il primo prende un progetto esistente o una directory e la importa in Git. Il secondo clona un repository Git esistente, su un altro server. -### Inizializzare un Repository in una Directory Esistente ### +### Creare un repository in una directory preesistente ### -Se stai iniziando a tracciare un progetto esistente con Git, devi posizionarti nella directory del progetto e digitare: +Se vuoi iniziare a tenere traccia con Git di un progetto esistente, devi andare nella directory del progetto e digitare: $ git init -Questo creerà una nuova sottodirectory chiamata .git che conterrà tutti i file necessari per il repository — uno scheletro del repository Git. A questo punto, niente del tuo progetto è già tracciato. (Vedi il Capitolo 9 per avere maggiori informazioni esatte sui file che sono contenuti nella directory `.git` che hai appena creato.) +Questo creerà una nuova sottodirectory chiamata `.git` che conterrà tutti i file necessari per il tuo repository, una struttura del repository Git. A questo punto non è ancora stato tracciato niente del tuo progetto. (Vedi il *Capitolo 9* per sapere quali file sono contenuti nella directory `.git` che hai appena creato.) -Se vuoi iniziare a tracciare i file esistenti (al contrario di una directory vuota), dovresti iniziare a monitorare questi file eseguendo un commit iniziale. Lo puoi fare con pochi comandi che specificano quali file vuoi controllare, seguiti da un commit: +Se vuoi iniziare a tracciare i file esistenti (a differenza di una directory vuota), dovresti iniziare a monitorare questi file con una commit iniziale. Lo puoi fare con pochi `git add`, che specificano quali file vuoi tracciare, seguiti da una commit: $ git add *.c $ git add README $ git commit -m 'initial project version' -Vedremo in seguito velocemente cosa fanno questi comandi. A questo punto hai un repository Git con dei file tracciati ed un commit iniziale. +Tra un minuto vedremo cosa fanno questi comandi. A questo punto hai un repository Git con dei file tracciati e una commit iniziale. ### Clonare un Repository Esistente ### -Se vuoi avere la copia di un repository Git esistente — per esempio, un progetto a cui vuoi contribuire — il comando di cui hai bisogno è git clone. Se hai familiarità con altri sistemi VCS come Subversion, noterai che il comando è clone e non checkout. Questa è una distinzione importante — Git riceve una copia di circa tutti i dati che un server possiede. Ogni versione di ogni file della storia del progetto sono scaricate quando lanci `git clone`. Infatti, se il disco del tuo server è corrotto, puoi usare qualsiasi copia di qualsiasi client per ripristinare il server allo stato in cui era quando è stato clonato (puoi perdere alcuni agganci server, ma tutte le versioni dei dati saranno presenti — vedi il Capitolo 4 per maggiori dettagli). +Se vuoi copiare un repository Git esistente — per esempio, un progetto a cui vuoi contribuire — il comando di cui hai bisogno è `git clone`. Se hai familiarità con altri sistemi VCS come Subversion, noterai che il comando è `clone` e non `checkout`. Questa è una distinzione importante: Git riceve una copia di quasi tutti i dati che sono sul server. Quando esegui `git clone` vengono scaricate tutte le versioni di ciascun file della cronologia del progetto. Infatti, se si danneggiasse il disco del tuo server, potresti usare qualsiasi clone di qualsiasi client per ripristinare il server allo stato in cui era quando è stato clonato (potresti perdere alcuni `hooks` lato-server, ma tutte le versioni dei dati saranno presenti: vedi il *Capitolo 4* per maggiori dettagli). -Clona un repository con `git clone [url]`. Per esempio, se vuoi clonare la libreria Ruby Git chiamata Grit, puoi farlo così: +Cloni un repository con `git clone [url]`. Per esempio, se vuoi clonare la libreria Ruby Git chiamata Grit, puoi farlo così: $ git clone git://github.com/schacon/grit.git -Questo comando crea un directory "grit", inizializza una directory `.git` dentro di essa, scarica tutti i dati per questo repository ed imposta la copia di lavoro dell'ultima versione. Se entri nella nuova directory `grit`, vedrai i file del progetto, pronti per essere modificati o usati. Se vuoi clonare il repository in una directory con un nome diverso da grit, puoi specificarlo come opzione successiva al comando da terminale: +Questo comando crea un directory "grit", dentro di questa inizializza una directory `.git`, scarica tutti i dati del repository e fa il checkout dell'ultima versione per poterci lavorare su. Se vai nella nuova directory `grit`, vedrai i file del progetto, pronti per essere modificati o usati. Se vuoi clonare il repository in una directory con un nome diverso da grit, puoi specificarlo sulla riga di comando: $ git clone git://github.com/schacon/grit.git mygrit -Questo comando fa la stessa cosa del precedente, ma la directory di destinazione è chiamata mygrit. +Questo comando fa la stessa cosa del precedente, ma la directory di destinazione è chiamata `mygrit`. -Git può usare differenti protocolli di trasferimento. L'esempio precedente usa il protocollo `git://`, ma puoi anche vedere `http(s)://` o `user@server:/path.git`, che usa il protocollo di trasferimento SSH. Il Capitolo 4 introdurrà tutte le opzioni disponibili che il server può impostare per farti accedere al repository Git ed i pro e i contro di ognuna. +Git può usare differenti protocolli di trasferimento. L'esempio precedente usa il protocollo `git://`, ma puoi anche vedere `http(s)://` o `user@server:/path.git`, che usa il protocollo di trasferimento SSH. Il *Capitolo 4* introdurrà tutte le opzioni che un server può rendere disponibili per l'accesso al repository Git e i pro e i contro di ciascuna. -## Registrare i Cambiamenti nel Repository ## +## Salvare le modifiche sul repository ## -In buona fede hai copiato un repository Git e hai la copia di lavoro dei file di questo progetto. Ora puoi apportare alcune modifiche ed inviare gli snapshots di questi cambiamenti nel tuo repository ogni volta che il progetto raggiunge uno stato che vuoi registrare. +Hai clonato un vero repository Git e hai la copia di lavoro dei file del progetto. Ora puoi fare qualche modifica e inviare gli snapshots di queste al tuo repository ogni volta che il progetto raggiunga uno stato che vuoi salvare. -Ricorda che ogni file nella tua directory di lavoro è in una dei due stati seguenti: *tracciato* o *non tracciato*. I file *tracciati* sono i file presenti nell'ultimo snapshot; possono essere *non modificati*, *modificati* o *staged* (parcheggiati, ndt). I file *non tracciati* sono tutti gli altri - qualsiasi file nella tua directory di lavoro che non è presente nel tuo ultimo snapshot o nella tua area di stage. Quando cloni per la prima volta un repository, tutti i tuoi file sono tracciati e non modificati perché li hai appena prelevati e non hai modificato ancora niente. +Ricorda che ogni file della tua directory di lavoro può essere in uno dei due stati seguenti: *tracked* (tracciato, ndt.) o *untracked* (non tracciato, ndt.). I file *tracked* sono già presenti nell'ultimo snapshot; possono quindi essere *unmodified* (non modificati, ndt.), *modified* (modificati, ndt.) o *staged*. I file *untracked* sono tutti gli altri: qualsiasi file nella tua directory di lavoro che non è presente nell'ultimo snapshot o nella tua area di stage. Quando cloni per la prima volta un repository, tutti i tuoi file sono tracciati e non modificati perché li hai appena prelevati e non hai modificato ancora niente. -Quando modifichi i file, Git li vede come cambiati, perché li hai modificati rispetto all'ultimo commit. Parcheggi questi file e poi esegui il commit di tutti i cambiamenti presenti nell'area di stage, ed il ciclo si ripete. Questo ciclo di vita è illustrato nella Figura 2-1. +Quando editi dei file, Git li vede come modificati, perché sono cambiati rispetto all'ultima commit. Metti nell'area di stage i file modificati e poi fai la commit di tutto ciò che è in quest'area, e quindi il ciclo si ripete. Questo ciclo di vita è illustrato nella Figura 2-1. Insert 18333fig0201.png Figura 2-1. Il ciclo di vita dello stato dei tuoi file. -### Controlla lo Stato dei Tuoi File ### +### Controlla lo stato dei tuoi file ### -Lo strumento principale che userai per determinare quali file sono in un certo stato è il comando git status. Se lanci questo comando direttamente dopo aver fatto una clonazione, dovresti vedere qualcosa di simile a: +Lo strumento principale che userai per determinare lo stato dei tuoi file è il comando `git status`. Se esegui questo comando appena dopo un clone, dovresti vedere qualcosa di simile: $ git status # On branch master - nothing to commit (working directory clean) + nothing to commit, working directory clean -Questo significa che hai una directory di lavoro pulita — in altre parole, non c'è traccia di file modificati. Git inoltre non vede altri file non tracciati, altrimenti sarebbero elencati qui. Infine, il comando ci dice in quale ramo si è. Per ora, è sempre il master, che è il predefinito; non preoccuparti di questo per ora. Il prossimo capitolo tratterà delle ramificazioni e dei riferimenti nei dettagli. +Questo significa che hai una directory di lavoro pulita, ovvero che nessuno dei file tracciati è stato modificato. Inoltre Git non ha trovato nessun file non ancora tracciato, altrimenti sarebbero elencati qui. In aggiunta il comando indica anche in quale ramo sei. Per ora, è sempre `master`, che è il predefinito; non preoccupartene per ora. Il prossimo capitolo tratterà in dettagli dei `branch` (ramificazioni) e dei riferimenti. -Ora diciamo che hai aggiunto un nuovo file al tuo progetto, un semplice file README. Se il file non esisteva prima, e lanci `git status`, vedrai il tuo file non tracciato come segue: +Immagina di aver aggiunto un nuovo file al tuo progetto, un semplice README. Se il file non esisteva e lanci `git status`, vedrai così il file non tracciato: $ 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) -Puoi vedere che il tuo nuovo file README non è tracciato, perché è sotto al titolo "Untracked files" nell'output degli stati. Untracked fondamentalmente significa che Git vede un file che non avevi nel precedente snapshot (commit); Git non inizierà ad includerlo negli snapshot dei tuoi commit fino a quando tu non glielo dirai esplicitamente. Si comporta così per evitare che tu accidentalmente includa file binari generati o qualsiasi altro tipo di file che non vuoi sia incluso. Se vuoi includere il file README, continua con il tracciamento dei file. +Puoi vedere che il nuovo file README non è tracciato poiché nell'output è nella sezione dal titolo "Untracked files". `Untracked` significa che Git vede un file che non avevi nello `snapshot` precedente (commit); Git non lo includerà negli snapshot delle tuoe commit fino a quando non glielo dirai esplicitamente. Fa così per evitare che includa accidentalmente dei file binari generati o qualsiasi altro tipo di file che non intendi includere. Se vuoi includere il README, iniziamo a tracciarlo. ### Tracciare Nuovi File ### -Per iniziare a tracciare un nuovo file, usa il comando `git add`. Per tracciare il file `README`, lancia questo comando: +Per iniziare a tracciare un nuovo file, si usa il comando `git add`. Per tracciare il file `README`, usa questo comando: $ git add README -Se lanci nuovamente il comando di stato, puoi vedere il tuo file `README` tracciato e parcheggiato: +Se lanci nuovamente il comando per lo stato, puoi vedere che il tuo file `README` ora è tracciato e nell'area di `stage`: $ 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 + -Ti dice che è in stage (parcheggiato, ndt) perché è sotto al titolo "Changes to be committed". Se fai ora il commit, la versione del file al momento in cui hai lanciato `git add` sarà quella che troverai nella storia dello snapshot. Potresti ricordare che quando hai eseguito `git init` precedentemente, poi hai dovuto lanciare `git add (file)` — che era necessario per l'inizio del tracciamento dei file nella tua directory. Il comando git add prende il nome del percorso di ogni file o directory; se è una directory, il comando aggiunge tutti i file in quella directory ricorsivamente. +Sai che è nell'area di `stage` perché è nella sezione "Changes to be committed". Se a questo punto fai commit, la versione del file com'era quando hai lanciato `git add` sarà quella che troverai nella cronologia dello snapshot. Ricorderai che quando prima hai eseguito `git init`, poi hai dovuto lanciare `git add (file)`, che era necessario per iniziare a tracciare i file nella tua directory. Il comando `git add` accetta il nome del percorso di un file o una directory; se è una directory, il comando aggiunge ricorsivamente tutti i file in quella directory. -### Parcheggiare File Modificati ### +### Fare lo stage dei file modificati ### -Ora modifichiamo un file che è già stato tracciato. Se modifichi un file precedentemente tracciato chiamato `benchmarks.rb` e poi avvii nuovamente il comando `status`, otterrai qualcosa di simile a: +Modifichiamo un file che è già tracciato. Se modifichi un file tracciato chiamato `benchmarks.rb` e poi esegui il comando `status`, otterrai qualcosa di simile a: $ 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 -Il file benchmarks.rb appare sotto la sezione chiamata "Changes not staged for commit" — che significa che un file che è tracciato è stato modificato nella directory di lavoro ma non ancora messo in stage. Per parcheggiarlo, avvia il comando `git add` (è un comando multifunzione — è usato per iniziare a tracciare nuovi file, per parcheggiare i file e per fare altre cose come eseguire la fusione dei file che entrano in conflitto dopo che sono stati risolti). Avvia dunque `git add` per parcheggiare ora il file benchmarks.rb, e avvia nuovamente `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 + + +Il file benchmarks.rb appare nella sezione chiamata "Changes not staged for commit" — che significa che un file tracciato è stato modificato nella directory di lavoro ma non è ancora nello stage. Per farlo, esegui il comando `git add` (è un comando multifunzione — lo usi per iniziare a tracciare nuovi file, per fare lo stage dei file e per fare altre cose, ad esempio per segnare come risolti i conflitti causati da un `merge`). Esegui `git add` per mettere in `stage` il file benchmarks.rb, e riesegui `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 + -Entrambi i file sono parcheggiati ed entreranno nel prossimo commit. A questo punto, supponendo che tu ti sia ricordato di una piccola modifica da fare a benchmarks.rb prima di fare il commit. Apri nuovamente il file ed esegui la modifica, e ora sei pronto per il commit. Come sempre, lanci `git status` ancora una volta: +Entrambi i file sono nello `stage` e staranno nella prossima commit. A questo punto, immagina che ti sia ricordato di una piccola modifica da fare in 'benchmarks.rb' prima della commit. Riapri il file e fai la modifica: ora sei pronto per la commit. Come sempre, esegui `git status` di nuovo: $ 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 - # - -Che succede? Ora benchmarks.rb è elencato sia in stage che non. Come è possibile? É saltato fuori che Git ha parcheggiato il file esattamente come se tu avessi avviato il comando git add. Se esegui ora il commit, la versione di benchmarks.rb che verrà inviata nel commit sarà quella di quando tu hai lanciato il comando git add, non la versione del file che appare nella tua directory di lavoro quando lanci git commit. Se modifichi un file dopo che hai lanciato `git add`, devi nuovamente avviare `git add` per parcheggiare l'ultima versione del file: + 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 + + +Cos'è successo? Ora `benchmarks.rb` è elencato sia dentro che fuori lo `stage`. Come è possibile? È saltato fuori che Git ha messo in `stage` il file esattamente com'era quando hai eseguito `git add`. Se committi ora, la versione di `benchmarks.rb` che verrà committata sarà quella che avevi quando hai eseguito il `git add`, non la versione del file che trovi nella directory di lavoro quando esegui `git commit`. Se modifichi un file dopo che hai eseguito `git add`, devi rieseguire `git add` per mettere nello `stage` l'ultima versione del 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 + ### Ignorare File ### -Spesso, si ha una classe di file che non si vuole automaticamente aggiungere o far vedere come file non tracciati a Git. Ci sono generalmente alcuni file generati automaticamente come i file di log o i file prodotti dalla creazione di un sistema. In questi casi, puoi creare un file chiamato .gitignore con una lista di pattern corrispondente ad essi. Questo è un esempio di file .gitignore: +Spesso hai dei file che non vuoi che Git aggiunga automaticamente e nemmeno che te li mostri come tracciati. Generalmente si tratta di file generati automaticamente, come i log o quelli prodotti dal tuoi sistema di `build`. In questi casi puoi creare un file chiamato `.gitignore` con la lista di pattern dei file che vuoi ignorare. Questo è un `.gitignore` d'esempio: $ cat .gitignore *.[oa] *~ -La prima linea dice a Git di ignorare qualsiasi file che finisce con .o o .a — file di oggetti o archivi che possono essere il prodotto di una compilazione del tuo codice. La seconda linea dice a Git di ignorare tutti i file che finiscono con la tilde (`~`), che è usata da alcuni editor di testo come Emacs per marcare i file temporanei. Puoi anche includere directory di log, tmp o pid; documentazioni generate automaticamente; e così via. Imposta un file .gitignore prima di di procedere è generalmente una buona idea, così si evita il rischio di eseguire accidentalmente dei commit dei file che non vuoi nel tuo repository Git. +La prima riga dice a Git di ignorare qualsiasi file che finisce in `.o` o `.a` — file di oggetti o archivi che possono essere il prodotto di una compilazione del tuo codice. La seconda riga dice a Git di ignorare tutti i file che finiscono con tilde (`~`), che è usata da alcuni editor di testo come Emacs per marcare i file temporanei. Puoi anche includere le directory `log`, `tmp` o `pid`, documenti generati automaticamente e così via. Definire un file `.gitignore` prima di iniziare generalmente è una buona idea, così eviti il rischio di committare accidentalmente dei file che non vuoi nel tuo repository Git. -Le regole per i pattern che puoi mettere nel file .gitignore sono le seguenti: +Queste sono le regole per i pattern che puoi usare in `.gitignore`: -* Linee vuote o linee che iniziano con # sono ignorate. -* I glob pattern standard (formati usati per indicare classi di caratteri nelle shell, ndt) funzionano. -* Puoi terminare i pattern con un diviso (`/`) per specificare una directory. -* Puoi negare un pattern aggiungendo all'inizio il punto di esclamazione (`!`). +* Le righe vuote o che inizino con `#` vengono ignorate. +* Gli standard `glob pattern` funzionano (http://it.wikipedia.org/wiki/Glob_pattern, ndt). +* Puoi terminare i pattern con uno slash (`/`) per indicare una directory. +* Puoi negare un pattern facendolo iniziare con un punto esclamativo (`!`). -I glob pattern sono come espressioni regolari semplificate usate dalla shell. Un asterisco (`*`) corrisponde a zero o più caratteri; `[abc]` corrispondente ad ogni carattere all'interno delle parentesi (in questo caso a, b, o c); il punto di domanda (`?`) corrispondente ad un singolo carattere; ed i caratteri all'interno delle parentesi quadre separati dal segno meno (`[0-9]`) corrispondono ad ogni carattere all'interno del range impostato (in questo caso da 0 a 9). +I `glob pattern` sono come espressioni regolari semplificate, usate dalla shell. L'asterisco (`*`) corrisponde a zero o più caratteri; `[abc]` corrisponde a ogni carattere all'interno delle parentesi (in questo caso `a`, `b`, o `c`); il punto interrogativo (`?`) corrisponden ad un carattere singolo; e i caratteri all'interno delle parentesi quadre separati dal segno meno (`[0-9]`) corrispondono ad ogni carattere all'interno dell'intervallo (in questo caso da 0 a 9). -Questo è un altro esempio di file .gitignore: +Questo è un altro esempio di file `.gitignore`: # un commento - questo è ignorato - # no file .a + # escludi i file .a *.a - # ma traccia lib.a, mentre vengono ignorati tutti i file .a come sopra + # ma traccia lib.a, sebbene su tu stia ignorando tutti i file `.a` !lib.a - # ignora solamente il file TODO in root, non del tipo subdir/TODO + # ignora solo il TODO nella root, e non subdir/TODO /TODO # ignora tutti i file nella directory build/ build/ @@ -183,28 +186,29 @@ Questo è un altro esempio di file .gitignore: # ignora tutti i file .txt nella directory doc/ doc/**/*.txt -Un pattern `**/` è disponibile in Git dalla version 1.8.2. +Il pattern `**/` è disponibile in Git dalla version 1.8.2. -### Visualizzare le Tue Modifiche Parcheggiate e Non ### +### Mostra le modifiche dentro e fuori lo `stage` ### -Se il comando `git status` è troppo vago per te — vorrai conoscere esattamente cosa hai modificato, non solamente i file che hai cambiato — puoi usare il comando `git diff`. Scopriremo in maggior dettaglio `git diff` più avanti; ma probabilmente lo userai più spesso per rispondere a queste due domande: Cosa hai modificato, ma non ancora parcheggiato? E cosa hai parcheggiato e che sta per mettere nel commit? Certamente, `git status` risponde a queste domande in generale, `git diff` ti mostra le linee esatte aggiunte e rimosse — la patch, per così dire. +Se `git status` è troppo vago per te - vuoi sapere cos'è stato effettivamente modificato e non solo quali file — puoi usare il comando `git diff`. Tratteremo più avanti `git diff` con maggior dettaglio, ma probabilmente lo userai molto spesso per rispondere a queste due domande: Cos'è che hai modificato ma non è ancora in `stage`? E cos'hai nello `stage` che non hai ancora committato? Sebbene `git status` risponda a queste domande in modo generico, `git diff` mostra le righe effettivamente aggiunte e rimosse — la patch così com'è. -Nuovamente ti chiedo di modificare e parcheggiare il file README e poi modificare il file benchmarks.rb senza parcheggiarlo. Se lanci il comando `status`, vedrai nuovamente questo: +Supponiamo che tu abbia modificato nuovamente `README` e `benchmarks.rb` ma messo nello `stage` solo il primo. Se esegui il comando `status`, vedrai qualcosa come questo: $ 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 - # - -Per vedere cosa hai modificato, ma non ancora parcheggiato, digita `git diff` senza altri argomenti: + 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 + + +Per vedere cosa hai modificato, ma non ancora nello `stage`, digita `git diff` senza altri argomenti: $ git diff diff --git a/benchmarks.rb b/benchmarks.rb @@ -223,9 +227,9 @@ Per vedere cosa hai modificato, ma non ancora parcheggiato, digita `git diff` se log = git.commits('master', 15) log.size -Questo comando compara cosa c'è nella tua directory di lavoro con quello che è nella tua area di stage. Il risultato ti dice i cambiamenti che hai fatto che non sono ancora stati parcheggiati. +Questo comando confronta cosa c'è nella tua directory di lavoro con quello che c'è nella tua area di `stage`. Il risultato mostra le tue modifiche che ancora non hai messo nello `stage`. -Se vuoi vedere cosa hai parcheggiato e cosa sarà inviato con il tuo prossimo commit, puoi usare `git diff --cached`. (Nella versione 1.6.1 e successive di Git, puoi usare anche `git diff --staged`, che dovrebbe essere più facile da ricordare). Questo comando compara i tuoi cambiamenti nell'area di stage ed il tuo ultimo commit: +Se vuoi vedere cosa c'è nello `stage` e che farà parte della prossima commit, puoi usare `git diff --cached`. (Da Git 1.6.1 in poi, puoi usare anche `git diff --staged`, che dovrebbe essere più facile da ricordare). Questo comando confronta le modifiche che hai nell'area di `stage` e la tua ultima commit: $ git diff --cached diff --git a/README b/README @@ -240,25 +244,27 @@ Se vuoi vedere cosa hai parcheggiato e cosa sarà inviato con il tuo prossimo co + +Grit is a Ruby library for extracting information from a Git repository -É importante notare che `git diff` di per se non visualizza tutti i cambiamenti fatti dal tuo ultimo commit — solo i cambiamenti che ancora non sono parcheggiati. Questo può confondere, perché se hai messo in stage tutte le tue modifiche, `git diff` non darà nessun output. +È importante notare che `git diff` di per se non visualizza tutte le modifiche fatte dall'ultima commit, ma solo quelle che non sono ancora in `stage`. Questo può confondere, perché se hai messo in `stage` tutte le tue modifiche, `git diff` non mostrereà nulla. -Per un altro esempio, se parcheggi il file benchmarks.rb e lo modifichi, puoi usare `git diff` per vedere i cambiamenti nel file che sono in stage e i cambiamenti che non sono parcheggiati: +Ecco un altro esempio, se metti in `stage` il file `benchmarks.rb` e lo modifichi, puoi usare `git diff` per vedere quali modifiche al file sono in stage e i quali non ancora: $ 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 - # - -Ora puoi usare `git diff` per vedere cosa non è ancora parcheggiato + 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 + + +Puoi quindi usare `git diff` per vedere cosa non è ancora in `stage` $ git diff diff --git a/benchmarks.rb b/benchmarks.rb @@ -271,7 +277,7 @@ Ora puoi usare `git diff` per vedere cosa non è ancora parcheggiato ##pp Grit::GitRuby.cache_client.stats +# test line -e `git diff --cached` per vedere cosa hai parcheggiato precedentemente: +e `git diff --cached` per vedere cos'è già in `stage`: $ git diff --cached diff --git a/benchmarks.rb b/benchmarks.rb @@ -290,143 +296,142 @@ e `git diff --cached` per vedere cosa hai parcheggiato precedentemente: log = git.commits('master', 15) log.size -### Eseguire il Commit delle Tue Modifiche ### +### Committa le tue modifiche ### -Ora la tua area di stage è impostata come volevi, puoi eseguire il commit delle tue modifiche. Ricorda che qualsiasi cosa che non è parcheggiata — qualsiasi file che hai creato o modificato e a cui non hai fatto `git add` — non andrà nel commit. Rimarranno come file modificati sul tuo disco. -In questo caso, l'ultima volta che hai lanciato `git status`, hai visto che tutto era parcheggiato, così sei pronto ad inviare le tue modifiche con un commit. Il modo più semplice per eseguire il commit è digitare `git commit`: +Ora che la tua area di stage è configurata come vuoi, puoi fare la commit delle tue modifiche. Ricorda che tutto ciò che non è in `stage` — qualsiasi file che hai creato o modificato per cui non hai fatto `git add` — non sarà nella commit. Rimarranno come file modificati sul tuo disco. +In questo caso, l'ultima volta che hai eseguito `git status`, hai visto che tutto era in `stage`, così sei pronto a committare le tue modifiche. Il modo più semplice per farlo è eseguire `git commit`: $ git commit -Facendo questo lanci l'editor che avevi scelto. (Questo è impostato nella tua shell dalla variabile di ambiente `$EDITOR` — generalmente vim o emacs, ovviamente puoi configurarlo con qualsiasi altro editor usando il comando `git config --global core.editor` come visto nel Capitolo 1). +Facendolo lanci il tuo editor predefinito. (Questo è impostato nella tua shell con la variabile di ambiente `$EDITOR` — generalmente vim o emacs, sebbene tu possa configurarlo con qualsiasi altro editor, usando il comando `git config --global core.editor` come hai visto nel *Capitolo 1*). -L'editor visualizzerà il seguente testo (questo è un esempio della schermata di Vim): +L'editor visualizzerà il testo (questo è un esempio della schermata di Vim): # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Changes to be committed: - # (use "git reset HEAD ..." to unstage) - # # new file: README # modified: benchmarks.rb + # ~ ~ ~ ".git/COMMIT_EDITMSG" 10L, 283C -Puoi vedere che il messaggio predefinito del commit contiene l'ultimo output del comando `git status`, commentato, e la prima riga in alto è vuota. Puoi rimuovere questi commenti ed inserire il tuo messaggio, o puoi lasciarli così per aiutarti a ricordare cosa hai inviato. (Per avere una nota di ricordo più esplicita puoi passare l'opzione `-v` a `git commit`. Così facendo inserirai i cambiamenti effettuati nell'editor in modo che tu possa vedere esattamente cosa hai fatto). Quando esci dall'editor, Git crea il tuo commit con un messaggio (con i commenti ed i cambiamenti eliminati). +Come vedi, il messaggio predefinito della commit contiene l'ultimo output del comando `git status`, commentato, e la prima riga in alto è vuota. Puoi rimuovere questi commenti e inserire il tuo messaggio di commit, o puoi lasciarli così per aiutarti a ricordare cosa stai committando. (Per una nota ancora più esplicita puoi usare l'opzione `-v` a `git commit`. Facendo saranno nel commento saranno inserite anche le modifiche stesse, così che tu possa vedere esattamente cosa hai fatto). Quando esci dall'editor, Git crea la tuo commit con un messaggio (rimuovendo commenti ed eventuali diff). -In alternativa, puoi inserire il messaggio del tuo commit in linea con il comando `commit` specificando dopo di esso l'opzione -m, come segue: +In alternativa, puoi inserire il messaggio per la tua commit alla riga di comando della `commit` specificando l'opzione -m, come segue: - $ git commit -m "Story 182: Fix benchmarks for speed" - [master]: created 463dc4f: "Fix benchmarks for speed" - 2 files changed, 3 insertions(+), 0 deletions(-) + $ git commit -m "Storia 182: Corretti benchmarks per la velocità" + [master 463dc4f] Storia 182: Corretti benchmarks per la velocità + 2 files changed, 3 insertions(+) create mode 100644 README -Ora hai creato il tuo primo commit! Puoi vedere che il commit ha riportato alcune informazioni sull'operazione: a quale ramo hai affidato il commit (`master`), quale checksum SHA-1 ha il commit (`463dc4f`), quanti file sono stati modificati e le statistiche sulle linee aggiunte e rimosse nel commit. +Hai creato la tua prima commit! Puoi vedere che la commit restituisce alcune informazioni su se stessa: su quale `branch` (ramo, ndt) hai fatto la commit (`master`), quale checksum SHA-1 ha la commit (`463dc4f`), quanti file sono stati modificati e le statistiche sulle righe aggiunte e rimosse con la commit. -Ricorda che il commit registra lo snapshot che hai impostato nella tua area di stage. Qualsiasi cosa che non hai parcheggiato rimarrà come modificata; puoi fare un altro commit per aggiungere questi alla storia del progetto. Ogni volta che fai un commit stai registrando una istantanea del tuo progetto, che puoi ripristinare o comparare successivamente. +Ricorda che la commit registra lo snapshot che hai salvato nella tua area di `stage`. Qualsiasi cosa che non è nello `stage` rimarrà lì come modificata; puoi fare un'altra commit per aggiungerli alla cronologia del progetto. Ogni volta che fai una commit, stai salvando un'istantanea (`snapshot`) del tuo progetto che puoi ripristinare o confrontare in seguito. -### Saltare l'Area di Stage ### +### Saltare l'area di stage ### -Anche se può essere estremamente utile per amministrare i commit esattamente come li vuoi, l'area di stage è molto più complessa di quanto tu possa averne bisogno nel lavoro normale. Se vuoi saltare l'area di parcheggio, Git fornisce una semplice scorciatoia. Passando l'opzione `-a` al comando `git commit` Git automaticamente parcheggia tutti i file che sono già stati tracciati facendo il commit, permettendoti di saltare la parte `git add`: +Sebbene sia estremamente utile per amministrare le commit come vuoi, l'area di stage è molto più complessa di quanto tu possa averne bisogno nel lavoro normale. Se vuoi saltare l'area di `stage`, Git fornisce una semplice accorciatoia. Con l'opzione `-a` al comando `git commit`, Git, committando, mette automaticamente nello `stage` tutti i file che erano già tracciati, permettendoti di saltare la parte `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(+) -Nota come non hai bisogno, in questo caso, di lanciare `git add` sul file benchmarks.rb prima del commit. +Nota come in questo caso non hai bisogno di eseguire `git add` per benchmarks.rb prima della commit. -### Rimuovere File ### +### Rimuovere i file ### -Per rimuovere un file con Git, hai bisogno di rimuoverlo dai file tracciati (più precisamente, rimuoverlo dall'area di stage) e poi di fare il commit. Il comando `git rm` fa questo ed inoltre rimuove il file dalla tua directory di lavoro così non lo vedrai come un file non tracciato la prossima volta. +Per rimuovere un file da Git devi rimuoverlo dai file tracciati (più precisamente, rimuoverlo dall'area di `stage`) e quindi committare. Il comando `git rm` fa questo e lo rimuove dalla tua directory di lavoro, così che la prossima volta non lo vedrai come un file non tracciato. -Se semplicemente rimuovi il file dalla directory di lavoro, sarà visto sotto l'area "Changes not staged for commit" (cioè, _non parcheggiato_) dell'output `git status`: +Se rimuovi semplicemente il file dalla directory di lavoro, apparirà nella sezione "Changes not staged for commit" (cioè, _no in `stage`_) dell'output `git status`: $ 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") -Poi, se lanci `git rm`, parcheggia il file rimosso: +Se poi esegui `git rm`, la rimozione del file viene messa nello `stage`: $ 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 + -La prossima volta che fai il commit, il file se ne andrà e non sarà più tracciato. Se modifichi il file e già aggiunto all'indice, devi forzarne la rimozione con l'opzione `-f`. Questa è una caratteristica di sicurezza per prevenire la rimozione accidentale dei dati che non sono ancora stati registrati in uno snapshot e che non possono essere recuperati da Git. +La prossima volta che committerai, il file sparirà e non sarà più tracciato. Se avevi già modificato il file e lo avevi aggiunto all'indice, devi forzarne la rimozione con l'opzione `-f`. Questa è una misura di sicurezza per prevenire la rimozione accidentale dei dati che non sono ancora stati salvati in uno `snapshot` e che non possono essere recuperati con Git. -Un'altra cosa utile che potresti voler fare è mantenere il file nel tuo albero di lavoro ma rimuoverlo dall'area di stage. In altre parole, vuoi mantenere il file sul tuo disco ma non vuoi che Git ne mantenga ancora traccia. Questo è particolarmente utile se ti dimentichi di aggiungere qualcosa al tuo file `.gitignore` ed accidentalmente lo aggiungi, come un lungo file di log od un gruppo di file `.a` compilati. Per fare questo, usa l'opzione `--cached`: +Un'altra cosa utile che potresti voler fare è mantenere il file nel tuo ambiente di di lavoro ma rimuoverlo dall'area di `stage`. In altre parole, vuoi mantenere il file sul tuo disco ma non vuoi che Git continui a tracciarlo. Questo è particolarmente utile se hai dimenticato di aggiungere qualcosa al tuo `.gitignore` e accidentalmente lo metti in `stage`, come un file di log molto grande o un gruppo di file compilati `.a`. Per farlo usa l'opzione `--cached`: $ git rm --cached readme.txt -Puoi passare file, directory o glob pattern di file al comando `git rm`. Questo significa che puoi fare cose come +Puoi passare file, directory o pattern glob di file al comando `git rm`. Questo significa che puoi fare $ git rm log/\*.log -Nota la barra inversa (`\`) di fronte a `*`. Questo è necessario perché Git ha una sua espansione dei nomi di file in aggiunta all'espansione dei filename della tua shell. Questo comando rimuove tutti i file che hanno l'estensione `.log` nella directory `log/`. O puoi fare qualcosa di simile a: +Nota la barra inversa (`\`) prima di `*`. Questo è necessario perché Git ha un'espansione propria dei nomi di file oltre a quella della tua shell. Questo comando rimuove tutti i file che hanno l'estensione `.log` nella directory `log/`. O puoi eseguire: $ git rm \*~ -Questo comando rimuove tutti i file che finiscono con `~`. +Per rimuovere tutti i file che finiscono con `~`. -### Muovere File ### +### Spostare i file ### -A differenza di altri sistemi VCS, Git non traccia esplicitamente i movimenti di file. Se rinomini un file in Git, nessun metadato è immagazzinato in Git che ti dirà che hai rinominato il file. Tuttavia, Git è abbastanza intelligente da capirlo dopo che è avvenuto — ci occuperemo di rilevare il movimento dei file più tardi. +A differenza di altri sistemi VCS, Git non traccia esplicitamente gli spostamenti dei file. Se rinomini un file in Git, nessun metadato viene salvato per dirgli che lo hai rinominato. Tuttavia, Git è abbastanza intelligente da capirlo dopo che l'hai fatto — più in la ci occuperemo di rilevare il movimento dei file. -Perciò crea un po' di confusione il fatto che Git abbia un comando `mv`. Se vuoi rinominare un file in Git, puoi lanciare qualcosa come +Può perciò creare un po' di confusione il fatto che Git abbia un comando `mv`. Se vuoi rinominare un file in Git puoi eseguire qualcosa come $ git mv file_from file_to -e questo funziona bene. Infatti, se lanci qualcosa come questo e guardi lo stato, vedrai che Git considera il file rinominato: +e funziona. Se, infatti, lanci un comando del genere e controlli lo stato, vedrai che Git considera il file rinominato: - $ git mv README.txt README + $ git mv README README.txt $ 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 -> README.txt + -Ovviamente, questo è equivalente a lanciare qualcosa come: +Ovviamente, questo è equivalente a eseguire: - $ mv README.txt README - $ git rm README.txt - $ git add README + $ mv README README.txt + $ git rm README + $ git add README.txt -Git capisce implicitamente che è stato rinominato, così non è un problema rinominare un file in questo modo o con il comando `mv`. L'unica reale differenza è che `mv` è un solo comando invece di tre — è un comando di convenienza. Più importante è che tu puoi usare qualsiasi strumento per rinominare un file, ed aggiungere/togliere più tardi, prima di un commit. +Git capisce che, implicitamente stai rinominando il file, così che non c'è differenza se rinominare un file in questo modo o con il comando `mv`. L'unica differenza reale è che `mv` è un solo comando invece di tre: è un questione di convenienza. La cosa più importante è che puoi usare qualsiasi strumento per rinominare un file, e gestire l'aggiunta/rimozione più tardi, prima della commit. -## Vedere la Storia dei Commit ## +## Vedere la cronologia delle commit ## -Dopo che hai creato un po' di commit, o se hai clonato un repository che contiene una storia di commit, probabilmente vuoi guardare indietro per vedere cosa è successo. Lo strumento base e più potente per farlo è il comando `git log`. +Dopo che avrai creato un po' di commit, o se hai clonato un repository che già ha la sua cronologia di commit, vorrai probabilmente guardare cos'è successo nel passato. Lo strumento essenziale e quello più potente per farlo è il comando `git log`. -Questi esempi usano un progetto veramente semplice chiamato simplegit che è spesso usato per le dimostrazioni. Per ottenere il progetto, lancia: +Questi esempi usano un progetto veramente semplice chiamato `simplegit` che uso spesso per gli esempi. Per ottenere il progetto, esegui git clone git://github.com/schacon/simplegit-progit.git -Quando lanci `git log` in questo progetto, dovresti avere un output che assomiglia a questo: +Quando esegui `git log` in questo progetto, dovresti avere un output che assomiglia a questo: $ git log commit ca82a6dff817ec66f44342007202690a93763949 @@ -447,11 +452,11 @@ Quando lanci `git log` in questo progetto, dovresti avere un output che assomigl first commit -In modo predefinito, senza argomenti, `git log` mostra i commit fatti nel repository in ordine cronologico inverso. Così, il commit più recente è mostrato all'inizio. Come puoi vedere, questo comando elenca ogni commit con il suo codice SHA-1, il nome dell'autore e la sua e-mail, la data di scrittura ed il messaggio di invio. +In modo predefinito, senza argomenti, `git log` mostra le commit fatte nel repository in ordine cronologico inverso. In questo modo la commit più recente è la prima ad apparire. Come vedi, questo comando elenca ogni commit con il suo codice SHA-1, il nome e l'email dell'autore, la data di salvataggio e il messaggio della commit. -Un enorme numero e varietà di opzioni da passare al comando `git log` sono disponibili per vedere esattamente cosa si sta cercando. Qui, vedremo alcune opzioni più usate. +Sono disponibili moltissime opzioni da passare al comando `git log` per vedere esattamente quello che stai cercando. Qui ne vedremo alcune tra quelle più usate. -Una delle opzioni più utili è `-p`, che mostra l'introduzione del diff di ogni commit. Puoi anche usare `-2`, che limita l'output solamente agli ultimi due ingressi: +Una delle opzioni più utili è `-p`, che mostra le differenze introdotte da ciascuna commit. Puoi usare anche `-2`, che limita l'output agli ultimi due elementi: $ git log -p -2 commit ca82a6dff817ec66f44342007202690a93763949 @@ -464,11 +469,13 @@ Una delle opzioni più utili è `-p`, che mostra l'introduzione del diff di ogni 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 @@ -491,28 +498,29 @@ Una delle opzioni più utili è `-p`, che mostra l'introduzione del diff di ogni -end \ No newline at end of file -Questa opzione visualizza le stessi informazioni ma direttamente seguita dal diff di ogni voce. Questo è veramente utile per la revisione del codice o per sfogliare velocemente cosa è successo in una serie di commit che un collaboratore ha aggiunto. +Quest'opzione mostra le stessi informazioni ma ciascun elemento è seguito dalle differenze. Questo è molto utile per revisionare il codice o per dare un'occhiata veloce a cosa è successo in una serie di commit che un collaboratore ha aggiunto. -Qualche volta è più semplice controllare i cambiamenti per parole piuttosto che per linee. Esiste un'opzione `--word-diff` disponibile in Git, che puoi aggiungere al comando `git log -p` per ottenere un word diff (differenza per parole, ndt) invece del normale diff linea per linea. Il formato Word diff è piuttosto inutile quando applicato al codice sorgente, ma diviene utile quando applicato a grandi file di testo, come libri o la tua dissertazione. Ecco un esempio: +Qualche volta è più semplice verificare le singole modifiche piuttosto che intere righe. Per questo in Git è disponibile l'opzione `--word-diff`, che puoi aggiungere al comando `git log -p` per vedere le differenze tra le parole invece di quella normale, linea per linea. Il formato `word diff` è piuttosto inutile quando applicato al codice sorgente, ma diventa utile quando applicato a grandi file di testo, come i libri o la tua tesi. Ecco un esempio: $ git log -U1 --word-diff - commit da734f4151c0bf92798edd67fb571f86ab4179e6 - Author: Jed Hartman - Date: Tue Mar 19 18:00:35 2013 -0700 - - Added a missing "in" to a sentence. + commit ca82a6dff817ec66f44342007202690a93763949 + Author: Scott Chacon + Date: Mon Mar 17 21:52:11 2008 -0700 - diff --git a/en/01-chapter2.markdown b/en/01-chapter2.markdown - index 879e48c..a992ff3 100644 - --- a/en/01-chapter2.markdown - +++ b/en/01-chapter2.markdown - @@ -553,3 +553,3 @@ You may be wondering what the difference is + changed the version number - This option adds a nice little ASCII graph showing your branch and merge history, which we can see {+in+} our copy of the Grit project repository: + 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" -Come puoi vedere, non ci sono linee aggiunte o rimosse in questo output come in un normale diff. Invece i cambiamenti sono mostrati sulla linea. Puoi vedere la parola racchiusa in `{+ +}` (parole rimosse sarebbe state mostrate come `[-removed-]`). Potresti anche volere ridurre le solite tre linee di contesto nell'output di diff a solo una linea, dato che il contesto è ora costituito da parole, non linee. Puoi farlo con `-U1` come abbiamo fatto nell'esempio qui sopra. +Come puoi vedere, non ci sono righe aggiunte o rimosse in questo output, come in una normale differenza. I cambiamente sono invece mostrati sulla stessa riga. Puoi vedere la parola aggiunta racchiusa tra `{+ +}` e quella rimossa tra `[- -]`. Potresti anche volere ridurre le solite tre righe di contesto dall'output delle differenze a una sola, poiché ora il contesto è costituito da parole e non righe. Puoi farlo con `-U1`, come abbiamo fatto nell'esempio qui sopra. -Puoi anche usare una serie di opzioni di riassunto con `git log`. Per esempio, se vuoi vedere alcune statistiche brevi per ogni commit, puoi usare l'opzione `--stat`: +Puoi usare anche una serie di opzioni di riassunto con `git log`. Per esempio, se vuoi vedere alcune statistiche brevi per ciascuna commit, puoi usare l'opzione `--stat`: $ git log --stat commit ca82a6dff817ec66f44342007202690a93763949 @@ -522,7 +530,7 @@ Puoi anche usare una serie di opzioni di riassunto con `git log`. Per esempio, s 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 @@ -531,7 +539,7 @@ Puoi anche usare una serie di opzioni di riassunto con `git log`. Per esempio, s 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 @@ -542,45 +550,50 @@ Puoi anche usare una serie di opzioni di riassunto con `git log`. Per esempio, s README | 6 ++++++ Rakefile | 23 +++++++++++++++++++++++ lib/simplegit.rb | 25 +++++++++++++++++++++++++ - 3 files changed, 54 insertions(+), 0 deletions(-) + 3 files changed, 54 insertions(+) -Come puoi vedere, l'opzione `--stat` stampa sotto ogni voce di commit una lista dei file modificati, quanti file sono stati modificati, e quante linee in questi file sono state aggiunte o rimosse. Inoltre aggiunge un resoconto delle informazioni alla fine. -Un'altra opzione veramente utile è `--pretty`. Questa opzione modifica gli output di log per la formattazione rispetto a quella predefinita. Alcune opzioni pre-costruite sono pronte all'uso. L'opzione `oneline` stampa ogni commit in una singola linea, che è utile se stai guardando una lunga serie di commit. In aggiunta le opzioni `sort`, `full` e `fuller` mostrano l'output pressapoco nello stesso modo ma con più o meno informazioni, rispettivamente: +Come puoi vedere, l'opzione `--stat` visualizza sotto ogni commit la lista dei file modificati, quanti file sono stati modificati, e quante righe in questi file sono state aggiunte e rimosse. Alla fine aggiunge anche un resoconto delle informazioni. +Un'altra opzione veramente utile è `--pretty`. Questa opzione modifica gli output di log rispetto a quella predefinita. Alcune opzioni predefinite sono pronte per l'uso. L'opzione `oneline` visualizza ogni commit su una singola linea, che è utile se stai controllando una lunga serie di commit. In aggiunta le opzioni `short`, `full` e `fuller` mostrano più o meno lo stesso output ma con più o meno informazioni, rispettivamente: $ git log --pretty=oneline ca82a6dff817ec66f44342007202690a93763949 changed the version number 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test code a11bef06a3f659402fe7563abf99ad00de2209e6 first commit -L'opzione più interessante è `format`, che ti permette di specificare la tua formattazione dell'output di log. Questa è specialmente utile quando stai generando un output da analizzare su una macchina — perché specifichi in modo preciso il formato, sai che non cambierà con gli aggiornamenti di Git: +L'opzione più interessante è `format`, che ti permette di specificare la formattazione dell'output di log. Questa è specialmente utile quando stai generando un output che sarà analizzo da una macchina, perché specificando esplicitamente il formato, sai che non cambierà con gli aggiornamenti di Git: $ git log --pretty=format:"%h - %an, %ar : %s" ca82a6d - Scott Chacon, 11 months ago : changed the version number 085bb3b - Scott Chacon, 11 months ago : removed unnecessary test code a11bef0 - Scott Chacon, 11 months ago : first commit -La Tabella 2-1 elenca alcune delle opzioni più utili da usare. +Table 2-1 lists some of the more useful options that format takes. + + Opzione Descrizione dell'output - %H Hash commit - %h Hash commit abbreviato - %T Hash tree - %t Hash tree abbreviato - %P Hash genitore - %p Hash genitore abbreviati - %an Nome autore - %ae E-mail autore - %ad Data autore (rispetta il formato dell'opzione –date= ) - %ar Data autore, relativa - %cn Nome di chi ha fatto il commit - %ce E-mail di chi ha fatto il commit - %cd Data di chi ha fatto il commit - %cr Data di chi ha fatto il commit, relativa + %H Hash della commit + %h Hash della commit abbreviato + %T Hash dell'albero + %t Hash dell'albero abbreviato + %P Hash del genitore + %p Hash del genitore abbreviato + %an Nome dell'autore + %ae e-mail dell'autore + %ad Data di commit dell'autore (il formato rispetta l'opzione --date=) + %ar Data relativa di commit dell'autore + %cn Nome di chi ha fatto la commit (`committer`, in inglese) + %ce e-mail di chi ha fatto la commit + %cd Data della commit + %cr Data relativa della commit %s Oggetto -Sarai sorpreso dalla differenza tra _author_ (l'autore) e _committer_ (chi ha eseguito il commit). L'autore è la persona che ha scritto originariamente il lavoro, mentre chi ha eseguito il commit è la persona che per ultima ha applicato il lavoro. Così, se invii una patch ad un progetto ed uno dei membri del progetto applica la patch, entrambi sarete riconosciuti — tu come l'autore ed il membro del progetto come colui il quale ha eseguito il commit. Scopriremo meglio questa distinzione nel Capitolo 5. +Potresti essere sorpreso dalla differenza tra autore e _committer_ (chi ha eseguito la commit). L'autore è la persona che ha scritto la modifica, mentre il _committer_ è l'ultima persona che ha applicato la modifica. Così, se invii una modifica a un progetto ed uno dei membri principali del progetto la applica, ne avranno entrambi il riconoscimento — tu come l'autore ed il membro del progetto come chi l'ha committata. Vedremo meglio questa distinzione nel *Capitolo 5*. -Le opzioni oneline e format sono particolarmente utili con un'altra opzione `log` chiamata `--graph`. Questa opzione aggiunge un grafico ASCII carino che mostra le diramazioni e le unioni della storia, che possiamo vedere nella copia del repository del progetto Grit: +Le opzioni `oneline` e `format` sono particolarmente utili con un'altra opzione di `log` chiamata `--graph`. Questa aggiunge un piccolo grafico ASCII carino che mostra le diramazioni e le unioni della cronologia, che possiamo vedere nella copia del repository del progetto Grit: $ git log --pretty=format:"%h %s" --graph * 2d3acf9 ignore errors from SIGCHLD on trap @@ -596,46 +609,103 @@ Le opzioni oneline e format sono particolarmente utili con un'altra opzione `log Queste sono solo alcune opzioni semplici per la formattazione dell'output di `git log` — ce ne sono altre. La tabella 2-2 elenca le opzioni che abbiamo visto prima e altre opzioni comunemente usate che possono essere utili per cambiare l'output del comando log. + + Opzione Descrizione - -p Mostra la patch introdotta per ogni commit. - --word-diff Mostra la patch nel formato word diff. + -p Mostra la modifica introdotta con ogni commit. + --word-diff Mostra la modifica nel formato `word diff`. --stat Mostra le statistiche per i file modificati in ogni commit. - --shortstat Mostra solo le linee cambiate/inserite/cancellate dal comando --stat. - --name-only Mostra la lista dei file modificati dopo le informazione del commit. - --name-status Mostra la lista dei file con le informazioni di aggiunte/modifiche/rimozioni. - --abbrev-commit Mostra solo i primi caratteri del codice checksum SHA-1 invece di tutti e 40. - --relative-date Mostra la data in un formato relativo (per esempio, "2 week ago", "2 settimane fa") invece di usare l'intero formato della data. - --graph Mostra un grafico ASCII dei rami e delle unioni della storia accando all'output di log. - --pretty Mostra i commit in un formato alternativo. L'opzione include oneline, short, full, fuller, e format (dove hai specificato la tua formattazione). + --shortstat Mostra solo le righe cambiate/aggiunte/rimosse del comando --stat. + --name-only Mostra l'elenco dei file modificati dopo le informazione della commit. + --name-status Mostra l'elenco dei file con le informazioni aggiunte/modifiche/eliminate. + --abbrev-commit Mostra solo i primi caratteri del codice SHA-1 invece di tutti i 40. + --relative-date Mostra la data in un formato relativo (per esempio, "2 week ago", "2 settimane fa") invece di usare il formato completo della data. + --graph Mostra un grafico ASCII delle diramazioni e delle unioni della cronologia insieme all'output del log. + --pretty Mostra le commit in un formato alternativo. L'opzione include oneline, short, full, fuller, e format (quando specifichi un tuo formato). --oneline Un'opzione di convenienza abbreviazione per `--pretty=oneline --abbrev-commit`. -### Limitare l'Output di Log ### +### Limita l'output del log ### -Oltre alle opzioni per la formattazione dell'output, git log accetta un numero di opzioni di limitazione — cioè, opzioni che ti permettono di vedere solo alcuni commit. Hai già visto una opzione del genere — l'opzione `-2`, che mostra solamente gli ultimi due commit. Infatti, puoi fare `-`, dove `n` è un intero per vedere gli ultimi `n` commit. In realtà, non userai spesso questa possibilità, perché Git di base veicola tutti gli output attraverso un impaginatore così vedrai solamente una pagina di log alla volta. +Oltre alle opzioni per la formattazione dell'output, `git log` accetta una serie di utili opzioni restrittive, ovvero opzioni che ti permettono di vedere solo alcune commit. Abbiamo già visto una opzione del genere, l'opzione `-2`, che mostra solamente le ultime due commit. Infatti, puoi usare `-`, dove `n` è un intero, per vedere le ultime `n` commit. In realtà non la userai spesso, perché Git accoda tutti gli output paginandoli, così vedrai solamente una pagina alla volta. -Ovviamente, le opzioni di limitazione temporali come `--since` e `--until` sono molto utili. Per esempio, questo comando prende la lista dei commit fatti nelle ultime due settimane: +Le opzioni temporali come `--since` e `--until` sono invece molto utili. Questo comando, per esempio, prende la lista dei commit fatti nelle ultime due settimane: $ git log --since=2.weeks Questo comando funziona con molti formati — puoi specificare una data (“2008-01-15”) o una data relativa come “2 years 1 day 3 minutes ago”. -Puoi inoltre filtrare l'elenco dei commit che corrispondono a dei criteri di ricerca. L'opzione `--author` ti permette di filtrare uno specifico autore e l'opzione `--grep` permette di cercare delle parole chiave nei messaggi dei commit. (Nota che se vuoi specificare sia le opzioni author e grep, devi aggiungere `--all-match` o il comando ricercherà i commit sia di uno sia di quell'altro.) +Puoi inoltre filtrare l'elenco delle commit che corrispondono a dei criteri di ricerca. L'opzione `--author` ti permette di filtrare per uno specifico autore e l'opzione `--grep` ti permette di cercare delle parole chiave nei messaggi delle commit. (Nota che specifichi entrambe le opzioni il comando cercherà le commit che corrispondano a tutte le opzioni specificate.) -L'ultima opzione di filtro veramente utile da passare a `git log` è un percorso. Se specifichi una directory o un nome di file, puoi limitare l'output del log ai commit che introducono modifiche a questi file. E' sempre l'ultima opzione fornita ed è generalmente preceduta dal doppio meno (`--`) per separare i path dalle opzioni. +Se vuoi specificare più opzioni `--grep` alternative devi usare `--all-match`. -Nella tabella 2-3 vediamo una lista di riferimento di queste e di altre opzioni comuni. +L'ultima opzione di `git log` per il filtraggio è il percorso. Se specifichi il nome di una directory o di un file, puoi limitare l'output del log alle sole commit che introducono modifiche a quei file. Questa è sempre l'ultima opzione specificata e generalmente è preceduta dal doppio meno (`--`) per separare i percorsi dalle opzioni. - Opzioni Descrizione - -(n) Vedi solo gli ultimi n commit - --since, --after Limita ai commit fatti prima o dopo una data specificata. - --until, --before Limita ai commit fatti prima o fino ad una specifica data. - --author Visualizza solo i commit in cui l'autore corrisponde alla stringa specificata. - --committer Visualizza solo i commit dove chi ha eseguito il commit corrisponde alla stringa specificata. +Nella tabella 2-3 vediamo una lista di riferimento di queste e di altre opzioni comuni. -Per esempio, se vuoi vedere quali commit modificano i file nella storia del codice sorgente di Git dove Junio Hamano ha eseguito i commit e non sono stati unificati nel mese di Ottobre del 2008, puoi lanciare qualcosa di simile a: + - $ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \ - --before="2008-11-01" --no-merges -- t/ + Opzioni Descrizione + -(n) Vedi solo le ultime n commit + --since, --after Mostra solo le commit fatte dalla data specificata. + --until, --before Mostra solo le commit fatte entro la data specificata. + --author Mostra solo le commit dell'autore specificato. + --committer Mostra solo le commit del committer specificato. + + +### Filtrare i risultati in base a data e ora ### + + Per sapere cosa è stato committato nel repository di Git (git://git.kernel.org/pub/scm/git/git.git) il 29/04/2014 (usando come riferimento il fuso orario impostato sul tuo computer) + + $ git log --after="2014-04-29 00:00:00" --before="2014-04-29 23:59:59" \ + --pretty=fuller + + Il risultato che si ottiene eseguendo questo comando cambia in base al fuso orario dove viene eseguito. È quindi consigliato usare un orario assoluto quando si usano le opzioni `--after` e `--before`, come per esempio l'ISO 8601 (che include anche informazioni sul furo orario), così da ottenere gli stessi risultati indipendentemente dal fuso orario. + +Per ottenere le commit eseguite in un determinato istante (per esempio il 29 Aprile 2013 alle 17:07:22 CET), possiamo eseguire: + + $ git log --after="2013-04-29T17:07:22+0200" \ + --before="2013-04-29T17:07:22+0200" --pretty=fuller + + commit de7c201a10857e5d424dbd8db880a6f24ba250f9 + Author: Ramkumar Ramachandra + AuthorDate: Mon Apr 29 18:19:37 2013 +0530 + Commit: Junio C Hamano + CommitDate: Mon Apr 29 08:07:22 2013 -0700 + + git-completion.bash: lexical sorting for diff.statGraphWidth + + df44483a (diff --stat: add config option to limit graph width, + 2012-03-01) added the option diff.startGraphWidth to the list of + configuration variables in git-completion.bash, but failed to notice + that the list is sorted alphabetically. Move it to its rightful place + in the list. + + Signed-off-by: Ramkumar Ramachandra + Signed-off-by: Junio C Hamano + +Data e ora di `AuthorDate` e `CommitDate` hanno un formato standard (`--date=default`) che mostra le informazioni sul fuso orario, rispettivamente, dell'autore e di chi ha eseguito la commit. + +Altri formati utili sono `--date=iso` (ISO 8601), `--date=rfc` (RFC 2822), `--date=raw` (i secondi passati dall'1/1/1970 UTC) `--date=local` (l'orario del tuo attuale fuso) e `--date=relative` (per esempio: "2 ore fa"). + +Usando `git log` senza specificare un orario equivale a specificare l'orario attuale del tuo computer (mantenendo la differenza con l'UTC). + +Per esempio, eseguendo `git log` alle 09:00 su un computer che sia 3 ore avanti rispetto all'UTC, rende equivalenti questi comandi: + + $ git log --after=2008-06-01 --before=2008-07-01 + $ git log --after="2008-06-01T09:00:00+0300" \ + --before="2008-07-01T09:00:00+0300" + +Per fare un ultimo esempio, se vuoi vedere quale commit di Junio Hamano dell'ottobre del 2008 (relative al fuso di New York) che modificano i file di test nella cronologia dei sorgenti di Git che non sono ancora state unite con merge, puoi eseguire questo: + + $ git log --pretty="%h - %s" --author=gitster \ + --after="2008-10-01T00:00:00-0400" \ + --before="2008-10-31T23:59:59-0400" --no-merges -- t/ 5610e3b - Fix testcase failure when extended attribute acd3b9e - Enhance hold_lock_file_for_{update,append}() f563754 - demonstrate breakage of detached checkout wi @@ -643,126 +713,127 @@ Per esempio, se vuoi vedere quali commit modificano i file nella storia del codi 51a94af - Fix "checkout --track -b newbranch" on detac b0ad11e - pull: allow "git pull origin $something:$cur -Ci sono circa 20,000 commit nella storia del codice sorgente di git, questo comando mostra 6 righe corrispondenti ai termini di ricerca. +Ci sono circa 20,000 commit nella cronologia dei sorgenti di git, questo comando mostra 6 righe che corrispondono ai termini della ricerca. -### Usare una GUI per Visualizzare la Storia ### +### Usare una GUI per visualizzare la cronologia ### -Se vuoi usare uno strumento più grafico per visualizzare la storia dei tuoi commit, puoi vedere un programma in Tck/Tk chiamato gitk che è distribuito con Git. Gitk è fondamentalmente uno strumento visuale come `git log`, e accetta circa tutte le opzioni di filtro che `git log` ha. Se digiti gitk dalla riga di comando del tuo progetto, dovresti vedere qualcosa di simile alla Figura 2-2. +Se vuoi usare uno strumento più grafico per visualizzare la cronologia delle tue commit, puoi provare un programma in Tck/Tk chiamato `gitk` che viene distribuito con Git. Gitk è fondamentalmente uno strumento grafico come `git log`, e accetta quasi tutte le opzioni di filtro supportate da `git log`. Se digiti `gitk` dalla riga di comando nel tuo progetto, dovresti vedere qualcosa di simile alla Figura 2-2. Insert 18333fig0202.png -Figura 2-2. Il visualizzatore della storia gitk. +Figura 2-2. Il grafico della cronologia con gitk. -Puoi vedere la storia dei commit nella metà alta della finestra con un grafico genealogico. La finestra di diff nella metà inferiore mostra i cambiamenti introdotti ad ogni commit che selezioni. +Puoi vedere la cronologia delle commit, nella metà superiore, della finestra come un albero genealogico carino. La finestra delle differenza, nella metà inferiore, mostra le modifiche introdotte con ciascuna commit che selezioni. -## Annullare le Cose ## +## Annullare qualcosa ## -Ad ogni stadio potresti voler annullare qualcosa. Qui, vedremo alcuni strumenti fondamentali per annullare i cambiamenti che hai fatto. Attenzione, perché non sempre puoi invertire alcuni annullamenti. Questa è una delle aree in Git dove puoi perdere qualche lavoro se sbagli. +In qualsiasi momento puoi voler annullare qualcosa. Rivedremo alcuni strumenti basilari per annullare le modifiche fatte. Attenzione però, perché non sempre puoi ripristinare ciò che annulli. Questa è una delle aree di Git dove puoi perdere del lavoro svolto se commetti un errore. -### Modificare il Tuo Ultimo Commit ### +### Modifica la tua ultima commit ### -Uno degli annullamenti comuni avviene quando invii troppo presto un commit e magari dimentichi di aggiungere alcuni file, o sbagli il messaggio di commit. Se vuoi provare nuovamente questo commit, puoi lanciare commit con l'opzione `--amend`: +Uno degli annullamenti più comuni si verifica quando committi qualcosa troppo presto e magari dimentichi di aggiungere qualche file, o sbagli qualcosa nel messaggio di commit. Se vuoi modificare questa commit puoi eseguire il comando commit con l'opzione `--amend`: $ git commit --amend -Questo comando prende la tua area di stage e la usa per il commit. Se non hai fatto cambiamenti dal tuo ultimo commit (per esempio, lanci questo comando subito dopo il tuo commit precedente), allora il tuo snapshot sarà esattamente uguale e potrai cambiare il tuo messaggio di commit. +Questo comando usa la tua area di `stage` per la commit. Se non hai fatto modifiche dalla tua ultima commit (per esempio, esegui questo comando subito dopo la tua commit precedente), allora il tuo snapshot sarà identico e potrai cambiare il tuo messaggio di commit. -L'editor per il messaggio del commit apparirà, ma già contiene il messaggio del commit precedente. Puoi modificare il messaggio come sempre, ma sovrascriverà il commit precedente. +Verrà lanciata la stessa applicazione per scrivere il messaggio della commit, ma conterrà già il messaggio della commit precedente. Puoi modificare il messaggio normalmente, ma questo sovrascriverà la commit precedente. -Come esempio, se fai il commit e poi realizzi di aver dimenticato un cambiamento nella tua area di stage di un file e vuoi aggiungerlo a questo commit, puoi farlo così: +Per esempio, se fai una commit e realizzi di non aver messo nello `stage` le modifiche a un file e vuoi aggiungerlo a questa commit, puoi fare così: $ git commit -m 'initial commit' $ git add forgotten_file $ git commit --amend -Tutti e tre i comandi finisco in un singolo commit — il secondo commit riscrive il risultato del primo. +Dopo questi tre comandi ti ritroverai con una sola commit: la seconda sovrascrive la prima. -### Disimpegnare un File Staged ### +### Rimuovere un file dall'area di `stage` ### -Le prossime due sezioni mostrano come gestire le modifiche della tua area di stage e della directory di lavoro. La parte divertente è che il comando che usi per determinare lo stato di queste due aree ricorda come annullare i cambiamenti fatti. Per esempio, supponiamo che hai modificato due file e vuoi inviarli come modifiche separate, ma accidentalmente digiti `git add *` e li parcheggi entrambi. Come puoi disimpegnare uno dei due? Il comando `git status` ti ricorda: +Le prossime due sezioni mostrano come gestire le modifiche della tua area di stage e della directory di lavoro. La parte divertente è che il comando che usi per determinare lo stato di queste due aree ti ricorda come annullare le modifiche alle stesse. Per esempio, supponiamo che hai modificato due file e vuoi committarli come modifiche separate, ma accidentalmente digiti `git add *` e li metti entrambi in `stage`. Come puoi rimuoverne uno? Il comando `git status` ti ricorda: $ 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 + -Ora il testo sotto “Changes to be committed”, dice di usare `git reset HEAD ...` per annullare. Così, usa questo avviso per disimpegnare il file benchmarks.rb dal parcheggio: +Il testo sotto “Changes to be committed” ti dice di usare `git reset HEAD ...` per rimuovere dallo `stage`. Usa quindi questo consiglio per rimuoever `benchmarks.rb`: $ 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 - # - -Il comando è un po' strano, ma funziona. Il file benchmarks.rb è modificato ma non parcheggiato. - -### Annullare le Modifiche di un File Modificato ### - -Come fare se hai realizzato che non vuoi più tenere le modifiche che hai fatto al file `benchmarks.rb`? Come puoi annullarle facilmente — ritornare a come era al tuo ultimo commit (o alla clonazione iniziale, o come lo avevi nella tua directory di lavoro)? Fortunatamente, `git status` ci dice come farlo. Nell'ultimo output di esempio, l'area di unstage (file non parcheggiati) assomiglia a: - - # 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 - # - -Ci dice abbastanza esplicitamente come annullare le modifiche fatte (al limite, le nuove versioni di Git, 1.6.1 e successive, lo fanno — se hai una versione più vecchia è raccomandato aggiornarla per avere queste funzioni utili). Vediamo cosa ci dice: + 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 + + +Il comando è un po' strano, ma funziona. Il file `benchmarks.rb` ora è modificato ma non più nello `stage`. + +### Annullare le modifiche a un file ### + +Come fare se ti rendi conto che non vuoi più mantenere le modifiche di `benchmarks.rb`? Come puoi annullarle facilmente — ritornare a come era prima dell'ultima commit (o al clone iniziale, o comunque lo avevi nella tua directory di lavoro)? Fortunatamente `git status` ti dice come farlo. Nell'ultimo output di esempio, l'area dei file modificati appare così: + + 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 + + +Ti dice abbastanza chiaramente come annullare le tue modifiche (almeno le nuove versioni di Git, dalla 1.6.1 in poi, lo fanno: se hai una versione più vecchia ti raccomandiamo di aggiornarla per avere alcune di queste funzioni utili e carine). Vediamo cosa dice: $ 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 + -Puoi vedere come le modifiche sono state annullate. Dovresti inoltre realizzare che è un comando pericoloso: ogni cambiamento fatto al file è sparito — semplicemente hai copiato un altro file su di esso. Non usare mai questo comando a meno che non sai assolutamente che non vuoi il file. Se hai bisogno solamente di toglierlo di torno, vedremo ripostigli e ramificazioni nei capitoli successivi ; queste sono generalmente le vie migliori da seguire. +Puoi vedere come le modifiche siano state annullate. Dovresti capire quanto questo sia un comando pericoloso: tutte le modifiche fatte al file sono sparite: lo hai praticamente sovrascritto con un altro file. Non usare mai questo comando a meno che non sia assolutamente certo di non volere il file. Se hai solo bisogno di toglierlo di torno, vedremo i `ripostigli` (*stash*) e le diramazioni (*branch*) nei prossimi capitoli, che generalmente sono le strade migliori da seguire. -Ricorda, qualsiasi cosa che è stata affidata a Git può quasi sempre essere recuperata. Tutti i commit che erano su rami che sono stati cancellati o sovrascritti tramite un commit `--amend` possono essere recuperati (vedi il *Capitolo 9* per il recupero dei dati). Tuttavia, qualsiasi cosa che perdi e che non è stata affidata a Git probabilmente non sarà mai più visto. +Ricorda: qualsiasi cosa che sia stata committata in Git può quasi sempre essere recuperata. Tutte le commit che erano sulle diramazioni che sono state cancellate o sovrascritte con una commit `--amend` possono essere recuperate (vedi il *Capitolo 9* per il recupero dei dati). Ma qualsiasi cosa che perdi che non sia stata mai committata non la vedrai mai più. -## Lavorare con Sorgenti Remote ## +## Lavorare coi server remote ## -Per essere in grado di collaborare con un qualsiasi progetto Git, hai bisogno di sapere come amministrare il tuo repository remoto. I repository remoti sono versioni di progetti che sono ospitati in Internet o su una rete da qualche parte. Puoi averne più di uno, molti dei quali possono essere di sola lettura o di scrittura e lettura per te. Collaborare con altri implica di sapere amministrare questi repository remoti e mettere e togliere i dati a e da questi quando hai necessità di condividerli per lavoro. -Amministrare repository remoti include il sapere aggiungere repository remoti, rimuovere quelli che non sono validi, amministrare vari rami remoti e definire quando sono tracciati o meno, e altro. In questa sezione, vedremo le tecniche di amministrazione remota. +Per poter collaborare con un qualsiasi progetto Git, devi sapere come amministrare i tuoi repository remoti. I repository remoti sono versioni dei progetti ospitate da qualche parte su Internet o sulla rete locale. Puoi averne molti e normalmente avrai un accesso in sola lettura o anche in scrittura. Collaborare con altri implica di sapere amministrare questi repository remoti, inviarne e prelevarne dati per condividere il lavoro. +Amministrare i repository remoti significa sapere come aggiungerli, rimuovere quelli che non più validi, amministrare varie diramazioni remote e decidere quali tracciare e quali no, e ancora altro. Di seguito tratteremo le conoscenze necessarie per farlo. -### Visualizzare la Sorgente Remota ### +### Vedi i tuoi server remoti ### -Per vedere quale server remoto hai configurato, puoi lanciare il comando git remote. Questo elenca i soprannomi di ogni nodo specificato. Se hai clonato il tuo repository, dovresti al limite vedere origin — che è il nome predefinito che Git da al server che hai clonato: +Per vedere i server remoti che hai configurato, puoi eseguire il comando `git remote`. Questo elenca i nomi brevi di ogni nodo remoto che hai configurato. Se hai clonato il tuo repository, dovresti vedere almeno *origin* — che è il nome predefinito che Git da al server da cui cloni: $ 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 -Puoi anche specificare `-v`, che mostra l'URL che Git ha salvato per il soprannome: +Puoi anche aggiungere `-v`, che mostra anche l'URL che Git ha associato a quel nome breve: $ git remote -v origin git://github.com/schacon/ticgit.git (fetch) origin git://github.com/schacon/ticgit.git (push) -Se hai più di un repository remoto, il comando li elenca tutti. Per esempio, il mio repository Grit assomiglia a questo. +Se hai più di un server remoto, il comando li elenca tutti. Per esempio, il mio repository di Grit appare così: $ cd grit $ git remote -v @@ -772,11 +843,11 @@ Se hai più di un repository remoto, il comando li elenca tutti. Per esempio, il koke git://github.com/koke/grit.git origin git@github.com:mojombo/grit.git -Questo significa che possiamo prendere i contributi da qualsiasi di questi utenti in modo facile. Ma nota che solo origin è un URL SSH, è l'unico dove posso fare il push (vedremo questa cosa nel Capitolo 4). +Questo significa che posso prendere facilmente i contributi da qualunque di questi utenti. Nota però che solamente *origin* è un URL SSH, e quindi è l'unico dove posso inviare il mio lavoro con `push` (il perché lo vedremo nel *Capitolo 4*). -### Aggiungere un Repository Remoto ### +### Aggiungere un repository remoto ### -Ho menzionato e fornito alcune dimostrazioni, nelle sezioni precedenti, sull'aggiunta di repository remoti, ma qui scendo nello specifico. Per aggiungere un nuovo repository Git con un soprannome per riconoscerlo velocemente, avvia `git remote add [soprannome] [url]`: +Nelle sezioni precedenti ho accennato all'aggiunta dei repository remoti e dato alcuni esempi, ma qui lo vedremo nello specifico. Per aggiungere un nuovo repository Git remoto con un nome breve a cui possa riferirti facilmente, esegui `git remote add [nome breve] [url]`: $ git remote origin @@ -785,7 +856,7 @@ Ho menzionato e fornito alcune dimostrazioni, nelle sezioni precedenti, sull'agg origin git://github.com/schacon/ticgit.git pb git://github.com/paulboone/ticgit.git -Ora puoi usare la stringa pb dalla linea di comando al posto dell'intero URL. Per esempio, se vuoi prelevare tutte le informazioni che Paul ha ma che ancora non hai nel tuo repository, puoi lanciare git fetch pb: +Ora potrai usare il nome `pb` alla riga di comando al posto dell'URL intero. Se vuoi, per esempio, prendere tutto ciò che ha Paul, ma che non sono ancora nel tuo repository, puoi eseguire `git fetch pb`: $ git fetch pb remote: Counting objects: 58, done. @@ -796,31 +867,31 @@ Ora puoi usare la stringa pb dalla linea di comando al posto dell'intero URL. Pe * [new branch] master -> pb/master * [new branch] ticgit -> pb/ticgit -Il ramo master di Paul è accessibile localmente come `pb/master` — puoi unirlo in uno dei tuoi rami, o puoi caricare un tuo ramo locale a questo punto per ispezionarlo. +La diramazione `master` di Paul è accessibile localmente come `pb/master` — puoi farne il `merge` in uno delle tue diramazioni, o puoi scaricarla in una tua diramazione locale se vuoi controllarla. -### Prelevare e Trarre da Sorgenti in Remoto ### +### Scarica e condividi coi server remoti ### -Come già visto, per ottenere i dati da un progetto remoto, puoi farlo: +Come abbiamo appena visto, per scaricare dati da un progetto remoto, puoi fare: $ git fetch [nome-remoto] -Il comando va sul progetto remoto e si tira giù tutti i dati dal progetto remoto che ancora non hai. Dopo aver fatto questo, dovresti avere tutti i riferimenti ai rami da questa sorgente remota, che poi potrai fondere o ispezionare in ogni momento. (Vedremo cosa sono i rami e come usarli in maggior dettaglio al *Capitolo 3*). +Il comando va sul progetto remoto e scarica tutti i dati dal progetto remoto che tu ancora non hai. Dopo averlo fatto dovresti trovare i riferimenti a tutte le diramazioni di quel server, che potrai unire o controllare in qualsiasi momento. (Vedremo in dettaglio cosa sono le diramazioni e come usarle nel *Capitolo 3*). -Se hai clonato un repository, il comando automaticamente aggiunge un repository remoto sotto il nome origin. Così, `git fetch origin` preleva ogni lavoro che è stato inserito su quel server da quando hai fatto la clonazione (o dall'ultimo prelievo). E' importante notare che il comando `fetch` mette i dati nel tuo repository locale — non unisce automaticamente e non modifica alcun file su cui tu stai lavorando. Devi eseguire la fusione manualmente nel tuo lavoro, quando sei pronto. +Quando cloni un repository, viene aggiunto automaticamente un repository remoto chiamato *origin*. In questo modo `git fetch origin` scarica le modifiche che sono state condividise con server remoto da quando lo hai clonato (o dall'ultimo tuo aggiornamento). È importante notare che il comando `fetch` scarica queste informazioni nel tuo repository locale: non le unisce automaticamente e non modifica alcun file su cui stai lavorando. Quando sei pronto dovrai essere tu a unirle al tuo lavoro, manualmente. -Se hai un ramo impostato per tracciare un ramo remoto (vedi la prossima sezione e il Capitolo 3 per maggiori informazioni), puoi usare il comando `git pull` per prelevare automaticamente e poi fondere un ramo remoto nel ramo corrente. Questo è un modo più facile e comodo di lavorare; e in modo predefinito, il comando `git clone` automaticamente imposta il tuo ramo locale master per tracciare il ramo remoto master del server che hai clonato (assumendo che il sorgente remoto abbia un ramo master). Lanciare `git pull` generalmente preleva i dati dal server di origine clonato e automaticamente prova a fondere il codice con il codice su cui stai lavorando. +Se hai una diramazione impostata per tracciarne una remota (vedi la prossima sezione e il *Capitolo 3* per maggiori informazioni), puoi usare il comando `git pull` per scaricare e unire automaticamente una diramazione remota in quella attuale. Questo potrebbe essere un modo più facile e più comodo per lavorare; e in modo predefinito, il comando `git clone` imposta automaticamente la tua diramazione `master` per tracciare il master del server che hai clonato (supponendo che il server remoto abbia una diramazione `master`). Eseguendo `git pull` vengono generalmente scaricati i dati dal server da cui hai fatto il clone originario e prova a unirli automaticamente con il codice su cui stai lavorando. -### Inserire nella Sorgente Remota ### +### Condividi coi server remoti ### -Quando hai il tuo progetto al punto in cui lo vuoi condividere, devi inviarlo a monte (push upstream). Il comando per fare questo è semplice: `git push [nome-remoto] [nome-ramo]`. Se vuoi fare il push del tuo ramo master al tuo server `origin` (ancora, generalmente con la clonazione sono impostati entrambi questi nomi automaticamente), puoi lanciare il push per mettere il tuo lavoro sul server: +Quando il tuo progetto raggiunge uno stato che vuoi condividere, devi caricarlo sul server principale. Il comando perlo è semplice: `git push [nome-remoto] [diramazione]`. Se vuoi condividere la tua diramazione `master` sul tuo server `origin` (lo ripeto: clonando questi nomi vengono generalmente definiti automaticamente), puoi eseguire il comando seguente per caricare il tuo lavoro sul server: $ git push origin master -Questo comando funziona solamente se hai fatto una clonazione da un server in cui hai i permessi di scrittura e se nessuno ha inviato dati nel mentre. Se tu e qualcun altro clonate un repository nello stesso momento ed essi inviano i dati, e poi tu invii i dati, il tuo invio verrà gustamente rifiutato. Devi prima scaricare il loro lavoro ed incorporarlo nel tuo per poter inviare le tue modifiche. Vedi il *Capitolo 3* per maggiori dettagli ed informazioni su come fare il push su server remoti. +Questo comando funziona solamente se hai clonato il tuo progetto da un server su cui hai i permessi di scrittura e se nessun altro ha caricato modifiche nel frattempo. Se cloni un repository assieme ad altri e questi caricano delle modifiche sul server, il tuo invio verrà rifiutato. Dovrai prima scaricare le loro modifiche e incorporarle con le tue per poterle poi inviare. Vedi il *Capitolo 3* per maggiori informazioni su come fare il `push` su server remoti. -### Ispezionare una Sorgente Remota ### +### Controllare un server remoto ### -Se vuoi vedere più informazioni su di una sorgente remota in particolare, puoi usare il comando `git remote show [nome-remoto]`. Se lanci il comando con un soprannome particolare, come `origin`, avrai qualcosa di simile a questo: +Se vuoi più informazioni su una particolare server remoto, puoi usare il comando `git remote show [nome-remoto]`. Se esegui il comando con un nome particolare, per esempio `origin`, avrai qualcosa di simile: $ git remote show origin * remote origin @@ -831,9 +902,9 @@ Se vuoi vedere più informazioni su di una sorgente remota in particolare, puoi master ticgit -Questo elenca tutti gli URL del repository remoto oltre che alle informazioni sui rami tracciati. Il comando utilmente ti dirà che sei sul ramo principale e se lanci `git pull`, questo automaticamente unirà il ramo master sul server remoto dopo aver prelevato tutte i riferimenti remoti. Inoltre elencherà i riferimenti che ha scaricato. +che mostra gli URL del repository remoto oltre alle informazioni sulle diramazioni tracciate. Il comando ti dice anche se esegui `git pull` mentre sei su `master`, integrerà le modifiche sul `master` remoto dopo aver scaricato tutti i riferimenti remoti. Elenca anche i riferimenti remoti che hai già scaricato. -Questo è un semplice esempio che potrai incontrare. Quando usi moltissimo Git, tuttavia, potrai vedere molte più informazioni da `git remote show`: +Questo è un esempio semplice di quanto probabilmente vedrai. Tuttavia, quando usi intensamente Git potresti trovare molte più informazioni con `git remote show`: $ git remote show origin * remote origin @@ -857,20 +928,20 @@ Questo è un semplice esempio che potrai incontrare. Quando usi moltissimo Git, Local branch pushed with 'git push' master:master -Questo comando mostra quale ramo è automaticamente caricato quando lanci `git push` su certe diramazioni. Inoltre ti mostrerà quali rami remoti sul server che ancora non possiedi, quali rami remoti possiedi e che saranno rimossi dal server, e le diramazioni che saranno automaticamente unite quando lancerai `git pull`. +Questo comando mostra quale diramazione viene scaricata automaticamente quando esegui `git push` su certe diramazioni. Mostra anche quali diramazioni remote non hai ancora scaricato, quali diramazioni remote hai in locale che sono state rimosse dal server, e le diramazioni che vengono unite automaticamente quando esegui `git pull`. -### Rimuovere e Rinominare Sorgenti Remote ### +### Rimuovere e rinominare server remoti ### -Se vuoi rinominare un riferimento, nelle nuove versioni di Git, puoi lanciare `git remote rename` per cambiare il soprannome di una sorgente remota. Per esempio, se vuoi rinominare `pb` in `paul`, puoi farlo con `git remote rename`: +Se vuoi rinominare un riferimento, con versioni più recenti di Git, puoi farlo con `git remote rename` per cambiare il nome breve di un server remoto. Se vuoi per esempio rinominare `pb` in `paul`, puoi farlo con `git remote rename`: $ git remote rename pb paul $ git remote origin paul -Vale la pena ricordare che questo cambia anche i nomi dei rami remoti. Quello che prima era riferito a `pb/master` ora è `paul/master`. +Vale la pena ricordare che questo cambia anche i nomi delle diramazioni remote. Quello che prima veniva chiamato `pb/master` ora è `paul/master`. -Se vuoi rimuovere un riferimento per una qualche ragione — hai spostato il server o non stai più usando un mirror particolare, o magari un collaboratore non collabora più — puoi usare `git remote rm`: +Se vuoi rimuovere un riferimento per qualsiasi ragione (hai spostato il server o non stai più usando un particolare mirror, o magari un collaboratore che non collabora più) puoi usare `git remote rm`: $ git remote rm paul $ git remote @@ -878,19 +949,19 @@ Se vuoi rimuovere un riferimento per una qualche ragione — hai spostato il ser ### Etichettare ### -Come la maggior parte dei VCS, Git ha la possibilità di contrassegnare (tag, ndt) dei punti specifici della storia come importanti. Generalmente, le persone usano questa funzionalità per marcare i punti di rilascio (v1.0, e così via). In questa sezione, imparerai come elencare le etichette disponibili, come crearne di nuove, ed i differenti tipi di etichette esistenti. +Come la maggior parte dei VCS, Git ha la possibilità di contrassegnare (tag, ndt) dei punti specifici della cronologia come importanti. Le persone normalmente usano questa funzionalità per segnare i punti di rilascio (v1.0, e così via). In questa sezione, imparerai come elencare le etichette disponibili, come crearne di nuove, e i diversi tipi di etichette esistenti. -### Elencare le Proprie Etichette ### +### Elena le etichette ### -Elencare le etichette disponibili in Git è facilissimo. Semplicemente digita `git tag`: +Elencare le etichette esistenti in Git è facilissimo. Digita semplicemente `git tag`: $ git tag v0.1 v1.3 -Questo comando elenca le etichette in ordine alfabetico; l'ordine con il quale compaiono non è realmente importante. +Questo comando elenca le etichette in ordine alfabetico; l'ordine con cui appaiono non ha importanza. -Puoi inoltre cercare le etichette con uno schema specifico. Il repository sorgente di Git, per esempio, contiene più di 240 etichette. Se sei solo interessato a vedere quelli della serie 1.4.2, puoi lanciare: +Puoi inoltre cercare etichette con uno schema specifico. Il repository sorgente di Git, per esempio, contiene più di 240 etichette. Se sei interessato a vedere solo quelli della serie 1.4.2, puoi eseguire: $ git tag -l 'v1.4.2.*' v1.4.2.1 @@ -898,13 +969,13 @@ Puoi inoltre cercare le etichette con uno schema specifico. Il repository sorgen v1.4.2.3 v1.4.2.4 -### Creare Etichette ### +### Creare etichette ### -Git usa due principali tipi di etichette: lightweight (semplificate, ndt) e annotated (commentate, ndt). Un'etichetta lightweight è molto simile ad un ramo che non è cambiato — è semplicemente un riferimento ad uno specifico commit. Le etichette annotated, tuttavia, sono salvate come oggetti nel database Git. Ne viene calcolato il checksum; contengono il nome, l'e-mail e la data di chi ha inserito l'etichetta; hanno un messaggio; e possono essere firmati e verificati con GNU Privacy Guard (GPG). É generalmente raccomandato creare etichette annotated così puoi avere tutte queste informazioni; ma se vuoi temporaneamente inserire un'etichetta e per qualche ragione non vuoi avere queste informazioni, le etichette lightweight sono ancora disponibili. +Git ha due tipi di etichette: semplici (`lightweight`, ndt) e annotate (`annotated`, ndt). Un'etichetta semplice è molto simile a una ramificazione che non cambia mai: è semplicemente un riferimento ad una commit specifica. Le etichette annotate, al contrario, sono salvate come oggetti complessi nel database Git. Ne viene calcolato il checksum, contengono il nome, l'e-mail e la data di chi ha inserito l'etichetta, hanno un messaggio d'etichetta; e possono essere firmate e verificate con GPG (GNU Privacy Guard). Generalmente si raccomanda di usare le etichette annotate così da avere tutte queste informazioni, ma se vuoi aggiungere un'etichetta temporanea o per qualche ragione non vuoi salvare quelle informazioni aggiuntive, hai sempre a disposizione le etichette semplici. -### Etichette Annotated ### +### Etichette annotate ### -Creare un'etichetta annotated in Git è semplice. La via più facile è specificare `-a` quando si lancia il comando `tag`: +Creare un'etichetta annotate in Git è semplice. Il modo più facile è specificare `-a` quando esegui il comando `tag`: $ git tag -a v1.4 -m 'my version 1.4' $ git tag @@ -912,9 +983,9 @@ Creare un'etichetta annotated in Git è semplice. La via più facile è specific v1.3 v1.4 -`-m` specifica il messaggio, che è salvato con l'etichetta. Se non specifichi un messaggio per una etichetta annotated, Git lancerà il tuo editor così potrai inserirlo. +`-m` specifica il messaggio per l'etichetta, che viene salvato con la stessa. Se non specifichi un messaggio per un'etichetta annotata, Git lancerà il tuo editor così da scriverla. -Puoi vedere i dati dell'etichetta assieme al commit in cui è stato inserito l'etichetta con il comando `git show`: +Puoi vedere i dati dell'etichetta assieme alla commit etichettata con il comando `git show`: $ git show v1.4 tag v1.4 @@ -929,18 +1000,18 @@ Puoi vedere i dati dell'etichetta assieme al commit in cui è stato inserito l'e Merge branch 'experiment' -Questo mostra le informazioni di chi ha eseguito l'etichetta, la data del commit della stessa, ed il messaggio prima di mostrare le informazioni del commit. +Questo mostra le informazioni dell'etichetta, la data in cui la commit è stata etichettata e il messaggio, prima di mostrare le informazioni della commit. -### Firmare le Etichette ### +### Etichette firmate ### -Puoi anche firmare le tue etichette con GPG, assumendo che tu abbia una chiave privata. Tutto quello che devi fare è usare `-s` invece di `-a`: +Puoi anche firmare le tue etichette con GPG, presumendo che tu abbia una chiave privata. Tutto quello che devi fare è usare `-s` invece di `-a`: $ git tag -s v1.5 -m 'my signed 1.5 tag' You need a passphrase to unlock the secret key for user: "Scott Chacon " 1024-bit DSA key, ID F721C45A, created 2009-02-09 -Se lanci `git show` su questa etichetta, potrai vedere la tua firma GPG in allegato ad essa: +Se esegui `git show` per questa etichetta, puoi vedere che è stata allegata la tua firma GPG: $ git show v1.5 tag v1.5 @@ -964,9 +1035,9 @@ Se lanci `git show` su questa etichetta, potrai vedere la tua firma GPG in alleg Più avanti, imparerai come verificare le etichette firmate. -### Etichette Lightweight ### +### Etichette semplici ### -Un altro modo per marcare i commit è usare le etichette lightweight. Questo è semplicemente fare il checksum del commit salvato in un file — nessun'altra informazione è mantenuta. Per creare un'etichetta semplificata, non fornire l'opzione `-a`, `s` o `-m`: +Un altro modo per etichettare una commit è con le etichette semplici. Questo in pratica è salvare il checksum della commit in un file: non viene salvata nessun'altra informazione. Per creare un'etichetta semplice, non usare le opzioni `-a`, `s` o `-m`: $ git tag v1.4-lw $ git tag @@ -976,7 +1047,7 @@ Un altro modo per marcare i commit è usare le etichette lightweight. Questo è v1.4-lw v1.5 -A questo punto, se lanci `git show` sulla tua etichetta, non vedrai altre informazioni aggiuntive. Il comando semplicemente mostra il commit: +Se ora lanci `git show` per questa etichetta, non vedrai altre informazioni aggiuntive. Il comando mostra solamente la commit: $ git show v1.4-lw commit 15027957951b64cf874c3557a0f3547bd83b3ff6 @@ -986,9 +1057,9 @@ A questo punto, se lanci `git show` sulla tua etichetta, non vedrai altre inform Merge branch 'experiment' -### Verificare le Etichette ### +### Verificare le etichette ### -Per verificarele etichetta firmate, usa `git tag -v [nome-tag]`. Questo comando usa la verifica GPG della firma. Avrai bisogno della chiave pubblica del firmatario nel tuo portachiavi affinché funzioni correttamente: +Per verificare un'etichetta firmata, usa `git tag -v [nome-tag]`. Questo comando usa GPG per verificare la verifica. Affinché funzioni hai bisogno che la chiave pubblica del firmatario sia nel tuo portachiavi: $ git tag -v v1.4.2.1 object 883653babd8ee7ea23e6a5c392bb739348b1eb61 @@ -1004,15 +1075,15 @@ Per verificarele etichetta firmate, usa `git tag -v [nome-tag]`. Questo comando gpg: aka "[jpeg image of size 1513]" Primary key fingerprint: 3565 2A26 2040 E066 C9A7 4A7D C0C6 D9A4 F311 9B9A -Se non hai la chiave pubblica del firmatario, otterrai qualche cosa di simile a questo invece: +Se non hai la chiave pubblica del firmatario, otterrai invece qualcosa così: gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A gpg: Can't check signature: public key not found error: could not verify the tag 'v1.4.2.1' -### Inserire una Etichetta Successivamente ### +### Etichettare successivamente ### -Puoi anche etichettare i commit che hai già superato. Supponiamo che la storia dei tuoi commit sia come questa: +Puoi etichettare anche commit passate. Supponiamo che la cronologia delle tue commit sia questa: $ git log --pretty=oneline 15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment' @@ -1026,11 +1097,11 @@ Puoi anche etichettare i commit che hai già superato. Supponiamo che la storia 964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo 8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme -Ora, supponiamo che ti sia dimenticato di mettere l'etichetta v1.2 al tuo progetto, che è al commit "updated rakefile". Puoi aggiungerlo successivamente. Per marcare questo commit, devi specificare il checksum (o parte di esso) del commit alla fine del comando: +Supponiamo che abbia dimenticato di etichettare il progetto alla `v1.2`, che era con la commit "updated rakefile". Puoi sempre aggiungerla in un secondo momento. Per etichettare questa commit, alla fine del comando, devi indicare il checksum (o parte di esso) della commit: - $ git tag -a v1.2 9fceb02 + $ git tag -a v1.2 -m 'version 1.2' 9fceb02 -Puoi vedere che hai marcato il commit: +Puoi vedere che hai etichettato la commit: $ git tag v0.1 @@ -1053,9 +1124,9 @@ Puoi vedere che hai marcato il commit: updated rakefile ... -### Condividere le Etichette ### +### Condividere le etichette ### -Di base, il comando `git push` non trasferisce le etichette sui server remoti. Devi esplicitamente inviare le etichette da condividere con il server dopo averle create. Questo processo è come condividere rami remoti — puoi lanciare `git push origin [nometag]`. +Normalmente il comando `git push` non invia le etichette sui server remoti. Devi farlo esplicitamente, dopo averle create, per condividerle con il server. Questo procedimento è come la condivisione delle diramazioni remote: puoi eseguire `git push origin [nome-tag]` $ git push origin v1.5 Counting objects: 50, done. @@ -1065,7 +1136,7 @@ Di base, il comando `git push` non trasferisce le etichette sui server remoti. D To git@github.com:schacon/simplegit.git * [new tag] v1.5 -> v1.5 -Se hai molte etichetta che vuoi inviare tutte assieme, puoi farlo usando l'opzione `--tags` del comando `git push`. Questo trasferirà tutti le tue etichette sul server remoto che non sono ancora presenti. +Se hai molte etichetta che vuoi inviare tutte assieme, puoi farlo usando l'opzione `--tags` col comando `git push`. Questo trasferirà al server remoto tutte le tue etichette che non sono ancora presenti. $ git push origin --tags Counting objects: 50, done. @@ -1079,61 +1150,64 @@ Se hai molte etichetta che vuoi inviare tutte assieme, puoi farlo usando l'opzio * [new tag] v1.4-lw -> v1.4-lw * [new tag] v1.5 -> v1.5 -Ora, quando qualcun altro clona o scarica dal tuo repository, avrà anche tutti le tue etichette. +Quando qualcuno clonerà il repository o scaricherà gli aggiornamenti, scaricherà anche tutte le tue etichette. -## Suggerimenti e Trucchi ## +## Suggerimenti ## -Prima di finire questo capitolo sulle basi di Git, ecco alcuni suggerimenti e trucchi per rendere l'esperienza nell'uso di Git più semplice, facile e familiare. Molte persone usano Git senza usare questi suggerimenti e non ci riferiremo ad essi o presumeremo che tu li abbia usati successivamente nel libro; ma probabilmente dovresti sapere come realizzarli. +Prima di terminare questo capitolo sulle basi di Git, ecco alcuni suggerimenti e trucchi per rendere la tua esperienza con Git più semplice, più facile e più familiare. Molte persone usano Git ma nessuno di questi suggerimenti e in seguito nel libro non ci riferiremo ad essi né presumeremo che tu li abbia usati, ma probabilmente dovresti sapere come realizzarli. -### Auto-Completamento ### +### Completamento automatico ### -Se usi una shell Bash, Git fornisce un piacevole script di auto completamento che può essere usato. Scarica il codice sorgente di Git, e guarda nella directory `contrib/completation`; dovrebbe esserci un file chiamato `git-completation.bash`. Copia questo file nella tua directory di home e aggiungila al tuo file `.bashrc`: +Se usi una shell Bash, Git fornisce uno script carino per il completamento automatico che potresti usare. Scaricalo direttamente dai sorgenti di Git su https://github.com/git/git/blob/master/contrib/completion/git-completion.bash. Copia questo file nella tua directory `home` e al tuo file `.bashrc` aggiungi: source ~/.git-completion.bash -Se vuoi impostare Git per avere l'auto completamento della shell Bash per tutti gli utenti, copia lo script nella directory `/opt/local/etc/bash_completion.d` sui sistemi Mac o in `/etc/bash_completion.d/` sui sistemi Linux. Questa è una directory degli script che Bash automaticamente carica per fornire l'auto completamento da shell. +Se vuoi che Git usi il completamento automatico in Bash per tutti gli utenti, copia lo script nella directory `/opt/local/etc/bash_completion.d` sui sistemi Mac o in `/etc/bash_completion.d/` sui sistemi Linux. Questa è una directory di script che Bash carica automaticamente, per fornire il completamento automatico nella shell. -Se stai usando Windows con Git Bash, che è l'installazione di base per Git su Windows con msysGit, l'auto completamento dovrebbe essere preconfigurato. +Se stai usando Windows con Git Bash, che è il predefinito quando installi Git su Windows con msysGit, il completamento automatico dovrebbe essere preconfigurato. -Premi il tasto Tab quando stai scrivendo un comando Git, e dovresti avere una serie di suggerimenti da selezionare: +Premi il tasto Tab quando stai scrivendo un comando Git, e dovresti vedere una serie di suggerimenti tra cui scegliere: $ git co commit config -In questo caso, scrivendo git co e poi premendo il tasto Tab due volte compaiono i suggerimenti commit e config. Aggiungendo `m` si completa `git commit` automaticamente. +In questo caso, scrivendo `git co` e premendo poi due volte il tasto Tab, compaiono i suggerimenti commit e config. Aggiungendo `m` automaticamente si completa `git commit`. -Questo funziona anche con le opzioni, cosa che forse è molto più utile. Per esempio, se si lancia il comando `git log` e non si ricorda una opzione, si può iniziare a pigiare il tasto Tab per vedere le corrispondenze: +Questo funziona anche con le opzioni, che probabilmente è molto più utile. Se per esempio stai eseguendo `git log` e non ricordi un'opzione, puoi premere il tasto Tab per vedere quelle disponibili: - $ git log --s - --shortstat --since= --src-prefix= --stat --summary + $ git log --s + --shortstat --sparse + --simplify-by-decoration --src-prefix= + --simplify-merges --stat + --since= --summary -Questo è un trucco davvero utile e permette di risparmiare molto tempo e lettura della documentazione. +Questo è un trucco davvero utile e permette di risparmiare molto tempo e evitarti la lettura della documentazione. -### Alias con Git ### +### Alias di Git ### -Git non deduce il comando se si digita solo in parte. Se non si vuole scrivere l'intero testo di qualsiasi comando Git, puoi facilmente scegliere un alias per ogni comando, usando `git config`. Qui ci sono un po' di esempi su alcune configurazioni che potresti volere impostare: +Git non indovina il tuo comando se ne digiti solo una parte. Se non vuoi vuole scrivere tutto il testo di un qualsiasi comando Git puoi configurare facilmente un alias per ogni comando usando `git config`. Di seguito ci sono alcuni esempi che potresti voler usare: $ git config --global alias.co checkout $ git config --global alias.br branch $ git config --global alias.ci commit $ git config --global alias.st status -Questo significa che, per esempio, invece di digitare `git commit`, hai solamente bisogno di scrivere `git ci`. Andando avanti con l'uso di Git, probabilmente ci saranno altri comandi che userai di frequente; in questi casi, non esitare a creare nuovi alias. +Questo significa che, per esempio, invece di digitare `git commit`, dovrai scrivere solo `git ci`. Andando avanti con l'uso di Git userai alcuni comandi con maggiore frequenza: e in questi casi non esitare a creare nuovi alias. -Questa tecnica può anche essere molto utile per creare comandi che ritieni dovrebbero esistere. Per esempio, per correggere un problema comune in cui si incorre quando si vuole disimpegnare un file dall'area di stage, puoi aggiungere il tuo alias unstage a Git: +Questa tecnica può essere anche molto utile per creare comandi che ritieni dovrebbero esistere. Per esempio, per correggere un problema comune in cui si incorre quando si vuole rimuovere un file dall'area di stage, puoi aggiungere il tuo alias `unstage` in Git: $ git config --global alias.unstage 'reset HEAD --' -Questo rende i seguenti due comandi equivalenti: +Questo rende equivalenti i due comandi seguenti: $ git unstage fileA $ git reset HEAD fileA -Questo sembra più pulito. É anche comodo aggiungere il comando `last`, come: +Questo sembra più pulito. É anche comodo aggiungere il comando `last`, così: $ git config --global alias.last 'log -1 HEAD' -In questo modo puoi vedere l'ultimo commit facilmente: +In questo modo puoi vedere facilmente l'ultima commit: $ git last commit 66938dae3329c7aebe598c2246a8e6af90d04646 @@ -1144,10 +1218,10 @@ In questo modo puoi vedere l'ultimo commit facilmente: Signed-off-by: Scott Chacon -Git semplicemente sostituisce il nuovo comando con quello che corrisponde all'alias. Magari, vuoi avviare un comando esterno, invece dei sotto comandi Git. In questo caso, devi avviare il comando con il carattere "!". Questo è utile se stai scrivendo i tuoi strumenti di lavoro con un repository Git. Per esempio creiamo un alias `git visual` per lanciare `gitk`: +Come immaginerai, Git semplicemente sostituisce il nuovo comando con qualsiasi cosa corrisponda all'alias. Potresti anche voler eseguire un comando esterno, piuttosto che uno di Git. In questo caso devi iniziare il comando con un "!". Questo è utile se stai scrivendo degli strumenti di lavoro tuoi per lavorare con un repository Git. Vediamolo praticamente creando l'alias `git visual` per eseguire `gitk`: $ git config --global alias.visual '!gitk' -## Riassunto ## +## Sommario ## -A questo punto, sei in grado di fare tutte le operazioni di Git base in locale — creare o clonare un repository, fare delle modifiche, parcheggiare ed inviare queste modifiche, vedere la storia di tutti i cambiamenti del repository fatti. Nel prossimo capitolo, vedremo una caratteristica vincente di Git: il suo modello di ramificazione. +A questo punto, sei in grado di eseguire tutte le operazioni di base di Git in locale: creare o clonare un repository, fare delle modifiche, mettere nello `stage` e inviare queste modifiche, vedere la cronologia delle modifiche fatte al repository. Nel prossimo capitolo, vedremo la caratteristica vincente di Git: il suo modello di ramificazione. diff --git a/it/03-git-branching/01-chapter3.markdown b/it/03-git-branching/01-chapter3.markdown index 50f2b7293..6f3ff1dbc 100644 --- a/it/03-git-branching/01-chapter3.markdown +++ b/it/03-git-branching/01-chapter3.markdown @@ -71,7 +71,7 @@ Questo è interessante, perché ora il tuo ramo testing è stato spostato in ava La Figura 3-8 mostra il risultato. -insert 18333fig0308.png +Insert 18333fig0308.png Figura 3-8. HEAD si è spostato ad un altro ramo con un checkout. Questo comando ha fatto due cose. Ha spostato il puntatore HEAD indietro per puntare al ramo master e ha riportato i file nella tua directory di lavoro allo stato in cui si trovavano in quel momento. Questo significa anche che i cambiamenti che farai da questo punto in poi saranno separati da una versione più vecchia del progetto. Essenzialmente riavvolge temporaneamente il lavoro che hai fatto nel tuo ramo testing così puoi muoverti in una direzione differente. @@ -268,7 +268,7 @@ Se vuoi usare uno strumento grafico per risolvere i problemi, puoi lanciare `git {remote}: modified Hit return to start merge resolution tool (opendiff): -Se vuoi usare uno strumento di fusione differente dal predefinito (Git usa `opendiff` in questo caso perché ho lanciato il comando su un Mac), puoi vedere tutti gli strumenti supportati all'inizio dopo “merge tool candidates”. Scrivi il nome dello strumento che vorresti usare. Nel Capitolo 7, discuteremo su come puoi modificare i valori predefiniti del tuo ambiente. +Se vuoi usare uno strumento di fusione differente dal predefinito (Git usa `opendiff` in questo caso perché ho lanciato il comando su un Mac), puoi vedere tutti gli strumenti supportati all'inizio dopo “... one of the following tools:” (uno dei seguenti strumenti, ndt.). Scrivi il nome dello strumento che vorresti usare. Nel Capitolo 7, discuteremo su come puoi modificare i valori predefiniti del tuo ambiente. Dopo che sei uscito dallo strumento di fusione, Git ti chiederà se la fusione è avvenuta con successo. Se gli dirai allo script che è così, parcheggerà i file in modo da segnarli come risolti per te. @@ -388,7 +388,7 @@ Questo può un po' confondere, quindi vediamo un esempio. Diciamo che hai un ser Insert 18333fig0322.png Figura 3-22. Un clone con Git fornisce un proprio ramo principale e un puntatore origin/master al ramo principale di origine. -Se fai del lavoro sul tuo ramo principale locale, e, allo stesso temo, qualcuno ha inviato degli aggiornamenti al ramo principale di `git.ourcompany.com`, allora la tua storia si muoverà in avanti in modo differente. Inoltre, mentre non hai contatti con il tuo server di partenza, il tuo puntatore `origin/master` non si sposterà (vedi Figura 3-23). +Se fai del lavoro sul tuo ramo principale locale, e, allo stesso tempo, qualcuno ha inviato degli aggiornamenti al ramo principale di `git.ourcompany.com`, allora la tua storia si muoverà in avanti in modo differente. Inoltre, mentre non hai contatti con il tuo server di partenza, il tuo puntatore `origin/master` non si sposterà (vedi Figura 3-23). Insert 18333fig0323.png Figura 3-23. Lavorando in locale ed avendo qualcuno che ha inviato al server remoto qualcosa rende l'avanzamento delle storie differente. diff --git a/it/04-git-server/01-chapter4.markdown b/it/04-git-server/01-chapter4.markdown index 56a46cd8c..514cd51f0 100644 --- a/it/04-git-server/01-chapter4.markdown +++ b/it/04-git-server/01-chapter4.markdown @@ -111,15 +111,16 @@ Un'altra cosa carina è che l'HTTP è un protocollo comunissimo che i firewall d L'altra faccia della medaglia nel fornire il tuo repository via HTTP è che è relativamente inefficiente per il client. In genere porta via molto tempo per clonare o scaricare dal repository, e si ha spesso un sovraccarico della rete tramite il trasferimento di volumi via HTTP rispetto ad altri protocolli di rete. Non essendo abbastanza intelligente da trasferire solo i dati di cui hai bisogno — non c'è un lavoro dinamico dalla parte del server in questa transazione — il protocollo HTTP viene spesso definito un protocollo _stupido_. Per maggiori informazioni sulle differenze nell'efficienza tra il protocollo HTTP e gli altri, vedi il Capitolo 9. -## Ottenere Git su di un Server ## +## Mettere Git su di un server ## Per inizializzare un qualsiasi server Git, devi esportare un repository esistente in un nuovo repository di soli dati — cioè un repository che non contiene la directory di lavoro. Questo è generalmente molto semplice da fare. Per clonare il tuo repository per creare un nuovo repository di soli dati, devi avviare il comando clone con l'opzione `--bare`. Convenzionalmente, un repository di soli dati in finisce in `.git`, ad esempio: $ 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. -L'output di questo comando confonde un pochino. Dato che `clone` è un `git init` quindi un `git fetch`, vediamo parte dell'output dalla parte `git init`, il quale crea una directory vuota. L'effecttivo trasferimento dell'oggetto non fornisce output, ma avviene. Ora dovresti avere una copia della directory dei dati di Git nella directory `my_project.git`. +Ora dovresti avere una copia della directory dei dati di Git nella directory `my_project.git`. La stessa cosa la si può ottenere con @@ -226,14 +227,18 @@ Devi solo aggiungerle al tuo file `authorized_keys`: $ cat /tmp/id_rsa.josie.pub >> ~/.ssh/authorized_keys $ cat /tmp/id_rsa.jessica.pub >> ~/.ssh/authorized_keys -Ora, puoi impostare un repository vuoto avviando `git init` con l'opzione `--bare`, che inizializza il repository senza la directory di lavoro: +L'autenticazione tramite chiavi SSH generalmente richiede una restrizione dei diritti di accesso ai file coinvolti. Per prevenire qualsiasi problema è necessario eseguire: + + $ chmod -R go= ~/.ssh + +Ora, puoi configurargli un repository vuoto eseguendo `git init` con l'opzione `--bare`, che inizializza il repository senza la directory di lavoro: $ cd /opt/git $ mkdir project.git $ cd project.git $ git --bare init -Poi, John, Josie o Jessica possono inviare la prima versione del loro progetto nel repository aggiungendolo come ramo remoto ed inviandolo su di un ramo. Nota che qualcuno deve accedere via shell alla macchina e creare un repository base ogni volta che si vuole aggiungere un progetto. Usiamo il nome `gitserver` per il server dove hai impostato il tuo utente 'git' ed il repository. Se lo stai usando nella rete interna e hai impostato un DNS con il punto `gitserver` per puntare a questo server, allora puoi usare il comando: +E John, Josie o Jessica possono inviare la prima versione del loro progetto nel repository aggiungendolo come ramo remoto ed inviandolo su di un ramo. Fai attenzione che ogni volta che vuoi aggiungere un progetto, qualcuno deve accedere via shell alla macchina e creare un repository base. Usiamo il nome `gitserver` per il server dove hai impostato il tuo utente 'git' ed il repository. Se lo stai usando nella rete interna e hai impostato un DNS con il punto `gitserver` per puntare a questo server, allora puoi usare il comando: # sul computer di Johns $ cd myproject @@ -734,19 +739,19 @@ GitHub è leggermente differente nello spazio dei nomi che usa per i progetti ri GitHub è inoltre una organizzazione commerciale che addebita gli account che mantengono repository privati, ma chiunque può avere un account libero per ospitare qualsiasi progetto open source come preferisce. Vedremo velocemente come ottenere ciò. -### Configurare un Account Utente ### +### Configurare un account ### -La prima cosa di cui hai bisogno è configurare un account utente gratuito. Se visiti la pagina "Pricing and Signup" all'inidirizzo `http://github.com/plans` e fai click sul pulsante "Sign Up" per un account gratuito (vedi figura 4-2), sarai portato alla pagina di iscrizione. +La prima cosa di cui hai bisogno di un account gratuito. Vai alla pagina "Plans and pricing", che trovi all'inidirizzo `http://https://github.com/pricing`, e clicca sul pulsante "Sign Up" per creare un account gratuito (vedi figura 4-2), sarai portato alla pagina di iscrizione. Insert 18333fig0402.png Figura 4-2. La pagina dei piani di GitHub. -Qui devi scegliere un nome utente che non è già stato scelto nel sistema ed inserire un indirizzo e-mail che verrà associato all'account e una password (vedi Figura 4-3). +Qui devi scegliere un nome utente che non sia già stato scelto da qualcun altro, indicare un indirizzo e-mail che verrà associato all'account e una password (vedi Figura 4-3). Insert 18333fig0403.png Figura 4-3. Il form di iscrizione di GitHub. -Se ne hai una, è buona cosa aggiungere la propria chiave pubblica SSH. Abbiamo già visto come generare una nuova chiave, nella sezione "Piccole Configurazioni". Prendi il contenuto della chiave pubblica della tua coppia di chiavi, ed incollala nel box SSH Public Key. Facendo click sul link "explain ssh keys" otterrai le istruzioni dettagliate su come fare questa cosa sui maggiori sistemi operativi. +Se già ne hai una, è buona cosa aggiungere la propria chiave pubblica SSH. Abbiamo già visto come generare una nuova chiave, nella sezione "Piccole Configurazioni". Prendi il contenuto della chiave pubblica della tua coppia di chiavi, ed incollala nel box SSH Public Key. Facendo click sul link "explain ssh keys" otterrai le istruzioni dettagliate su come fare questa cosa sui maggiori sistemi operativi. Cliccare il pulsante "I agree, sign me up" ti porta al tuo nuovo pannello utente (vedi Figura 4-4). Insert 18333fig0404.png diff --git a/it/05-distributed-git/01-chapter5.markdown b/it/05-distributed-git/01-chapter5.markdown index adb3990f0..6d453984b 100755 --- a/it/05-distributed-git/01-chapter5.markdown +++ b/it/05-distributed-git/01-chapter5.markdown @@ -105,11 +105,11 @@ Questo modello è stato originariamente scritto da Tim Pope su tpope.net: 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 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. +Negli 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 gruppi privati ### -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. +La configurazione più semplice che probabilmente incontrerai sarà di un 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. 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 `...`) @@ -285,7 +285,7 @@ A questo punto lei deve condividere il suo lavoro con John, così fa la push sul 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 + # Computer di Jessica $ git fetch origin $ git checkout -b featureB origin/master Switched to a new branch "featureB" diff --git a/it/06-git-tools/01-chapter6.markdown b/it/06-git-tools/01-chapter6.markdown index 516bf8580..50559d39e 100644 --- a/it/06-git-tools/01-chapter6.markdown +++ b/it/06-git-tools/01-chapter6.markdown @@ -1,8 +1,8 @@ -# Git Tools # +# Strumenti di Git # -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. +Finora hai imparato la maggior parte dei comandi d’uso quotidiani e i flussi di lavoro che devi conoscere per gestire o mantenere un repository Git per i tuoi sorgenti. Hai eseguito le attività di base per tracciare e committare i file, hai sfruttato il potere dell' *area di assemblamento* e le diramazioni (*branch*) e le unioni (*merge*) leggere. -Vedremo ora una serie di potenzialità di Git che potresti non usare quotidianamente, ma di cui potresti averne bisogno a un certo punto. +Ora vedremo una serie di cose molto potenti di Git che potresti non usare quotidianamente, ma di cui a un certo punto potresti averne bisogno. ## Selezione della revisione ## @@ -14,9 +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* 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. +Git è abbastanza intelligente da capire a quale *commit* ti riferisci se scrivi i primi caratteri purché il codice SHA-1 sia di almeno quattro caratteri e sia univoco: ovvero che uno solo degli oggetti nel *repository* inizi con quel SHA-1. -Per vedere per esempio una *commit* specifica, immaginiamo di eseguire 'git log' e venga identificata una *commit* dove sono state aggiunte determinate funzionalità: +Per vedere per esempio una specifica *commit*, immagina di eseguire 'git log' e trovi la *commit* dove sono state aggiunte determinate funzionalità: $ git log commit 734713bc047d87bf7eac9674765ae793478c50d3 @@ -38,7 +38,7 @@ Per vedere per esempio una *commit* specifica, immaginiamo di eseguire 'git log added some blame and merge stuff -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): +In questo caso scegli '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 @@ -51,68 +51,61 @@ Git riesce a capire un valore SHA-1 intero da uno corto, abbreviato. Se usi l’ 085bb3b removed unnecessary test code a11bef0 first commit -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. +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 ### -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? +Molte persone si preoccupa che a un certo punto, in modo del tutto casuale, ci possano essere due oggetti nel tuo *repository* che abbiano lo stesso SHA-1. Cosa succederebbe? -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. +Se dovessi committare un oggetto che abbia lo stesso hash SHA-1 di un altro oggetto che sia già nel tuo repository, Git troverà l'altro oggetto già nel database di Git e lo considererà già scritto. Se in seguito vorrai scaricare quest'ultimo ogetto, otterrai sempre le informazioni del più vecchio. -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. +Dovresti comunque essere consapevole che questo sia uno scenario molto improbabile. 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 1 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 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. +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 sia 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, in incidenti non correlati venga attaccato e ucciso da dei lupi nella stessa notte. -### Riferimenti ai *branch* ### +### Riferimenti alle diramazioni ### -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': +Il modo più diretto per specificare una *commit* è avere una diramazione (*branch* in inglese) che vi faccia riferimento, che ti permetterebbe di usare il nome della diramazione in qualsiasi comando Git che richieda un oggetto *commit* o un valore SHA-1. Se per esempio vuoi vedere l'ultima *commit* di una diramazione, i comandi seguenti sono equivalenti (supponendo che la diramazione 'topic1' punti a 'ca82a6d'): $ git show ca82a6dff817ec66f44342007202690a93763949 $ git show topic1 -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*. +Se vuoi vedere a quale SHA specifico punti una diramazione, o se vuoi vedere a quali SHA puntino questi esempi, puoi usare il comando 'rev-parse' di Git, che fa parte dei comandi sottotraccia (*plumbing* in inglese) . Nel Capitolo 9 trovi maggiori informazioni sui comandi sottotraccia ma, 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 davvero. Qui puoi quindi eseguire 'rev-parse' sulla tua diramazione. $ git rev-parse topic1 ca82a6dff817ec66f44342007202690a93763949 -### Nomi brevi di RefLog ### +### Nomi brevi dei riferimenti ### -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. +Una delle cose che Git fa dietro le quinte è aggiornare il registro dei riferimenti (*reflog* in inglese), che registra la posizione dei tuoi riferimenti HEAD e delle diramazione su cui hai lavorato negli ulti mesi. -Puoi consultare il reflog con il comando 'git reflog': +Puoi consultare il registro con il comando 'git reflog': $ git reflog - 734713b... HEAD@{0}: commit: fixed refs handling, added gc auto, updated - d921970... HEAD@{1}: merge phedders/rdocs: Merge made by recursive. - 1c002dd... HEAD@{2}: commit: added some blame and merge stuff - 1c36188... HEAD@{3}: rebase -i (squash): updating HEAD - 95df984... HEAD@{4}: commit: # This is a combination of two commits. - 1c36188... HEAD@{5}: rebase -i (squash): updating HEAD - 7e05da5... HEAD@{6}: rebase -i (pick): updating HEAD + 734713b HEAD@{0}: commit: fixed refs handling, added gc auto, updated + d921970 HEAD@{1}: merge phedders/rdocs: Merge made by recursive. + 1c002dd HEAD@{2}: commit: added some blame and merge stuff + 1c36188 HEAD@{3}: rebase -i (squash): updating HEAD + 95df984 HEAD@{4}: commit: # This is a combination of two commits. + 1c36188 HEAD@{5}: rebase -i (squash): updating HEAD + 7e05da5 HEAD@{6}: rebase -i (pick): updating HEAD -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: +Ogni volta che una diramazione viene aggiornata 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 quintultima commit a partire dalla *HEAD* del tuo *repository*, puoi usare il riferimento '@{n}' che vedi nel *output* del registro: $ git show HEAD@{5} -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: +Puoi anche usare questa sintassi per vedere dov'era una diramazione a una certa data. Se vuoi vedere, per esempio, dov'era ieri la diramazione 'master' 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* e non puoi quindi usarla per vedere *commit* più -vecchie di qualche mese. +Che mostra dov'era ieri la diramazione. Questa tecnica funziona solo per i dati che sono ancora nel registri e non puoi quindi usarla per vedere *commit* più vecchie di qualche mese. -Per vedere le informazioni del *reflog* formattate come l’output di '*git log*', puoi -eseguire il comando 'git log -g': +Per vedere le informazioni del registro formattate come l’output di `git log`, puoi eseguire il comando `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 @@ -126,24 +119,24 @@ eseguire il comando 'git log -g': Merge commit 'phedders/rdocs' -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. +E' importante notare che l'informazione del registro è solamente locale: è un registro di ciò che hai fatto nel tuo *repository*. I riferimenti non saranno uguali sui cloni degli altri. Appena dopo aver clonato un *repository* il tuo registro sarà vuoto perché non è successo ancora nulla nel tuo *repository*. Potrai eseguire 'git show HEAD@{2.months.ago}' solo se hai clonato il progetto almeno due mesi fa: se è stato clonato cinque minuti fa non otterrai nessun risultato. ### Riferimenti ancestrali ### -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: +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 vedere la cronologia del tuo progetto: $ 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 -Puoi quindi vedere la *commit* precedente specificando `HEAD^`, che significa "il genitore di HEAD": +Puoi quindi vedere la *commit* precedente specificando `HEAD^`, che significa "l'ascendente di HEAD": $ git show HEAD^ commit d921970aadf03b3cf0e71becdaab3147ba71cdef @@ -153,9 +146,7 @@ Puoi quindi vedere la *commit* precedente specificando `HEAD^`, che significa "i Merge commit 'phedders/rdocs' -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*: +Puoi specificare anche un numero dopo la `^`: per esempio `d921970^2` significa "il secondo ascendente di d921870." Questa sintassi è utile solo per incorporare delle *commit* che hanno più di un ascendente. Il primo ascendente è la diramazione dove ti trovi al momento dell'incorporamento, e il secondo è la *commit* sulla diramazione da cui hai fatto l'incorporamento: $ git show d921970^ commit 1c002dd4b536e7479fe34593e72e6c6c1819e53b @@ -171,8 +162,7 @@ Puoi anche specificare un numero dopo `^`: per esempio `d921970^2` significa Some rdoc changes -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 +Un altro modo di specificare un riferimento ancestrale è la `~`. Questo si riferisce anche al primo ascendente, quindi `HEAD~` e `HEAD^` sono equivalenti. La differenza diventa evidente quando specifichi un numero. `HEAD~2` significa "il primo ascendente del primo ascendente", o "il nonno”: attraversa i primi ascendenti il numero di volte specificato. Per esempio, nella cronologia precedente, `HEAD~3` sarebbe $ git show HEAD~3 commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d @@ -181,7 +171,7 @@ cronologia precedente, `HEAD~3` sarebbe ignore *.gem -Che può anche essere scritto come `HEAD^^^` che, di nuovo, è sempre il genitore del genitore del genitore: +Che può essere scritto anche come `HEAD^^^` che, di nuovo, è sempre il primo genitore del primo genitore del primo genitore: $ git show HEAD^^^ commit 1c3618887afb5fbcbea25b7c013f4e2114448b8d @@ -190,57 +180,57 @@ 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 secondo genitore del riferimento precedente (assumendo che si tratti di una commit d'incorporamento) usando `HEAD~3^2`, e così via. -### Intervalli di Commit ### +### 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?” +Ora che sai come specificare singole commit, vediamo come specificare intervalli di commit. Ciò è particolarmente utile per gestire le tue diramazioni: se ne hai molte puoi usare gli intervalli per rispondere a domande come “cosa c’è in questa diramazione che non ho ancora incorporato?” #### Due punti #### -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 +Il modo più comune per specificare un intervallo è con i due punti che, praticamente, chiede a Git di risolvere l’intervallo tra commit che sia raggiungibile da una commit, ma non dall’altra. Immaginiamo di avere la cronologia dell’immagine 6-1 Insert 18333fig0601.png -Figure 6-1. Esempio di cronologia per selezione di intervalli. +Figure 6-1. Esempio di cronologia per la 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: +Vuoi vedere cosa sia nella tua diramazione sperimentale che non sia ancora stato incorporato nella master: puoi chiedere a Git di mostrarti solo il registro delle commit con `master..experiment`: questo significa “tutte le commit raggiungibili da experiment che non lo siano da master”. Affinché questi esempi siano sintetici ma chiari, invece del registro effettivo di 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`: +Se volessi invece 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: +Questo è utile se vuoi mantenere aggiornata la diramazione `experiment` e sapere cosa stai per incorporare. Un’altro caso in cui si usa spesso questa sintassi è quando stai per condividere delle commit 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. +Questo comando mostra tutte le commit della tua diramazione che non sono in quella `master` del tuo repository remoto `origin`. Se esegui `git push` quando la tua diramazione attuale è associata a `origin/master`, le commit elencate da `git log origin/master..HEAD` saranno quelle che saranno inviate al server. +Puoi anche omettere una delle parti della sintassi, e Git assumerà che sia HEAD. Per esempio puoi ottenere lo stesso risultato dell’esempio precedente scrivendo `git log origin/master..`: Git sostituisce la parte mancante con HEAD. #### Punti multipli #### -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: +La sintassi dei due punti è utile come la stenografia, ma potresti voler specificare più di due branch per indicare la tua revisione, per vedere le commit che sono nelle varie diramazioni che non siano in quella attuale. Git ti permette di farlo sia con `^` che con l’opzione `--not` prima di ciascun riferimento del quale vuoi vedere le commit 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 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: +Questo è interessante, perché con questa sintassi puoi specificare più di due riferimenti nella tua richiesta, 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. +Questo produce un sistema di revisione molto potente che dovrebbe aiutarti a capire cosa c’è nelle tue diramazioni. #### 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 +L’ultima sintassi per la selezione di intervalli è quella dei tre punti, che indica tutte le commit raggiungibili da uno qualsiasi dei riferimenti ma non da entrambi. Rivedi la cronologia delle commit nella Figura 6-1. +Se vuoi vedere cosa ci sia nel `master` o in `experiment` ma non i riferimenti comuni, puoi eseguire $ git log master...experiment F @@ -248,9 +238,9 @@ Se vuoi vedere cosa sia in `master` o in `experiment` ma non i riferimenti comun D C -Che ti mostra l’output normale del *log*, ma solo con le informazioni di quelle quattro commit nel solito ordinamento cronologico. +Che ti mostra l’output normale del `log` mostrando solo le informazioni di quelle quattro commit nell'ordinamento cronologico normale. -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: +Un'opzione comunemente usata in questi casi con il comando `log` è il parametro `--left-right`, che mostra da che lato dell'intervallo si trovi ciascuna commit dell’intervallo selezionato, che rende le informazioni molto più utili: $ git log --left-right master...experiment < F @@ -260,6 +250,600 @@ In questo è comune usare il parametro `--left-right` con il comando `log`, che Con questi strumenti puoi dire facilmente a Git quale o quali commit vuoi ispezionare. +## Assemblaggio interattivo ## + +Git viene distribuito con un paio di script che rendono più semplice l'uso della riga di comando. In questo capitolo vedremo alcuni comandi interattivi che possono aiutarti a modellare le tue commit perché includano solo determinate combinazioni di parti dei file. Questi strumenti sono molto utili se modifichi molti file tutti assieme e poi decidi che vuoi distribuire le modifiche in più commit puntuali, piuttosto che un'unica grossa commit confusa. In questo modo puoi fare che le tue commit separino logicamente le tue modifiche e possano essere facilmente revisionate dagli altri sviluppatori con cui lavori. +Se esegui `git add` con le opzioni `-i` o `--interactive`, Git entrerà nella modalità interattiva, mostrandoti qualcosa del genere: + + $ git add -i + staged unstaged path + 1: unchanged +0/-1 TODO + 2: unchanged +1/-1 index.html + 3: unchanged +5/-1 lib/simplegit.rb + + *** Commands *** + 1: status 2: update 3: revert 4: add untracked + 5: patch 6: diff 7: quit 8: help + What now> + +Come vedi, questo comando mostra una vista della tua area di assemblaggio molto diversa: sono le stesse informazioni che otterà con il comando `git status`, ma in maniera più succinta e con più informazioni. Sulla sinistra mostra le modifiche che stai assemblando e quelle non ancora assemblate sulla destra. + +Dopo questa sezione c'è quella dei Comandi. Qui puoi fare una serie di cose, incluso assemblare file, disassemblarli, assemblare alcune parti dei file, aggiungere file non ancora tracciati e vedere le differenze con ciò che è già stato assemblato. + +### Assemblare e disassemblare file ### + +Se digiti `2` o `u` alla richiesta `What now>`, lo script ti chiederà quale file vuoi assemblare: + + What now> 2 + staged unstaged path + 1: unchanged +0/-1 TODO + 2: unchanged +1/-1 index.html + 3: unchanged +5/-1 lib/simplegit.rb + Update>> + +Per assemblare i file TODO e index.html, puoi digitare i numeri: + + Update>> 1,2 + staged unstaged path + * 1: unchanged +0/-1 TODO + * 2: unchanged +1/-1 index.html + 3: unchanged +5/-1 lib/simplegit.rb + Update>> + +L'asterisco (`*`) vicino a ogni file, significa che è stato selezionato per essere assemblato. Se premi INVIO alla richiesta `Update>>`, Git assembla tutto ciò che è stato selezionato: + + Update>> + updated 2 paths + + *** Commands *** + 1: status 2: update 3: revert 4: add untracked + 5: patch 6: diff 7: quit 8: help + What now> 1 + staged unstaged path + 1: +0/-1 nothing TODO + 2: +1/-1 nothing index.html + 3: unchanged +5/-1 lib/simplegit.rb + +Ora puoi vedere che i file TODO e index.html sono assemblati e simplegit.rb non lo è ancora. Se ora vuoi disassemblare il file TODO, devi digitare `3` o `r` (come `revert` - annullare): + + *** Commands *** + 1: status 2: update 3: revert 4: add untracked + 5: patch 6: diff 7: quit 8: help + What now> 3 + staged unstaged path + 1: +0/-1 nothing TODO + 2: +1/-1 nothing index.html + 3: unchanged +5/-1 lib/simplegit.rb + Revert>> 1 + staged unstaged path + * 1: +0/-1 nothing TODO + 2: +1/-1 nothing index.html + 3: unchanged +5/-1 lib/simplegit.rb + Revert>> [enter] + reverted one path + +Rivedendo lo stato di Git, puoi vedere che hai disassemblato il file TODO: + + *** Commands *** + 1: status 2: update 3: revert 4: add untracked + 5: patch 6: diff 7: quit 8: help + What now> 1 + staged unstaged path + 1: unchanged +0/-1 TODO + 2: +1/-1 nothing index.html + 3: unchanged +5/-1 lib/simplegit.rb + +Per vedere le differenze di ciò che hai assemblato puoi digitare `6` o `d` (come differenza). Ti mostrerà un elenco dei tuoi file assemblati, e potrai selezionare quelli di cui vuoi vedere le modifiche assemblate. Questo fa la stessa cosa del comando `git diff --cached`: + + *** Commands *** + 1: status 2: update 3: revert 4: add untracked + 5: patch 6: diff 7: quit 8: help + What now> 6 + staged unstaged path + 1: +1/-1 nothing index.html + Review diff>> 1 + diff --git a/index.html b/index.html + index 4d07108..4335f49 100644 + --- a/index.html + +++ b/index.html + @@ -16,7 +16,7 @@ Date Finder + +

...

+ + - + + + +