エディタで編集しているファイルを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)
こんな感じ.いつ誰がなんというコミットをしたかポップアップで出る.
やってみて分かったけど,1行だけ出てもよく分からなくて,周りのコミットログも見れないとだめな感じだった.上下も出すとかやればよさそうだけど,ずっとポップアップで出ると邪魔な気がする.
バッファ全体をgit blameするのも書いてみた.
(defun git-blame-current-buffer () (interactive) (shell-command (concat "git blame " (buffer-file-name (current-buffer)))) )
これはgit blameするだけなので,コミットメッセージを読めない.
カーソル位置の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にも上げてあるけど,使いたいひと居なさそう.