Friday, March 30, 2007

Emacs hack: ediff latest versions from CVS

Everyone on my team knows one thing - I sure do love my code reviews. The first thing I do to get the code review started is diff the changes the developer made in CVS with what was previously there.

For years, I've simply read the context diff to see what's changed. But recently (perhaps out of Eclipse envy?) I've considered using ediff, an interactive tool for diffing in emacs. Here's a sample screenshot of what ediff looks like:

The annoying thing about ediff was that I needed to type in the version numbers to diff. That totally slowed me down and made using ediff more of a pain.

Then it hit me - this is emacs. If I don't like something, I can write a bit of code to fix it. And so that's what I've done. The code below ends creating an interactive function named ediff-previous-and-current-version. In my .emacs file I've bound this command to Control-x v e. So now I simply open up a file, type key combination, and poof, I have an interactive diff of what's just changed.

Code reviewing was never so much fun.

(defun vc-buffer-current-version ()
  "Get the current CVS version of the current buffer."
  (vc-workfile-version (buffer-file-name)))

(defun vc-buffer-previous-version ()
  "Get the previous CVS version of the current buffer's file."
  (vc-default-previous-version
   (vc-backend (buffer-file-name))
   (buffer-file-name)
   (vc-buffer-current-version)))

(defun ediff-previous-and-current-version ()
  "Ediff the previous and current version of this file."
  (interactive)
  (ediff-vc-internal (vc-buffer-current-version) (vc-buffer-previous-version)))

(defun my-ediff-quit-hook ()
  "My own cleanup function, to make sure ediff is all pretty when done."
  (kill-buffer ediff-buffer-A)
  (kill-buffer ediff-buffer-B))
(add-hook 'ediff-quit-hook 'my-ediff-quit-hook)
Apologies to elisp hackers if I've butchered this code - please feel free to review it and make suggestions. I'd love to incorporate them.