hitode909の日記

趣味はマリンスポーツですの日記です

Gitのリポジトリの状態をGrowlで通知する

以前から,Gitのリポジトリの状態などをzshのプロンプトに表示していたのだけど,precmdのフックでgit logとかgit statusが何度も呼ばれていて,大変遅かった.
プロンプトが出るまで何も操作できなくて,困っていたので,dRubyで,非同期にリポジトリの状態を調べて,Growlで通知するようにした.


何かコマンドを実行するたびに,リポジトリの情報がGrowlで出てくるので,常に,自分が何をしているのか気にすることができる.


これを予めどこかで起動しておいて,

#! /opt/local/bin/ruby
require 'rubygems'
require 'drb/drb'
require 'git'
require 'g'

class Service
  def git_status(path)
    Thread.new {
      path = File.expand_path path
      git = Git.open(path) rescue return

      g git.current_branch
      changed = git.status.changed.length
      g "#{changed} changes" if changed > 0
      local = git.log(1).between('origin', 'HEAD').count
      g "#{local} local commits" if local > 0
    }
  end
end

uri = ARGV.shift || 'druby://localhost:12345'
DRb.start_service(uri, Service.new)
puts DRb.uri
sleep


このスクリプトを,パスの通ったところに置いて,

#! /opt/local/bin/ruby
require 'rubygems'
require 'drb/drb'

there = DRbObject.new_with_uri('druby://localhost:12345')
there.git_status(Dir.pwd)


.zshrcで,precmdのフックで実行するようにする.

precmd () {
    git_status
}


GitHubに置いた.
http://gist.github.com/310741


体感速度が上がったので,Gitに限らず,重い処理をprecmdでやりたいときは,dRubyに処理させるとよい感じになりそう.

追記

どうも動きがおかしい気がする.branchがずっとmasterになってる.

追記2

直した.

git.branch

すると,今チェックアウトされてるブランチをもらえると思っていたら,そうではなくて,このメソッドは,

git.branch("piyo")

とかして,指定した名前のブランチを取得するメソッドだった.名前を省略するとmasterになる.


現在チェックアウトしているブランチを取得するには,

git.current_branch

する.そうすると,現在チェックアウトしている(ブランチのオブジェクトではなくて,)ブランチの名前を取得できる.想像を絶する感じだけど,そういう仕様だった.