hitode909の日記

以前はプログラミング日記でしたが、今は子育て日記です

Emacsで快適にgit blameしたい(できてない)

エディタで編集しているファイルをgit blameしてコードの意図を理解しようとすることがよくあるのだけど,毎回ターミナルを開いてgit blameとかするのがめんどくさくて,なんとかしたい.
Emacsでカーソルのある行をgit blameできたら便利そうな気がしたので,やってみた.


これをgit-blame-onelineという名前で保存して,

#!/usr/bin/env ruby

(file, line) = *ARGV

Dir.chdir(File.dirname(file))

blame = `git blame -p -L #{line},+1 #{file} 2> /dev/null`

exit if $?.to_i != 0

data = {}

blame.each_line{|line|
  match = line.match(/^([^ ]+) (.*)$/)
  next unless match
  data[match[1]] = match[2]
}

print [Time.at(data['author-time'].to_i), data['author'], data['summary']].join(' ')


この関数を実行すると,カーソルがある行をgit blameできる.

(defun git-blame-current-line ()
  (interactive)
  (let ((old-buf (current-buffer))
    (blame-buf (get-buffer-create "*blame*"))
    (line-num (number-to-string (line-number-at-pos))))
    (set-buffer blame-buf)
    (erase-buffer)
    (call-process "git-blame-oneline" nil "*blame*" t (buffer-file-name old-buf) line-num)
    (setq content (buffer-string))
    (set-buffer old-buf)
    (when (not (eq (length content) 0))
      (popup-tip content)
      ; (message content)
      )
    ))


run-with-idle-timerで実行するとカーソルのある行が常時git blameされてポップアップされる.

(run-with-idle-timer 1.0 t 'git-blame-current-line)


こんな感じ.いつ誰がなんというコミットをしたかポップアップで出る.
http://gyazo.com/8d2d4921a86f410531716ab49970d4d6.png


やってみて分かったけど,1行だけ出てもよく分からなくて,周りのコミットログも見れないとだめな感じだった.上下も出すとかやればよさそうだけど,ずっとポップアップで出ると邪魔な気がする.


バッファ全体をgit blameするのも書いてみた.

(defun git-blame-current-buffer ()
  (interactive)
  (shell-command (concat "git blame " (buffer-file-name (current-buffer))))
  )

これはgit blameするだけなので,コミットメッセージを読めない.
http://gyazo.com/0ac32742134558c9c5378ed2a287abe5.png


カーソル位置のSHA1をgit showするのも作ってみた.blameしたバッファで,見たい行のSHA1の上で実行するとgit showが実行される.

(defun git-show-at-point ()
  (interactive)
  (shell-command (concat "git show " (thing-at-point 'symbol)))
  )


これはこれでいいけど,そんなに便利じゃない.ファイル全体をgit blameするのが重いし,コミットログを見るのにもう一手間あるのもめんどくさい.
vc-annotateがいい感じに使えればよさそうなので,そういうことも試してみたいと思っているけど,Emacsから快適にgit blameする情報をご存知の方は教えてください.


一応Githubにも上げてあるけど,使いたいひと居なさそう.