9

How can I get the root directory of the current git repo? I could run shell-command-to-string on something like git rev-parse --show-toplevel. Is there a better way? Does magit or any other git front-end expose this info?

Pradhan
  • 2,330
  • 14
  • 28

3 Answers3

13

In Magit this is available as magit-toplevel (but I agree with @abo-abo that it makes sense to use vc-root-dir).

tarsius
  • 25,298
  • 4
  • 69
  • 109
Kyle Meyer
  • 6,914
  • 26
  • 22
  • `vc-root-dir` is surely the most generic. However, I am unable to get it to work in that form as I mentioned in the comments on @abo-abo's answer. But this one worked straight. Thanks! – Pradhan Feb 17 '15 at 21:52
8

You need vc-root-dir. Works for more than git.

abo-abo
  • 13,943
  • 1
  • 29
  • 43
  • 3
    Could you elaborate? I don't see a function or a package titled `vc-root-dir`. The only thing that's close is `vc-root-diff`. And on a `vc`-related search, I find [this](http://stackoverflow.com/questions/16125637/get-the-vc-root-in-emacs-lisp). – Pradhan Feb 17 '15 at 21:33
  • It's an autoloaded function in vc.el, built-in – abo-abo Feb 17 '15 at 21:35
  • Perhaps my `vc` is too old? I have the one built-in with emacs 24.3. I don't see `vc-root` in `vc.el` or with `apropos` etc. Looking at `vc.el`, I see things like `(setq rootdir (vc-call-backend...))`. And indeed, `(vc-call-backend 'Git 'root default-directory)` works. – Pradhan Feb 17 '15 at 21:50
  • 1
    n.b. I think `vc-root-dir` is only in trunk at this stage. It's certainly not in 24.4. Presumably it will be available in Emacs 25. – phils Feb 17 '15 at 21:52
2

As mentioned by abo-abo, in Emacs 25, there is a function called vc-root-dir that does what you need in a backend-agnostic manner. For earlier versions of Emacs, the following is a suitable replacement:

(defun vc-root-dir ()
  (let ((backend (vc-deduce-backend)))
    (and backend
         (ignore-errors
           (vc-call-backend backend 'root default-directory)))))

As mentioned by Kyle, Magit provides the function magit-get-top-dir, which simply calls git rev-parse --show-cdup and interprets the result.

jch
  • 5,680
  • 22
  • 39
  • 1
    Indeed, after looking at the implementation of `vc-root-diff`, I tried `vc-deduce-backend`. Somehow, that returns `nil` in my git-repo. However, `vc-responsible-backend default-directory` returns `Git`. – Pradhan Feb 17 '15 at 22:21
  • If the current buffer is not tracked by `vc`, then `vc-deduce-backend` returns `nil`. Does that explain it? – jch Feb 17 '15 at 22:25
  • 1
    Ah, it does. I was running it in `ielm` and expecting `vc-deduce-backend` to use `default-directory`. Thanks! – Pradhan Feb 17 '15 at 22:35
  • Did you mean `vc-root-dir` instead of `vc-root-diff`? – Michael Mrozek Oct 01 '19 at 21:42