ボクノ Git チートシート

Git を使用していて「どうするんだっけ?」と思ったことをどんどん追記していく

リポジトリの状態に戻す (変更をなかったことにする)

% git checkout <filename>

ディレクトリを指定すると、まとめて戻せる

% git checkout .

ローカルで作ったブランチをリモートに push する

% git push --set-upstream origin <branchname>

削除されたリモートブランチをローカルに反映させる

% git fetch --prune

ローカルブランチは削除されないので、不要であればローカルブランチを削除する

ブランチの削除

% git branch --delete <branchname>

RSpec の基本的な使い方

最近、RSpec を学習していたので調べたことまとめ

まずは

おそらくここが正式なドキュメントサイト
(参考) RSpec: Behaviour Driven Development for Ruby

RSpec の初期設定


% bundle exec rspec --init
  create   spec/spec_helper.rb
  create   .rspec

テストプログラムは作成された spec ディレクトリに配置するのが基本

テストプログラム


テストプログラムのファイル名はテスト対象のファイル名に "_spec" をつけるのが慣例ぽい (例: hello.rb => hello_spec.rb)
テストプログラムは単に spec と表現されるのをよく見る
以下、簡単な spec の例

require 'hello'

describe 'Hello#message' do
  it 'returns hello message' do
    expect(Hello.new.message).to eq 'Hello World!'
  end
end

describe/context/example/it を利用してテストケースをグループ分けしていく
(参考) RSpecの(describe/context/example/it)の使い分け

テスト対象のロードについて

テスト対象の require をどこに記述すればよいのかしばらく悩んでいた

結論

各 spec ファイルに require 'spec_helper' は記述しない
各 spec ファイルの先頭でテスト対象モジュールを require する
モジュールのパスに変更があったときは -I オプションを指定して $LOAD_PATH を変更することで対応する

経緯

spec_helper.rb に記述して一括管理するのがよい?
こうすると、モジュールのディレクトリ変更でパスが変わり、全 spec ファイルを修正することになるリスクを減らせるかもしれない
しかし、この方法だと部分的なテストを行うときに全モジュールをロードするのが負担にならないか?

ちなみに RSpec はデフォルトで lib と spec を $LOAD_PATH に追加する
なので lib 配下のファイルはパスなしでよい (例: lib/hello.rb => require 'hello')
(参考) RSpecコードリーディング(第1部:RSpec)

各 spec に require 'spec_helper' を記述しない方がいいという意見も見かけた
その場合は、.spec ファイルに以下のデフォルトオプションを追加する

--require spec_helper

試してみようとしたら rspec --init で作成されたデフォルトの .spec にすでに記述されていた

http://rspec.info の Let's get started! を見ると、spec で require 'spec_helper' しないし、かわりにテスト対象モジュールを require してるから、それが想定している基本的な使い方なのだろう

いろいろあさっていたら、3.5 で config.when_first_matching_example_defined が追加されたから、一部の spec でしか使用しないセットアップロジックはこれ使うといいよ、という旨の記事をドキュメントサイトのブログで見つけた
(参考) RSpec 3.5 がリリースされました!

まだ勉強段階なので必要ないけど、今後必要になるかもしれない
頭の片隅に置いておこう

Bundler の基本的な使い方

Bundler のインストール

% rbenv exec gem install bundler
% rbenv rehash
% bunder -v

rbenv rehash はコマンドプログラムの更新
rbenv のヘルプには次のようにある

Rehash rbenv shims (run this after installing executables)

Bundler で gem をインストールする

Gemfile を作って編集し bundle install

% bundle init
% vi Gemfile
% rbenv exec bundler install

すると Gemfile.lock ファイルが作成される


注意!ここから先は未確認・未検証!

別環境で gem をインストールする

% rbenv exec bundler install

Gemfile.lock が存在し Gemfile が更新されていなければ Gemfile.lock に従う (Gemfile.lock は更新されない)
Gemfile.lock が存在し Gemfile が更新されている場合、更新された gem に対して依存性の再解決を行う

以下、bundler install のヘルプより引用

Install the gems specified in your Gemfile(5). If this is the first time you run bundle install (and a Gemfile.lock does not exist), Bundler will fetch all remote sources, resolve dependencies and install all needed gems.

If a Gemfile.lock does exist, and you have not updated your Gemfile(5), Bundler will fetch all remote sources, but use the dependencies specified in the Gemfile.lock instead of resolving dependencies.

If a Gemfile.lock does exist, and you have updated your Gemfile(5), Bundler will use the dependencies in the Gemfile.lock for all gems that you did not update, but will re-resolve the dependencies of gems that you did update. You can find more information about this update process below under CONSERVATIVE UPDATING.

インストールされている Gem を更新する (version up)

% rbenv exec bundler update

このとき Gem のバージョンが変わると Gemfile.lock が更新される

Git コマンドラインの認証で macOS のキーチェーンを利用する

credential-osxkeychain サブコマンドが使えるか確認する

% git credential-osxkeychain

usage: git credential-osxkeychain <get|store|erase>

 

credential-osxkeychain を有効にする

% git config --global credential.helper osxkeychain

これだけ、おわり

 

認証情報を削除したい場合は、キーチェーンアクセスから認証情報を検索し削除すればOK

rbenv で Ruby環境構築

昨年(2017-04-25)の記録が残っていたのでまとめておく

 

前提

  • ログインシェルは zsh
  • Xcodeコマンドラインツールがインストールされてること
  • Homebrew がインストールされてること

 

はじめる前に

Rubyバージョンを確認しておく

$ ruby -v

(記録時では 2.0.0)

 

(念のため) Homebrew に rbenv と ruby-build があるか確認しておく

$ brew search rbenv

$ brew search ruby-build 

 

rbenv + ruby-build のインストール

$ brew install rbenv ruby-build 

rbenv をインストールしたら rbenv init してみる

% rbenv init

# Load rbenv automatically by appending

# the following to ~/.zshrc:

 

eval "$(rbenv init -)" 

指示されているとおり ~/.zshrc に eval "$(rbenv init -)" を追記する

 

バージョンを指定して Ruby をインストールする

インストールできる Ruby バージョンは次のように確認できる

% rbenv install -l

...

  2.3.0

  2.3.1

  2.3.2

  2.3.3

  2.3.4

  2.4.0-dev

  2.4.0-preview1

  2.4.0-preview2

  2.4.0-preview3

  2.4.0-rc1

  2.4.0

  2.4.1

  2.5.0-dev

...

この中からインストールするバージョンを選ぶ

(当時は 2.3.3 を選択)

 

選んだバージョンを指定して rbenv で Ruby をインストール

% rbenv install 2.3.3

 

インストールされている Rubyバージョンは次のように確認できる

% rbenv versions

* system (set by /Users/username/.rbenv/version)

  2.3.3

「*」がついているものが現在有効になっているバージョン

 

特定のディレクトリにのみ Rubyバージョン変更を適用する

ワーキングディレクトリ(今回は ~/working)に移動して Rubyバージョンを確認

% cd ~/working

% ruby -v

ruby 2.0.0p648 (2015-12-16 revision 53162) [universal.x86_64-darwin16]

% rbenv version

system (set by /Users/username/.rbenv/version)

% rbenv which ruby

/usr/bin/ruby

 

Rubyバージョンを変更する

% rbenv local 2.3.3

% ruby -v

ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin16]

% rbenv version

2.3.3 (set by /Users/username/working/.ruby-version)

% rbenv which ruby

/Users/username/.rbenv/versions/2.3.3/bin/ruby

% ls -a

.             ..            .ruby-version 

ruby コマンドが切り替わっているのがわる

rbenv local で Ruby バージョンを切り替えた場合、そのディレクトリ配下では指定したバージョンが有効になる

 

(おまけ) そのとき gem は?

上の手順で ruby は変更されているが gem はどうなっているのか?

 

まずはホームディレクトリで gem を調べてみる

% gem -v

2.0.14.1

% rbenv which gem

/usr/bin/gem

% gem environment

RubyGems Environment:

  - RUBYGEMS VERSION: 2.0.14.1

  - RUBY VERSION: 2.0.0 (2015-12-16 patchlevel 648) [universal.x86_64-darwin16]

  - INSTALLATION DIRECTORY: /Library/Ruby/Gems/2.0.0

  - RUBY EXECUTABLE: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby

  - EXECUTABLE DIRECTORY: /usr/local/bin

  - RUBYGEMS PLATFORMS:

    - ruby

    - universal-darwin-16

  - GEM PATHS:

     - /Library/Ruby/Gems/2.0.0

     - /Users/username/.gem/ruby/2.0.0

     - /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/gems/2.0.0

  - GEM CONFIGURATION:

     - :update_sources => true

     - :verbose => true

     - :backtrace => false

     - :bulk_threshold => 1000

  - REMOTE SOURCES:

     - https://rubygems.org/

 

次に Ruby 2.3.3 を適用したワーキングディレクトリで

% gem -v

2.5.2

% rbenv which gem

/Users/username/.rbenv/versions/2.3.3/bin/gem

% gem environment

RubyGems Environment:

  - RUBYGEMS VERSION: 2.5.2

  - RUBY VERSION: 2.3.3 (2016-11-21 patchlevel 222) [x86_64-darwin16]

  - INSTALLATION DIRECTORY: /Users/username/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0

  - USER INSTALLATION DIRECTORY: /Users/username/.gem/ruby/2.3.0

  - RUBY EXECUTABLE: /Users/username/.rbenv/versions/2.3.3/bin/ruby

  - EXECUTABLE DIRECTORY: /Users/username/.rbenv/versions/2.3.3/bin

  - SPEC CACHE DIRECTORY: /Users/username/.gem/specs

  - SYSTEM CONFIGURATION DIRECTORY: /Users/username/.rbenv/versions/2.3.3/etc

  - RUBYGEMS PLATFORMS:

    - ruby

    - x86_64-darwin-16

  - GEM PATHS:

     - /Users/username/.rbenv/versions/2.3.3/lib/ruby/gems/2.3.0

     - /Users/username/.gem/ruby/2.3.0

  - GEM CONFIGURATION:

     - :update_sources => true

     - :verbose => true

     - :backtrace => false

     - :bulk_threshold => 1000

  - REMOTE SOURCES:

     - https://rubygems.org/

  - SHELL PATH:

     - /Users/username/.rbenv/versions/2.3.3/bin

     - /usr/local/Cellar/rbenv/1.1.0/libexec

     - /Users/username/.rbenv/shims

     - /usr/local/bin

     - /usr/bin

     - /bin

     - /usr/sbin

     - /sbin

     - /Users/username/bin

gem もちゃんと切り替わっているのがわかる

gem パッケージのインストール先も ~/.rbenv/versions/... になっている

 

いろいろ調べてみると、rbenv を利用している際の gem インストールは rbenv exec gem install を、bundler は rbenv exec bundle を使用するのがよさそう

上の調査結果を見る限り gem install は rbenv exec を使用していなくてもよさそうだが、システムに同名のコマンドが混在しているとどっちが適用されるか不安があるから rbenv exec を利用するのが安全か?

Homebrew のインストール

オフィシャルサイトhttps://brew.sh/index_ja のトップに記載されてるコマンドをたたくだけ

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)

 インストール後のチェック

brew doctor 

Homebrew とパッケージリストの更新

brew update

 

Git 用語まとめ

なんとなくわかったこと。(勘違いや間違いを含む可能性アリ)

図も描いてみたかったけど時間かかるしやめた。 

repository

リポジトリ。履歴情報。コミットオブジェクト、ブランチやタグの情報など。または、ワーキングツリーを含む Git 管理下のディレクトリを指す。

 

bare repository

ベアリポジトリ。ワーキングツリーをもたない。git init で指定されたディレクトリ直下に履歴情報が配置される。bare は「裸の」という意味。

 

non-bare repository

ワーキングツリーをもつリポジトリgit init で指定されたディレクトリがワーキングツリーとなる。同時に .git ディレクトリが作成され、履歴情報、インデックスなどの Git 管理ファイルが配置される。

 

working tree

ワーキングツリー。ワーキングディレクトリ。ユーザーの作業領域。

 

index

インデックス。ステージングエリアとも呼ばれる。コミット対象のファイルを管理する。

 

staging

ステージング。コミット対象のファイルをインデックスに登録すること。Git コマンドは "add"

 

commit

コミット。インデックスに登録された情報をもとにワーキングツリーのスナップショットを作成し、リポジトリに登録する。

 

commit object

コミットオブジェクト。コミット時点でのワーキングツリーのスナップショットの先頭データ。曖昧だがスナップショット全体を示すこともある。

スナップショットのデータ構造は commit -> tree (ディレクトリ構造) -> tree or blob (ファイルデータ) となっている。コミットオブジェクトは、ツリーオブジェクト、親コミットオブジェクト、作者、作成日時、コミッター、コミット日時、コミットコメントの情報をもつ。

 

author

最初にコミットした人。通常はファイルを修正した人。通常の commit --amend rebase では変わらない。

 

committer

最後にコミットした人。commit --amend rebase をしたら変わる。

 

branch

ブランチ。直訳すると「枝」。履歴ツリーの枝をイメージした言葉だと思うが、実態は履歴上にある最新のコミットを示すタグのようなものだと考えるとしっくりくる。履歴が枝分かれする(複数のコミットオブジェクトが同じ親を示す)と複数のブランチが存在することになる。

 

remote-tracking branch

リモート追跡ブランチ。リモートブランチの追跡ブランチ。ローカルに存在するリモートブランチのコピー。fetch するとリモートブランチの最新情報を取得し、リモート追跡ブランチが更新される。

 

remote repository

リモートリポジトリ。push & fetch の対象となる別のリポジトリ。だいたいは共有リポジトリgit remote -v で確認できる。通常は origin clone もとのリポジトリが設定される。

 

local repository

ローカルリポジトリ。現在、作業しているリポジトリ

 

merge

マージ。現在のブランチに、別のブランチとの差分を取り込む。

fast-forward ではない場合、または --no-ff オプションが指定された場合は、別のブランチとの差分を取り込みマージコミットを作成する。

 

fast-forward merge

ファストフォワードマージ。現在のブランチが指定されたブランチの履歴の途中にあり、まだ枝分かれしていない場合、現在のブランチを指定されたブランチと同じコミットに移動させる。マージコミットは作成されない。

 

rebase

リベース。親(枝分かれするコミットオブジェクト)の付け替え。指定されたブランチの最新情報を取り込み、カレントブランチの履歴上にある、(枝分かれしてから最新のものまで)すべてのコミットを作り直す。