2011年12月24日土曜日

【翻訳】速くなったのはいいとして、Bundler 1.1 の他の新機能は?

Pat Shaughnessy "Besides being faster, what else is new in Bundler 1.1?" 
 http://patshaughnessy.net/2011/11/5/besides-being-faster-what-else-is-new-in-bundler-1-1


Twitter(@oshow)

201112 WEB+DB PRESS Vol.66  Bundler 
Bundler1.1  Bundler 


Bundler 1.1 



 2011115
by Pat Shaughnessy

 3Bundler 1.0  Bundler 1.1  Bundler  1.1 gem  gem Bundler 1.1  gem  gem 

 bundle outdatedbundle cleanbundle install --standalone 使Bundler  1.1 Bundler 1.1 gem 

Bundle outdated


 bundle outdated  Bundler 1.1 便 gem 調Bundler 1.0  1.1.rc  Rails 3.0.7  bundle outdated 

$ gem install bundler --pre
Successfully installed bundler-1.1.rc
1 gem installed
Installing ri documentation for bundler-1.1.rc...
Installing RDoc documentation for bundler-1.1.rc...

$ cd /path/to/an/old/rails/app

$ bundle outdated
Fetching gem metadata from http://rubygems.org/........

Outdated gems included in the bundle:
  * rake (0.9.2.2 > 0.8.7)
  * activesupport (3.1.1 > 3.0.7)
  * builder (3.0.0 > 2.1.2)
  * i18n (0.6.0 > 0.5.0)
  * activemodel (3.1.1 > 3.0.7)
  * erubis (2.7.0 > 2.6.6)
  * rack (1.3.5 > 1.2.4)
  * rack-mount (0.8.3 > 0.6.14)
  * rack-test (0.6.1 > 0.5.7)
  * actionpack (3.1.1 > 3.0.7)
  * mail (2.3.0 > 2.2.19)
  * actionmailer (3.1.1 > 3.0.7)
  * arel (2.2.1 > 2.0.10)
  * activerecord (3.1.1 > 3.0.7)
  * activeresource (3.1.1 > 3.0.7)
  * aws-ses (0.4.3 > 0.3.2)
  * ffi (1.0.10 > 1.0.9)
  * railties (3.1.1 > 3.0.7)
  * rails (3.1.1 > 3.0.7)
  * mysql2 (0.3.7 > 0.2.13)

Fetching gem metadate Bundler  RubyGems.org  API  gem 3 Bundler  gem  gem  bundle update  Rails 3.0.7  gem  Rails 3.1.1 使 rake mysql2  Rails 3.1.1  gem 

便Bundler  gem  gem 調 gem  mysql2 Rails 3.1.1 bundle update mysql2 Bundler 1.0  bundle update  gem git 使

 bundle outdated  gem 調--pre 

$ bundle outdated --pre
Fetching gem metadata from http://rubygems.org/........

Outdated gems included in the bundle (including pre-releases):
  * rake (0.9.3.beta.1 > 0.8.7)
  * activesupport (3.1.1 > 3.0.10)
  * builder (3.0.0 > 2.1.2)
  * i18n (0.6.0 > 0.5.0)
  * activemodel (3.1.1 > 3.0.10)
  * erubis (2.7.0 > 2.6.6)
  * rack (1.3.5 > 1.2.4)
  * rack-mount (0.8.3 > 0.6.14)
  * rack-test (0.6.1 > 0.5.7)
  * actionpack (3.1.1 > 3.0.10)
  * mail (2.3.0 > 2.2.19)
  * actionmailer (3.1.1 > 3.0.10)
  * arel (2.2.1 > 2.0.10)
  * activerecord (3.1.1 > 3.0.10)
  * activeresource (3.1.1 > 3.0.10)
  * aws-ses (0.4.3 > 0.3.2)
  * ffi (1.0.10 > 1.0.9)
  * thor (0.15.0.rc2 > 0.14.6)
  * railties (3.1.1 > 3.0.10)
  * rails (3.1.1 > 3.0.10)
  * delayed_job (3.0.0.pre2 > 2.1.4)
  * haml (3.2.0.alpha.8 > 3.1.3)
  * mysql2 (0.3.7 > 0.2.13)
  * ruby-debug-base (0.10.5.rc1 > 0.10.4)
  * ruby-debug (0.10.5.rc1 > 0.10.4)

これで、新しい "alpha.8" バージョンの haml や "pre2" バージョンの delayed_job など、その他インストール可能な開発版バージョンを知ることができる。

私見だが、--pre オプションは単に気のきいている機能ってだけじゃなく、各 gem にどんなリリース計画があり、自分のアプリケーションにどう影響があるかを注視するための素晴らしい方法に思える。Bundler 1.1 は、たくさんググったり RubyGems.org を探しまわらなきゃ見つからない、価値ある知識を与えてくれている。各 gem 作者が開発中のコードが自分のアプリに必要な物かどうかは別にしても、開発版の gem にアップグレードしてテストの失敗やバグを発見することで、haml や delayed_job やその他のプロジェクトへもっと簡単にコントリビュートする事ができるようになるわけだ。

bundle install --path のおさらい


 Bundler 1.1 の新機能の説明を続ける前に、Bundler 1.0 で導入された、あまり認知されていないオプションについておさらいしよう。bundle install を実行すると普通、Bundler は新しい gem を gem install の時と同じ場所へダウンロードしてインストールする。「システムの gem」というやつに混ざるわけだ。この場所は Ruby をインストールしたディレクトリの中にあり、RVM を使っている自分のラップトップではこうなる (Ruby 1.8.7):"/Users/pat/.rvm/rubies/ruby-1.8.7-p352/lib/ruby/gems/1.8/gems"

しかし、--path オプションを渡せば gem を好きなディレクトリにインストールするよう Bundler に指示できる。例えば以下のように。

$ bundle install --path vendor/bundle

 gem  "vendor/bundle/ruby/1.8/gems"  gem  --path 


 gem 

Bundler  Capistrano 使

Bundler 使

 gem 

 .bundle/config  bundle  使 bundle config 使

$ bundle config
Settings are listed in order of priority. The top value will be used.

disable_shared_gems
  Set for your local app (/path/to/an/old/rails/app/.bundle/config): "1"

path
  Set for your local app (/path/to/an/old/rails/app/.bundle/config): "vendor/bundle"

パスの設定を削除して gem のインストール先をシステムへ戻すなら、--system オプションを使おう。

$ bundle install --system

--path 
 gem 


 Bundler 1.1 使 gem --path 使 bundle install --path  gem 使 gem 使

 Rails 3.0.7  Rails 3.0.7  Rails 3.0.10  Gemfile 

gem 'rails', '3.0.10'

それから、bundle update を実行する。

$ bundle update rails
Fetching gem metadata from http://rubygems.org/........
Using rake (0.8.7)
Using abstract (1.0.0)
Installing activesupport (3.0.10)
Using builder (2.1.2)
Using i18n (0.5.0)
Installing activemodel (3.0.10)

...etc...

Using rspec-rails (2.6.0)
Using ruby-debug-base (0.10.4)
Using ruby-debug (0.10.4)
Removing actionmailer (3.0.7)
Removing actionpack (3.0.7)
Removing activemodel (3.0.7)
Removing activerecord (3.0.7)
Removing activeresource (3.0.7)
Removing activesupport (3.0.7)
Removing rails (3.0.7)
Removing railties (3.0.7)
Your bundle is updated! Use `bundle show [gemname]` to see where a bundled gem is installed.

Bundler  Rails 3.0.10  gemactivesupportactiverecord使 gem   gem gem 
 gem 

Bundle clean


  bundle clean 使 gem --path  bundle install  bundle update 

--path  gem 使bundle clean 使使 gem 

$ bundle clean
Can only use bundle clean when --path is set or --force is set

gem  --force 使

$ bundle clean --force
Removing actionmailer (3.1.1)
Removing actionpack (3.1.1)
Removing activemodel (3.1.1)
Removing activerecord (3.1.1)
Removing activeresource (3.1.1)
Removing activesupport (3.1.1)
Removing arel (2.2.1)

etc...

お分かりのように、私のラップトップにある Rails 3.1.1 アプリはたった今すべて壊れてしまった! 予想通り、Bundler は今対象としているアプリケーションのバンドルには含まれていない gem を全て削除してしまった。この場合、今いじっていたアプリケーションは Rails 3.0.10 をバンドルしていたのだから、それには無関係な gem(Rails 3.1.1)を削除したというわけだ。

bundle clean --force は、しばらくの間一つの Ruby アプリケーションしか触らない予定だと分かっていて、gem を整理してディスクスペースを節約したい時は便利だと思われる。システムの gem を綺麗にしておくことは、Bundler を使っていないレガシー Rails アプリケーションが気づかない内にシステムに入れている gem にうっかり依存してしまわないようにするのにも役立つ。

Bundle install --standalone


 これも Bundler 1.1 での新しいオプションで、Bundler がインストールされていないサーバやその他マシンでも動作するようなバンドルを作成させてくれる。以下のように実行される。

$ bundle install --standalone
Using rake (0.8.7) 
Using abstract (1.0.0) 
Using activesupport (3.0.9) 
Using builder (2.1.2) 

... etc...

Using rspec (2.7.0) 
Using rspec-rails (2.7.0) 
Using ruby-debug-base (0.10.4) 
Using ruby-debug (0.10.4) 
Your bundle is complete! It was installed into ./bundle

このオプションにより bundle install --path ./bundle を実行した時に作成されるのと同じ、バンドル内容を格納したローカルディレクトリがもたらされる。ただし、"bundle/bundler/setup.rb" という追加ファイルが作成される点が違う。

$ find bundle | more
bundle
bundle/bundler
bundle/bundler/setup.rb
bundle/ruby
bundle/ruby/1.8
bundle/ruby/1.8/bin
bundle/ruby/1.8/bin/cdiff

... etc...

このファイルの中身を見てみると、バンドルに含まれる各 gem の lib ディレクトリをロードパスに追加するコードが入っているのが分かる。

path = File.expand_path('..', __FILE__)
$:.unshift File.expand_path("#{path}/../ruby/1.8/gems/rake-0.8.7/lib")
$:.unshift File.expand_path("#{path}/../ruby/1.8/gems/abstract-1.0.0/lib")
$:.unshift File.expand_path("#{path}/../ruby/1.8/gems/activesupport-3.0.10/lib")
$:.unshift File.expand_path("#{path}/../ruby/1.8/gems/builder-2.1.2/lib")
$:.unshift File.expand_path("#{path}/../ruby/1.8/gems/i18n-0.5.0/lib")
$:.unshift File.expand_path("#{path}/../ruby/1.8/gems/activemodel-3.0.10/lib")

Bundler  Bundler Bundler  Gemfile 


  Bundler 1.1 ChangeLog 調http://gembundler.com 

関連記事:【翻訳】なぜ Bundler 1.1 は速くなるのか

【翻訳】なぜ Bundler 1.1 は速くなるのか

Pat Shaughnessy "Why Bundler 1.1 will be much faster" 
 http://patshaughnessy.net/2011/10/14/why-bundler-1-1-will-be-much-faster
使

Twitter(@oshow)

201112 WEB+DB PRESS Vol.66  Bundler 
Bundler1.1  Bundler 

 Bundler 1.1 



 20111015
by Pat Shaughnessy

  Rails 3 bundle install  bundle update 30 "Fetching source index for http://rubygems.org/."  Bundler  RubyGems.org  Bundler   Bundler 1.1  RubyGems  Bundler 

2011111115 Boston.rb Bundler 1.1 

 Budler 1.0 


 Bundler 1.1  Bundler 1.0  "Fetching source index..."  Nick Quaranto 20111Nick Bundler RubyGems.org  gem RubyGems.org  gem Nick 

Bundler  gem  gem  gem  gem 30 CPU 

Bundler 1.1 


  Bundler 調( Bundler 1.1  --pre )

$ gem install bundler --pre
Successfully installed bundler-1.1.rc
1 gem installed
Installing ri documentation for bundler-1.1.rc...
Installing RDoc documentation for bundler-1.1.rc...
$ cd /path/to/my/favorite/rails/app
$ bundle update
Fetching gem metadata from http://rubygems.org/.........
Using rake (0.9.2)
Using multi_json (1.0.3)
Using activesupport (3.1.1)
Using builder (3.0.0)

etc...

Using sass-rails (3.1.4)
Using sqlite3 (1.3.4)
Using uglifier (1.0.3)
Your bundle is updated! Use `bundle show [gemname]` to see where a bundled gem is installed.

2



(一) 4Bundler 1.0 30


(二) "Fetching source index..." "Fetching gem metadata from http://rubygems.org/........."  spec 



 Fetching gem metadate  

RubyGems.org  API


 bundle update  --verbose 

$ bundle update --verbose
Fetching gem metadata from http://rubygems.org/
Query List: ["rails", "sqlite3", "json", "sass-rails", "coffee-rails", "uglifier", "jquery-rails"]
Query Gemcutter Dependency Endpoint API: rails sqlite3 json sass-rails coffee-rails uglifier jquery-rails
Fetching from: http://rubygems.org/api/v1/dependencies?gems=rails,sqlite3,json,sass-rails,coffee-rails,uglifier,jquery-rails
HTTP Success
Query List: ["bundler", "railties", "actionmailer", "activeresource", "activerecord", "actionpack", "activesupport", "rake", "actionwebservice", "ffi", "sprockets", "tilt", "sass", "coffee-script", "multi_json", "execjs", "therubyracer", "thor"]
Query Gemcutter Dependency Endpoint API: bundler railties actionmailer activeresource activerecord actionpack activesupport rake actionwebservice ffi sprockets tilt sass coffee-script multi_json execjs therubyracer thor
Fetching from: http://rubygems.org/api/v1/dependencies?gems=bundler,railties,actionmailer,activeresource,activerecord,actionpack,activesupport,rake,actionwebservice,ffi,sprockets,tilt,sass,coffee-script,multi_json,execjs,therubyracer,thor
HTTP Success

etc...

 Bundler 1.1  gem RubyGems.org  HTTP  API source index  URL  gem JSON  JSON Ruby  Marshal 

RubyGems.org  API HTTParty  Marshal 使 gem 

require 'rubygems'
require 'httparty'

 class RubyGemsApi
  include HTTParty
  base_uri 'rubygems.org'

  def self.info_for(gems)
    res = get('/api/v1/dependencies', :query => { :gems => gems })
    Marshal.load(res)
  end

  def self.display_info_for(gems)
    info_for(gems).each do |info|
      puts "#{info[:name]} version #{info[:number]} dependencies: #{info[:dependencies].inspect}"
    end
  end
end

RubyGemsApi.display_info_for(ARGV[0])

例として私の大好きな gem である "uglifier" に対してこれを走らせてみる。

$ ruby parse_rubygems_api.rb uglifier
uglifier version 1.0.3 dependencies: [["multi_json", ">= 1.0.2"], ["execjs", ">= 0.3.0"]]
uglifier version 1.0.2 dependencies: [["multi_json", ">= 1.0.2"], ["execjs", ">= 0.3.0"]]
uglifier version 1.0.1 dependencies: [["multi_json", ">= 1.0.2"], ["execjs", ">= 0.3.0"]]
uglifier version 1.0.0 dependencies: [["multi_json", ">= 1.0.2"], ["execjs", ">= 0.3.0"]]
uglifier version 0.5.4 dependencies: [["multi_json", ">= 1.0.2"], ["execjs", ">= 0.3.0"]]
uglifier version 0.5.3 dependencies: [["multi_json", ">= 1.0.2"], ["execjs", ">= 0.3.0"]]
uglifier version 0.5.2 dependencies: [["multi_json", ">= 0"], ["execjs", ">= 0.3.0"]]
uglifier version 0.5.1 dependencies: [["json", ">= 0"], ["execjs", ">= 0"]]
uglifier version 0.5.0 dependencies: [["json", ">= 0"], ["execjs", "~> 0.1.0"]]
uglifier version 0.4.0 dependencies: [["therubyracer", "~> 0.8.0"]]
uglifier version 0.3.0 dependencies: [["therubyracer", ">= 0.8.0"]]
uglifier version 0.2.0 dependencies: []
uglifier version 0.1.1 dependencies: []
uglifier version 0.1.0 dependencies: []

レスポンスには最新版だけじゃなく、gem の各バージョン毎の依存関係が含まれているのに気づいて欲しい。これが必要なのは、Bundler の依存解決アルゴリズムが gem の古いバージョンを使う可能性があるからだ(バンドルしている他の gem の内容により、動作が違ってくる)。

gem 名をコンマで区切ったリストを指定することもでき、例えば上の方で --verbose を指定した時のリストを使えばこうだ。

$ ruby parse_rubygems_api.rb rails,sqlite3,json,sass-rails,coffee-rails,uglifier,jquery-rails

 HTTP API 1Bundler 

 gem 
Bundler 1.1 


  Gemfile 使 Gemfile 3 How does Bundler bundle 使

source 'http://rubygems.org'
gem 'uglifier’

 Gemfile  gem 



 Gemfile  bundle update --verbose Bundler  gem 

$ bundle update --verbose
Fetching gem metadata from http://rubygems.org/



Query List: ["uglifier"]
Query Gemcutter Dependency Endpoint API: uglifier
Fetching from: http://rubygems.org/api/v1/dependencies?gems=uglifier
HTTP Success

ここで最初に起こっているのは、Gemfile の中に唯一入っている gem である "uglifier" の依存関係を決定するための HTTP リクエストだ。この HTTP リクエストの結果は、上にある parse_rubygems_api.rb スクリプトの出力でわかる。uglifier のそれぞれ違うバージョンの中に出てくる、4つの gem だ。



最新の uglifier は json、execjs、multi_json に依存していて、ある古いバージョンでは "therubyracer" gem に依存している。

その次に Bundler がする事は、2回目の HTTP リクエストを RubyGems.org へ送り、これら4つの gem の依存関係を要求することだ。



Query List: ["multi_json", "execjs", "json", "therubyracer"]
Query Gemcutter Dependency Endpoint API: multi_json execjs json therubyracer
Fetching from: http://rubygems.org/api/v1/dependencies?gems=multi_json,execjs,json,therubyracer
HTTP Success

興味があるなら、parse_rubygems_api.rb を実行してこのリクエストの結果を見ることも出来る。以下は RubyGems.org が返す結果の図だ。



今度は "execjs" gem がいくつかのバージョンの "multi_json" へ依存している事と、"therubyracer" が "libv8" に依存していることがわかる。そして Bundler は RubyGems.org への3回目の HTTP リクエスト送信へと続き、libv8 の依存関係を得る。このリクエストに multi_json は含まれない。なぜなら、既にその情報は持っているからだ。



Query List: ["libv8"]
Query Gemcutter Dependency Endpoint API: libv8
Fetching from: http://rubygems.org/api/v1/dependencies?gems=libv8
HTTP Success

今度は RubyGems.org が空のセットを返す。libv8 は一つも依存する gem を持たないということだ。



Query List: []
Unmet Dependencies:

これで Bundler は必要な全依存情報を手に入れたので依存解決アルゴリズムの実行へと進み、そして最後に、たった今新しくなったバンドルに含まれている gem を列挙する。

Using multi_json (1.0.3) from /Users/pat/.rvm/gems/ruby-1.8.7-p352/specifications/multi_json-1.0.3.gemspec
Using execjs (1.2.9) from /Users/pat/.rvm/gems/ruby-1.8.7-p352/specifications/execjs-1.2.9.gemspec
Using uglifier (1.0.3) from /Users/pat/.rvm/gems/ruby-1.8.7-p352/specifications/uglifier-1.0.3.gemspec
Using bundler (1.1.rc) from /Users/pat/.rvm/gems/ruby-1.8.7-p352/specifications/bundler-1.1.rc.gemspec


関連記事:【翻訳】速くなったのはいいとして、Bundler 1.1 の他の新機能は?

2011年5月18日水曜日

【翻訳】Gitをボトムアップから理解する

John Wiegley "Git from the bottom up" 
PDF http://newartisans.com/2008/04/git-from-the-bottom-up/

BY-SABY-SA


Twitter(@oshow)


Git 



Wed, 2 Dec 2009
by John Wiegley


  Git 調 Git 調

Git 1.5.4.5 使


(一)
 
(二)
 
(三)
 

blob 
 
blob  tree 
 
tree 
 

 

 
 rebase 
 

(四)
 


 

(五)
 

mixed reset 
 
soft reset 
 
hard reset 
 

(六)stash  reflog
 
(七)
 
(八)
 


1. 


  3.0  BY-SA  URL 

http://creativecommons.org/licenses/by-sa/3.0/us/



 CC 3.0  BY-SA  O-Show 


2. 


 Git 

稿

repository
  (repository) HEAD () 

the index
 使Git  (index)  () 

working tree
  (working tree)  ( .git )

commit
  HEAD () 

branch
  ()

tag
 

master
  master 

HEAD
 HEAD 使

HEAD  () 

HEAD  detached HEAD 


Git 1


repository-workingtree-index


 (*1) Git 

(*1) 使 ()


3. 


 Git 

Git  Unix  ()  i-node  ()  i-node  i-node  ()  i-node 

 Git  Unix 12 blob blob  tree  i-node blob  SHA-1  i-node 2blob  blob  tree  blob  blob 

Git  blob blob  blob  tree  tree  blob  "foo"  2004 8 tree  "bar" 522 Git Git  (immutable) 

blob

  Git  Git  
$ mkdir sample; cd sample
$ echo 'Hello, world!' > greeting 
 "sample" 
Git  Git 使Git ID使 greeting 
$ git hash-object greeting
af5626b4a114abcb82d63db7c8082c3c4756e51b
ID2 () 2 greeting blob IDGit 1 


$ git init
$ git add greeting
$ git commit -m "Added my greeting"
blob 
ID Git ID67

$ git cat-file -t af5626b
blob
$ git cat-file blob af5626b
Hello, world!

  blob  tree 調 (ID)  blob 

blob  Git Git  blob 

blob  tree 

  blob blob blob blob ()

Git blob  tree  tree  blob  (tree)  blob  tree 
$ git ls-tree HEAD
100644 blob af5626b4a114abcb82d63db7c8082c3c4756e51b greeting
  greeting 
Git  tree 1 greeting  blob 

ls-tree  HEAD  blob  tree  HEAD  tree  tree 
$ git rev-parse HEAD
588483b99a46342501d99e3f10630cfc1219ea32 # これはあなたのシステム上では別物になる
$ git cat-file -t HEAD
commit
$ git cat-file commit HEAD
tree 0563f77d884e4f79ce95117e2d686d7d6e282887
author John Wiegley <johnw@newartisans.com> 1209512110 -0400
committer John Wiegley <johnw@newartisans.com> 1209512110 -0400

Added my greeting 
 HEAD 
 tree IDIDtree ID blob 

 tree 
$ git ls-tree 0563f77
100644 blob af5626b4a114abcb82d63db7c8082c3c4756e51b greeting

1 blob 1 tree blob 
$ find .git/objects -type f | sort
.git/objects/05/63f77d884e4f79ce95117e2d686d7d6e282887
.git/objects/58/8483b99a46342501d99e3f10630cfc1219ea32
.git/objects/af/5626b4a114abcb82d63db7c8082c3c4756e51b 
3
ID調
$ git cat-file -t 588483b99a46342501d99e3f10630cfc1219ea32
commit
$ git cat-file -t 0563f77d884e4f79ce95117e2d686d7d6e282887
tree
$ git cat-file -t af5626b4a114abcb82d63db7c8082c3c4756e51b
blob
 git sho
w 使

tree 

  tree 1tree   blob  blob  tree blob  tree  tree 


$ rm -fr greeting .git
$ echo 'Hello, world!' > greeting
$ git init
$ git add greeting
 index 
index  blob 使greeting 
$ git log # これは失敗する。まだコミットは存在しない!
fatal: bad default revision 'HEAD'
$ git ls-files --stage # index によって参照される blob を一覧表示する
100644 af5626b4a114abcb82d63db7c8082c3c4756e51b 0 greeting
 
ID greeting ID cat-file -t 使 blob  blob  (調)

 blob  tree .git/index  ( index  blob  tree )  blob  tree 
$ git write-tree # 一つの tree として index の内容を記録する
0563f77d884e4f79ce95117e2d686d7d6e282887
 blob (tree)
  tree IDblob  tree  write-tree index  tree 

 tree 使commit-tree 
$ echo "Initial commit" | git commit-tree 0563f77
5f1bc85745dcccce6121494fdd37658cb4ad441f
 commit-tree  tree ID
-p 使IDID使

 HEAD 
$ echo 5f1bc85745dcccce6121494fdd37658cb4ad441f > .git/refs/heads/master
 Git "master" 
update-ref 使
$ git update-ref refs/heads/master 5f1bc857
master 

$ git symbolic-ref HEAD refs/heads/master
 master  
HEAD  refs/heads/master 

 git log 使
$ git log
commit 5f1bc85745dcccce6121494fdd37658cb4ad441f
Author: John Wiegley <johnw@newartisans.com>
Date: Mon Apr 14 11:14:58 2008 -0400

Initial commit 

 refs/heads/master unreachable () tree  blob  ( git gc )refs/heads  reachable () 

  "trunk" Git  blobtree (*2) 

(*2) Git 

 branch 使調
$ git branch -v
* master 5f1bc85 Initial commit
 ()  

使ID使
$ git reset --hard 5f1bc85
--hard 
 ()git checkout 
$ git checkout 5f1bc85
 checkout  -f reset --hard checkout reset --hard  HEAD  tree 

使 "branch"  Git  Git  tree  blob  tree blob 




commit-tree-blob


...

  Git  (*3) 

(*3) 

 Git 使


  "branch"  HEAD 使


 

HEAD
  HEAD 使HEAD "using a detached HEAD ( HEAD 使)" ()

(detached HEAD   )

c82a22c39cbc32...
 40 SHA1 ID使便使

c82a22c
 ID使67

name^
 使2使

name^^
 

name^2
  () name^N 使N

name~10
 N (~) 使 rebase -i 使 name^^^^^^^^^^ 

name:path
  git show2
$ git diff HEAD^1:Makefile HEAD^2:Makefile

name^{tree}
  tree 

name1..name2
  git log 
 name2  name1 name1 ()  name1  name2  HEAD 使

name1...name2
 "3"2git log name1  name2  (name ) 

git diff name2name1  name2 git log  name1 

master..
  "master..HEAD" 使

..master
 git fetch  rebase  merge 

--since="2 weeks ago"
 

--until=1 week ago
 

--grep=pattern
 

--committer=pattern
  () 

--author=pattern
 author  author  e-mail author 

--no-merges
 

 ( master ) "foo"
$ git log --grep='foo' --author='johnw' --since="1 month ago" master..

 rebase 

  Git  rebase DZ HEAD 


basic-history


2DZAgit show-branch 
$ git branch
  Z
* D
$ git show-branch
!  [Z] Z
 * [D] D
--
 * [D] D
 * [D^] C
 * [D~2] B
+  [Z] Z
+  [Z^] Y
+  [Z~2] X
+  [Z~3] W
+* [D~3] A



A ( D~3  Z~4 )^ 使~3 3

 () Z4WXYZ

 () 3BCD



ZDBCDZ

使 Git 使Z 
$ git checkout Z # Z ブランチへ切り替え
$ git merge D # B、CDのコミットをZへマージ




merged-history


Z Z ( Z^ ) D(DZ)

ZDZD Z' DZ

ZDZ rebase 使


rebased-history


ZDrebase (*4)
$ git checkout Z # Z ブランチへ切り替える
$ git rebase D # Z のベースコミットをDの地点へ変更する

  rebase WAAWrebase  WD W' WX A+W+X  D+W'+X' Y Z Z' Z

rebase 使 merge 使 pull merge 

(*4) 使使rebase rebase  rebase merge 使(Rebase)

  rebase ZD (D HEAD) WZrebase  -i Z

pick
 使 () rebase 

squash
 squash  squash  ( squash  pick )ZD

edit
 edit rebase  index rebase --continue 

(drop)
 

使











 rebase  man LZ


basic-history2


D3ZCX HEAD LLZJ2008 
$ git checkout L
$ git rebase -i Z



rebased-history2


rebase 


4. 


  Git  blob Git  tree  blob  (git add )  index  tree  index  git reset  index  blob 

index  CVS  Subversion Darcs 


index-is-next-commit


index  git commit  -a  Subversion svn status   svn commit  index  HEAD  foo.c svn add 

 git commit -a 使git add  Subversion 

Subversion Git  index  HEAD 

foo.c Subversion 
$ svn diff foo.c > foo.patch
$ vi foo.patch
<foo.patch を編集し、後でコミットしたい変更を維持する>
$ patch -p1 -R < foo.patch # 二番目の変更セットを取り除く
$ svn commit -m "First commit message"
$ patch -p1 < foo.patch # 残りの変更を再適用する
$ svn commit -m "Second commit message"
 
 Gitindex 使
$ git add --patch foo.c
<最初にコミットしたいハンクを選択する>
$ git commit -m "First commit message"
$ git add foo.c # 残りの変更を add する
$ git commit -m "Second commit message"
  Emacs
 Christian Neukirchan  gitsum.el (*5) 退使11Christian

(*5) http://chneukirchen.org/blog/archive/2008/02/introducing-gitsum.html

 index 

Quiltindex  Quilt (*6) index 

(*6) http://savannah.nongnu.org/projects/quilt

 foo.c 24  Git index 使 ABCDA+B  A+CA+D

Git index 使使

1 index  Stacked Git (*7) 

(*7) http://procode.org/stgit

 Git 使2
$ git add -i # 最初の変更セットを選択する
$ git commit -m "First commit message"
$ git add -i # 二番目の変更セットを選択する
$ git commit -m "Second commit message"

$ git log # 一番目のコミットのハッシュIDを見つける
$ git checkout -b work <最初のコミットのハッシュ ID>^
$ git cherry-pick <2番目のコミットのハッシュ ID>
<...  テストを走らせる ...>
$ git checkout master # master ブランチへ戻る
$ git branch -D work # 一時的なブランチを削除する
 stg 
 stg 使
$ stg new patch1
$ git add -i # 一番目の変更セットを選択
$ stg refresh --index
$ stg new patch2
$ git add -i # 二番目の変更セットを選択
$ stg refresh --index

$ stg applied
patch1
patch2
<...  両方のパッチを使ってテスト ...>
$ stg pop patch1
<...  patch2 だけを使ってテスト ...>
$ stg pop patch2
$ stg push patch1
<...  patch1 だけを使ってテスト ...>
$ stg push -a
$ stg commit -a # 全てのパッチをコミットする
ID 
cherry-pick 


5. 


 Git git reset 使HEAD 

 git reset index 3調 Git 調

mixed reset 

  --mixed 使 ()git reset  HEAD index --soft --soft  HEAD  index 
$ git add foo.c # 新しい blob として index へ変更を追加する
$ git reset HEAD # index にステージされた全ての変更を削除する
$ git add foo.c # 間違えていたので add をやり直し

soft reset 

 git reset  --soft 使 HEAD  ()2
$ git reset --soft HEAD^ # 自身の親へ HEAD を戻す。最後のコミットを事実上無視することになる
$ git update-ref HEAD HEAD^ # 手動ではあるが、同じことをする
 HEAD 
 git status  git commit --amend 使

 HEAD HEAD  pull  soft reset 


new-head-and-old-head


 pull  HEAD  ()


downstream-concumser's-history


hard reset 

 hard reset (--hard )  HEAD  hard reset  HEAD 

git checkout  index git reset --hard  index 

 hard reset  soft reset git reset --hard 使
$ git reset --hard HEAD~3 # 変更を捨てて、過去に遡る

$ git reset --soft HEAD~3 # 以前のコミットをHEADが指すようにする
$ git reset --hard # ワーキングツリー内の差異を消し去る
hard reset 
Git  stash () 使
$ git stash
$ git checkout -b new-branch HEAD~3 # head を遡る!


(一)stash stash  stash 


(二)


 new-branch  master 
$ git branch -D master # さようなら古い master(まだ reflog には、いる)
$ git branch -m new-branch master # 今や new-branch が master になる

 git reset --soft  git reset --hard () 使 Git ()  master 使

 git reset --hard master  git stash 使 ()  reflog ()  git reset --hard 
$ git reset --hard HEAD@{1} # reflog から変更前の状態へ復帰させる

 git stash  git reset --hard 使git stash 使
$ git stash # これをするのが常に良いことなので、とりあえずする
$ git reset --hard HEAD~3 # 以前へ遡る

$ git reset --hard HEAD@{1} # おっと、あれは間違いだった、やり直し!
$ git stash apply # そしてワーキングツリーの変更を呼び戻す


6.  stash  reflog


 Git  blob 2blob  index  tree  tree blob 2

1 Git  reflog  git commit 使 index  tree  reflog reflog 使
$ git reflog
5f1bc85...  HEAD@{0}: commit (initial): Initial commit
reflog 
 (git reset 使) reflog 30

blob  foo.c  index Git  blob blob Git  blob  SHA-1 ID
$ git hash-object foo.c
<some hash id>
 

$ git stash
i
ndex  blob  Git tree  blob  stash  index  stash 

 git stash apply 使 stash  stash  reflog  (WIP Work in progress)
$ git stash list
stash@{0}: WIP on master: 5f1bc85... Initial commit

$ git reflog show stash # 上と同じ出力+stash コミットのハッシュID
2add13e...  stash@{0}: WIP on master: 5f1bc85...  Initial commit

$ git stash apply
stash 
 log  stash  stash 
$ git stash list
stash@{0}: WIP on master: 73ab4c1...  Initial commit
...
stash@{32}: WIP on master: 5f1bc85...  Initial commit

$ git log stash@{32} # これはいつやった?
$ git show stash@{32} # 私がやっていたことを見せろ

$ git checkout -b temp stash@{32} # 古いワーキングツリーを見てみよう!
 index  git stash  (stash ) git stash apply 使使

stash 30git stash clear 使 git reflog expire 使
$ git stash clear # やってはダメ! 全ての履歴を失ってしまう

$ git reflog expire --expire=30.days refs/stash
<維持されていた分の stash 履歴が出力される>

stash 使 stash 
$ cat <<EOF > /usr/local/bin/git-snapshot
#!/bin/sh
git stash && git stash apply
EOF
$ chmod +x $_
$ git snapshot
git reflog expire 
cron 使


7. 


 使Git 

Git Git Git 使Git 

THE END


8. 


Git 

 A tour of Git: the basics
http://cworth.org/hgbook-git/tour/

 Manage source code using Git
http://www.ibm.com/developerworks/linux/library/l-git/

 A tutorial introduction to git
http://www.kernel.org/pub/software/scm/git/docs/tutorial.html

 GitFaq  GitWiki
http://git.or.cz/gitwiki/GitFaq

 A git core tutorial for developers
http://www.kernel.org/pub/software/scm/git/docs/gitcore-tutorial.html

 git for the confused
http://www.gelato.unsw.edu.au/archives/git/0512/13748.html

 The Thing About Git
http://tomayko.com/writings/the-thing-about-git



Gitに関する翻訳記事はこちらもどうぞ:

A successful Git branching model を翻訳しました
【翻訳】あなたの知らないGit Tips


2011年1月18日火曜日

【翻訳】Gitのコミットメッセージに関する注意点

Tim Popeさんの "A Note About Git Commit Messages" を翻訳しました。
元記事はこちら: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
(翻訳の公開は本人より許諾済みです)

翻訳の間違い等があればブログコメントやTwitter(@oshow)などで遠慮無くご指摘ください。

Git


 Git rails.git 

Git
Short (50 chars or less) summary of changes

More detailed explanatory text, if necessary.  Wrap it to about 72
characters or so.  In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body.  The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.

Write your commit message in the present tense: "Fix bug" and not『Fixed
bug.』 This convention matches up with commit messages generated by
commands like git merge and git revert.

Further paragraphs come after blank lines.

- Bullet points are okay, too

- Typically a hyphen or asterisk is used for the bullet, preceded by a
  single space, with blank lines in between, but conventions vary here

- Use a hanging indent
変更に対する短い(50文字以下の)要約

もし必要なら、より詳しい説明を述べる。約72文字ほどで折り返すようにせよ。
ある文脈では、最初の行はE-Mailの件名になり、残りのテキストが本文になる。
空行で本文と要約を分離するのは絶対に必要だ(本文を省略していない限り)。
もしも二つを繋げてしまうと、rebaseのようなツールが混乱する可能性がある。

現在時制でコミットメッセージを書くこと。"Fixed bug"ではなく"Fix bug"だ。
この慣習は git merge や git revert のようなコマンドが生成したコミット
メッセージと調和する。

さらなる段落があれば空行の後に続けられる。

- 箇条書きも問題ない

- 箇条書きにはハイフンかアスタリスクが使われ、一つスペースを空けてから
  書き始め、合間には空行が入るのが通常だが、この部分の慣習は多種多様だ

- ぶら下げインデント(一行目だけ飛び出して後はインデントする)を使うこと

 72

git log  less -S 804472

  
$ git config --global core.pager 'less -R'
 
$ git config --global core.pager 'LESS=-R less'


(20141023)Git 2.1.0 


git format-patch --stdout e-mail使e-mail80e-mail rails.git e-mail

Vim  vim-git Git
:set textwidth=72
Textmate view  "Wrap Co
lumn" 調^Q 使()72
$ defaults write com.macromates.textmate OakWrapColumns '( 40, 72, 78 )'

 50 Git 使

git log --pretty=oneline ID

git rebase --interactive 

merge.summary 

git shortlog  ChangeLog 使

git format-patchgit send-email e-mail

git reflog  reflog 鹿使

gitk 

GitHub 

 Git  Subversion 


2011年1月6日木曜日

【翻訳】アクターによる並列性、そしてRubyでGoroutine

Ilya Grigorikさんの "Concurrency with Actors, Goroutines & Ruby" を翻訳しました。
元記事はこちら: http://www.igvita.com/2010/12/02/concurrency-with-actors-goroutines-ruby/
(翻訳の公開と画像の利用は本人より許諾済みです)

翻訳の間違い等があればブログコメントやTwitter(@oshow)などで遠慮無くご指摘ください。



RubyGoroutine


ruby-go  fork / waitBruce Tate Seven Languages in Seven Weeks Matz  Ruby  


 Matz   

(Process calculi) CCSCSPACP1970

CSPπ


erlang-scala-go  Erlang  Scala 
Google Go CSP π


 
 



GoroutineChannnel  Ruby


 Erlang Go VMErlang  使mailbox Go "communication channel" Unix


erlang-vs-go


GoGo runtime  Ruby gem install agent
c = Agent::Channel.new(name: 'incr', type: Integer)go(c) do |c, i=0|
  loop { c << i+= 1 }
end
 
p c.receive # =>1
p c.receive # =>2

githubAgent (Go-like concurrency, in Ruby)
Downloads: 275 File Size: 0.0 KB


'incr' channel  "go" channel  Ruby 

"go"  loop  channel  receive  channel producer  receive   producer-consumer  mutex   MRI  JRuby 

"" 


 使 Agent "" 使

 CSP/πErlang Go Ruby  Agent 



2011年1月2日日曜日

【翻訳】Rebaseは安全である

Gary Bernhardtさんの "Rebase Is Safe" を翻訳しました。
元記事はこちら: http://blog.extracheese.org/2010/12/rebase-is-safe.html
(翻訳の公開は本人より許諾済みです)

翻訳の間違い等があればブログコメントやTwitter(@oshow)などで遠慮無くご指摘ください。


Rebase


  Git  git rebase push  rebase 

 git rebase  git bisect  bisect  bisect false positive 

 rebase 


(set -e;
  git rev-list --reverse origin/master..master |
    while read rev; do
      echo "Checking out: $(git log --oneline -1 $rev)";
      git checkout -q $rev;
      python runtests.py;
    done)
 while 
origin/master  master Expector Gadget2
Checking out: 4f56581 Split tests into many files
....................
-------------------------------------------------
Ran 20 tests in 0.019s

OK
Checking out: 44de2c2 pyflakes
....................
-------------------------------------------------
Ran 20 tests in 0.019s

OK
1.1
Git  bisect rebase 

 set -e  git checkout master rebase 

 set -e  git checkout 
Checking out: 4f56581 Split tests into many files
error: You have local changes [...]; cannot switch branches.
6
 Mercurial  patch queue patch queue   rebase  Mercurial Mercurial  Git 

 zsh 100,000"rev-list"  ^R  dotfiles 使

 Git  Unix 使 Unix  "Python to Shell to Ruby"  "A Raw View into My Unix Hackery" Unix"The Tar Pipe" 使

"Why I Switched to Git From Mercurial" 





フォロワー