Auto-starting Emacs smerge-mode for Git

I love that Emacs notices merge conflicts in Bazaar versioned files, highlighting the differences in green and pink. It's a small thing, but I really miss this automation for when working with Git — I have to manually type M-x smerge-mode.

Emacs smerge-mode highlighting a conflict

The feature works by looking for conflict files and markers whenever you open a Bazaar versioned file:

;;; Copied from Emacs 24.3.1: vc/vc-bzr.el.gz:472
(defun vc-bzr-find-file-hook ()
  (when (and buffer-file-name
             ;; FIXME: We should check that "bzr status" says "conflict".
             (file-exists-p (concat buffer-file-name ".BASE"))
             (file-exists-p (concat buffer-file-name ".OTHER"))
             (file-exists-p (concat buffer-file-name ".THIS"))
             ;; If "bzr status" says there's a conflict but there are no
             ;; conflict markers, it's not clear what we should do.
               (goto-char (point-min))
               (re-search-forward "^<<<<<<< " nil t)))
    ;; TODO: the merge algorithm used in `bzr merge' is nicely configurable,
    ;; but the one in `bzr pull' isn't, so it would be good to provide an
    ;; elisp function to remerge from the .BASE/OTHER/THIS files.
    (add-hook 'after-save-hook 'vc-bzr-resolve-when-done nil t)
    (message "There are unresolved conflicts in this file")))

The above looks a little complicated, but the important part is the line (smerge-start-session). This starts smerge-mode to highlight merge conflicts.

Let's do something similar with Git by defining a function vc-git-find-file-hook:

(defun vc-git-find-file-hook ()
  (when (save-excursion
      (goto-char (point-min))
      (re-search-forward "^<<<<<<< " nil t))

Emacs vc-mode has a standard interface for version control systems, so simply defining this function is all we need to do. Emacs will look for and run the function if it exists (it doesn't by default).

Similar to the Bazaar version, this function looks for conflict marker text in the file, and starts smerge-mode if it finds any. The Git version is shorter because Git deals with conflicts differently, and also because I haven't hit any edge cases… yet.

(my software/consulting business)




FSF member since 2006 Become a Conservancy Supporter!