コミット履歴が無駄に多く,黒歴史のある Git リポジトリで開発をする場合,初回の git clone
が非常に遅いという問題がある.コミット数に依存せずに素早く落とせる方法を探していて,最近(今さら...!) git clone
の --depth
オプションのことを知った.用途によっては非常に便利なので,まとめておこうと思う.
前提
現時点で公開されている最新バージョンの Git 2.12.1 を前提にしている.Git は今もまだ機能が増えているため,定期的にバージョンアップしておくと良いと思う.Mac なら brew upgrade git
でサクッと最新バージョンになる.
$ git --version git version 2.12.1
git clone --depth
とは
git clone
で --depth
オプションを使うと,指定したコミット数で刈り取ることができる.以下の例では --depth 1
で,master ブランチにある最新のコミットだけを落としている.コミット履歴が大量にある Git リポジトリでも,素早く落とすことができるため便利.
ちなみに Git のドキュメントを読むと,--depth
オプションを使った git clone
のことを「シャロークローン (shallow clone)」と呼んでいた.合わせて覚えておくと良さそう.
$ git clone --depth 1 git@github.com:kakakakakku/togoo.git $ cd togoo $ git log --oneline | cat 80ff421 Added listing column "created_at"
shallow clone をしても pull / push に制約は無かった
shallow clone をすると pull / push ができないと書いてある記事が多かったが,少なくとも Git 2.12.1 では,普通に pull / push / fetch をすることができた.ようするに --depth 1
で git clone
して,開発をして,プルリクエストを作ることができる.
よって,最初はある程度の深さ(100 など)で shallow clone をして開発を始めて,コミット履歴が必要になったり,git blame
警察をするときになってから,過去のコミットを取得し直せば良いということになる.
追加で過去のコミットを取得する
では,過去のコミットを取得したくなったときにどうすれば良いかと言うと,git fetch
で --depth
オプションを使って深さを指定するか,--unshallow
オプションで全てを取得することになる.
# 深さを指定して取得する場合 $ git fetch --depth 5 # 全てを取得する場合 $ git fetch --unshallow
git diff --indent-heuristic
とは
せっかく Git の話を書いているので,案外知られていないように思う「便利な git diff
オプション」の話も書いておこうと思う.
git diff
で,差分結果が微妙にズレていて気持ち悪いなと感じた人は多いのでは?例えば,以下のようなサンプルコードで再現することができる.追加したのは最初の3行なのに...!という感じでツライ.
$ git diff --- a/hoge.rb +++ b/hoge.rb @@ -1,3 +1,7 @@ [1, 2, 3].each {|i| + puts i +} + +[1, 2, 3].each {|i| puts i + 1 }
この問題を解決するために Git 2.9 で git diff --compaction-heuristic
というオプションが追加されている.ただし,このオプションは不完全で,Git のデフォルト設定としては採用されなかった.そして Git 2.11 で,さらに改善された git diff --indent-heuristic
というオプションが追加された.--indent-heuristic
は全てのケースで改善がされているらしく,今後のバージョンで Git のデフォルト設定になる予定があると公式ブログにも書いてあった.
The new option goes under the name --indent-heuristic (and diff.indentHeuristic), and will likely become the default in a future version of Git.
--indent-heuristic
オプションを使うと,以下のように意図した差分結果になる.最高!
$ git diff --indent-heuristic --- a/hoge.rb +++ b/hoge.rb @@ -1,3 +1,7 @@ +[1, 2, 3].each {|i| + puts i +} + [1, 2, 3].each {|i| puts i + 1 }
--indent-heuristic
オプションをデフォルトにする
~/.gitconfig
に以下の設定をすれば,git diff
のデフォルト設定が --indent-heuristic
になる.個人的には必須な設定!
[diff] indentHeuristic = true
まとめ
- Git は定期的にバージョンアップする
- 巨大な Git リポジトリをサクッと落とす場合は
git clone --depth
を使う - 最新バージョンの Git なら shallow clone をしても pull / push ができる
~/.gitconfig
でdiff.indentHeuristic
を有効化すればgit diff
が便利になる