Emacs: Run git-blame on the current line
Published on 2014-05-09
Here's a handy function I wrote that you can add to your .emacs file. This function runs
git blame on the line the cursor is on. It prints the short commit id, author, and commit date into the minibuffer. It also copies the short commit id to the kill ring so you can paste it somewhere else if you need to.
Emacs's various git integration modes probably provide something more elaborate, but this works very well for me.
(defun git-blame-line () "Runs `git blame` on the current line and adds the commit id to the kill ring" (interactive) (let* ((line-number (save-excursion (goto-char (point-at-bol)) (+ 1 (count-lines 1 (point))))) (line-arg (format "%d,%d" line-number line-number)) (commit-buf (generate-new-buffer "*git-blame-line-commit*"))) (call-process "git" nil commit-buf nil "blame" (buffer-file-name) "-L" line-arg) (let* ((commit-id (with-current-buffer commit-buf (buffer-substring 1 9))) (log-buf (generate-new-buffer "*git-blame-line-log*"))) (kill-new commit-id) (call-process "git" nil log-buf nil "log" "-1" "--pretty=%h %an %s" commit-id) (with-current-buffer log-buf (message "Line %d: %s" line-number (buffer-string))) (kill-buffer log-buf)) (kill-buffer commit-buf)))
In case you don't read elisp, here's a translation of what's happening.
let line-number be the current line let commit-buf be a new buffer call `git blame file-name -L line-number,line-number` and write the result into commit-buf let commit-id be the short commit id parsed from commit-buf let log-buf be a new buffer add commit-id to the kill ring call `git log -1 commit-id --pretty='%h %an %s'` and write the result into log-buf write the line number and the contents of log-buf to the minibuffer kill log-buf and commit-buf