0

I'm using Pygit2 to run certain operations within the repo I'm working on.

If my code file is not at the root of the repo, how can I get the path of the repo from anywhere within the repo?

I can do the below in case the function is called from root, but how to do it if I run it from anywhere within the repository code?

$ cd /home/test/Desktop/code/Project
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

$ ipython3

In [1]: import os, pygit2
In [2]: repo = pygit2.Repository(os.getcwd())
Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186

2 Answers2

1

One option is simply to traverse parent directories until you find a .git directory:

import os
import pathlib
import pygit2

def find_toplevel(path, last=None):
    path = pathlib.Path(path).absolute()

    if path == last:
        return None
    if (path / '.git').is_dir():
        return path

    return find_toplevel(path.parent, last=path)

toplevel = find_toplevel('.')
if toplevel is not None:
  repo = pygit2.Repository(str(toplevel))

There are some caveats here, of course. You won't necessarily find a .git directory if someone has set the GIT_DIR environment variable. If you have a git worktree, then .git is a file, not a directory, and libgit2 doesn't seem to handle this (as of version 0.24).

larsks
  • 277,717
  • 41
  • 399
  • 399
  • Yes, traversal of parent directories is definitely one way to do it. I was checking if pygit2 had a mechanism to do it out of the box. Thanks for answering, I will wait for one more day before accepting this one in case any other answers come in. – Anshul Goyal Sep 01 '16 at 08:18
1

pygit2 does have a mechanism to do this, from libgit2:

from pygit2 import Repository, discover_repository


def get_repo(path: str) -> Repository:
    repo_path = discover_repository(path)
    if not repo_path:
        raise ValueError(f"No repository found at '{path}' and its parents")
    return Repository(repo_path)

See https://www.pygit2.org/repository.html?highlight=discover#pygit2.discover_repository

charlax
  • 25,125
  • 19
  • 60
  • 71