% cd |||||||||| hit tab…

Finding a file in a git repo with Emacs

posted 2011.04.29

I was looking for an even faster way to find files in the projects I work on than just using ido, so I looked at a whole bunch of different solutions that did not work for me. After realizing that pretty much all of the time I am working on a project, it is a http://git-scm.com/ repo. Luckily for me, git provides git-ls-files, which dumps out a list of all the files tracked in the repo. I made the following:

;;; find-file-in-git-repo.el --- Utility to find files in a git repo

;; Copyright 2011 atom smith

;; Author: atom smith
;; URL: http://github.com/re5et/find-file-in-git-repo
;; Version: 0.1.2

;;; Commentary:

;; Using default-directory searches upward for a .git repo directory,
;; then, feeds files into ido-completing-read using git ls-files.

(defun find-file-in-git-repo ()
  (interactive)
  (let* ((repo (find-git-repo default-directory))
         (files (shell-command-to-string (format "cd %s && git ls-files" repo))))
    (find-file
     (concat repo
             (ido-completing-read
              "find in git repo: "
              (remove-if (lambda (x) (string= "" x))
              (split-string files "\n")))))))

(defun find-git-repo (dir)
  (if (string= "/" dir)
      (message "not in a git repo.")
    (if (file-exists-p (expand-file-name ".git/" dir))
        dir
      (find-git-repo (expand-file-name "../" dir)))))

;;; find-file-in-git-repo.el ends here

(provide 'find-file-in-git-repo)

This works quite well for my purposes so I thought I would share it. I don’t claim to be an Emacs Lisp expert, so I would be more than happy with suggestions for improvements, or you could be really awesome and fork it and send me a pull request.

This is also available for installation from Marmalade with package.el or ELPA.