import git # pip3 install gitpython import os from functools import lru_cache def get_repo(starting_directory: str = os.path.dirname(__file__)) -> git.Repo: """ Try finding the repository by traversing up the tree. By default, the repository containing this module is returned. """ directory = starting_directory try: return git.Repo(directory) except git.InvalidGitRepositoryError: pass # We now have to traverse up the tree while directory != "/" and os.path.exists(directory): # Go to parent directory = os.path.abspath(directory + os.path.sep + "..") try: return git.Repo(directory) except git.InvalidGitRepositoryError: pass raise git.InvalidGitRepositoryError("Could not find git repository root in {}".format(starting_directory)) @lru_cache(maxsize=None) def get_version(repo: git.Repo = None) -> str: """ Return a version string for the current commit. There is a practical issue: the repository changes over time, f.e. switching branches with 'git checkout'. We want to know the version that is running in memory, not the one that is on disk. As a work-around, we cache the version information, in that it is at least consistent. It is up to the caller to request the version early enough. """ if repo is None: repo = get_repo() return "{} [{}]{}".format(repo.active_branch, repo.commit(), " (dirty)" if repo.is_dirty() else "") # at least cache the current repo version immediately try: _ = get_version() except: pass if __name__ == "__main__": print(get_version())