From b29388a8f9cf3522e5f52b47572af7d8f61862a1 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Wed, 19 Oct 2016 15:49:13 +0200 Subject: [PATCH 1/3] FIX #535: expand also GIT_DIR var on Repo-construct + Ignore "empty" GIT_DIR vars. + Improve documentation on the constructor `path` parameter. --- git/repo/base.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index c5cdce7c6..d36864bba 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -124,6 +124,8 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals repo = Repo("~/Development/git-python.git") repo = Repo("$REPOSITORIES/Development/git-python.git") + if `None, current-directory is used. + The :envvar:`GIT_DIR` if set and not empty takes precendance over this parameter. :param odbt: Object DataBase type - a type which is constructed by providing the directory containing the database objects, i.e. .git/objects. It will @@ -136,17 +138,19 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals :raise InvalidGitRepositoryError: :raise NoSuchPathError: :return: git.Repo """ - epath = _expand_path(path or os.getcwd()) self.git = None # should be set for __del__ not to fail in case we raise + epath = os.getenv('GIT_DIR') + epath = _expand_path(epath or path or os.getcwd()) if not os.path.exists(epath): raise NoSuchPathError(epath) self.working_dir = None self._working_tree_dir = None self.git_dir = None - curpath = os.getenv('GIT_DIR', epath) - # walk up the path to find the .git dir + ## Walk up the path to find the `.git` dir. + # + curpath = epath while curpath: # ABOUT os.path.NORMPATH # It's important to normalize the paths, as submodules will otherwise initialize their From 9d5d143f72e4d588e3a0abb2ab82fa5a2c35e8aa Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Wed, 19 Oct 2016 16:01:47 +0200 Subject: [PATCH 2/3] repo: minor code and doc correcions. + Expansion of paths also `osp.normalize()` them. + Make Repo-fields --> class-fields to avoid initializations on construct. + Explain and rename `git.repo.fun.find_git_dir()` is for submodules (`find_submodule_git_dir()`). --- git/repo/base.py | 26 +++++++++++++------------- git/repo/fun.py | 7 ++++--- git/test/test_submodule.py | 4 ++-- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index d36864bba..bde9b936a 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -47,7 +47,7 @@ from .fun import ( rev_parse, is_git_dir, - find_git_dir, + find_submodule_git_dir, touch, ) from git.compat import ( @@ -79,7 +79,7 @@ def _expand_path(p): - return os.path.abspath(os.path.expandvars(os.path.expanduser(p))) + return os.path.normpath(os.path.abspath(os.path.expandvars(os.path.expanduser(p)))) class Repo(object): @@ -98,6 +98,11 @@ class Repo(object): 'git_dir' is the .git repository directory, which is always set.""" DAEMON_EXPORT_FILE = 'git-daemon-export-ok' + git = None # Must exist, or __del__ will fail in case we raise on `__init__()` + working_dir = None + _working_tree_dir = None + git_dir = None + # precompiled regex re_whitespace = re.compile(r'\s+') re_hexsha_only = re.compile('^[0-9A-Fa-f]{40}$') @@ -138,16 +143,11 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals :raise InvalidGitRepositoryError: :raise NoSuchPathError: :return: git.Repo """ - self.git = None # should be set for __del__ not to fail in case we raise epath = os.getenv('GIT_DIR') epath = _expand_path(epath or path or os.getcwd()) if not os.path.exists(epath): raise NoSuchPathError(epath) - self.working_dir = None - self._working_tree_dir = None - self.git_dir = None - ## Walk up the path to find the `.git` dir. # curpath = epath @@ -157,20 +157,20 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals # repo instances with paths that depend on path-portions that will not exist after being # removed. It's just cleaner. if is_git_dir(curpath): - self.git_dir = os.path.normpath(curpath) + self.git_dir = curpath self._working_tree_dir = os.path.dirname(self.git_dir) break - gitpath = find_git_dir(join(curpath, '.git')) - if gitpath is not None: - self.git_dir = os.path.normpath(gitpath) + sm_gitpath = find_submodule_git_dir(join(curpath, '.git')) + if sm_gitpath is not None: + self.git_dir = os.path.normpath(sm_gitpath) self._working_tree_dir = curpath break if not search_parent_directories: break - curpath, dummy = os.path.split(curpath) - if not dummy: + curpath, tail = os.path.split(curpath) + if not tail: break # END while curpath diff --git a/git/repo/fun.py b/git/repo/fun.py index 320eb1c8d..fe0896a92 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -20,7 +20,7 @@ from git.compat import xrange -__all__ = ('rev_parse', 'is_git_dir', 'touch', 'find_git_dir', 'name_to_object', 'short_to_long', 'deref_tag', +__all__ = ('rev_parse', 'is_git_dir', 'touch', 'find_submodule_git_dir', 'name_to_object', 'short_to_long', 'deref_tag', 'to_commit') @@ -49,7 +49,8 @@ def is_git_dir(d): return False -def find_git_dir(d): +def find_submodule_git_dir(d): + """Search for a submodule repo.""" if is_git_dir(d): return d @@ -64,7 +65,7 @@ def find_git_dir(d): path = content[8:] if not os.path.isabs(path): path = join(dirname(d), path) - return find_git_dir(path) + return find_submodule_git_dir(path) # end handle exception return None diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 9db4f9c90..39040ced0 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -14,7 +14,7 @@ from git.objects.submodule.base import Submodule from git.objects.submodule.root import RootModule, RootUpdateProgress from git.repo.fun import ( - find_git_dir, + find_submodule_git_dir, touch ) from git.test.lib import ( @@ -757,7 +757,7 @@ def assert_exists(sm, value=True): else: assert osp.isfile(module_repo_path) assert sm.module().has_separate_working_tree() - assert find_git_dir(module_repo_path) is not None, "module pointed to by .git file must be valid" + assert find_submodule_git_dir(module_repo_path) is not None, "module pointed to by .git file must be valid" # end verify submodule 'style' # test move From 5fac8d40f535ec8f3d1cf2187fbbe3418d82cf62 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 22 Oct 2016 13:27:44 +0200 Subject: [PATCH 3/3] fix(repo): Use GIT_DIR only if no repo-path given FIX #535 according to Byron's comment: https://github.com/gitpython-developers/GitPython/issues/535#issuecomment-255522529 --- git/repo/base.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/git/repo/base.py b/git/repo/base.py index f3a04cf4c..0f85e3d96 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -100,8 +100,8 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals repo = Repo("$REPOSITORIES/Development/git-python.git") - In *Cygwin*, path may be a `'cygdrive/...'` prefixed path. - - If `None, current-directory is used. - - The :envvar:`GIT_DIR` if set and not empty takes precendance over this parameter. + - If it evaluates to false, :envvar:`GIT_DIR` is used, and if this also evals to false, + the current-directory is used. :param odbt: Object DataBase type - a type which is constructed by providing the directory containing the database objects, i.e. .git/objects. It will @@ -114,7 +114,9 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals :raise InvalidGitRepositoryError: :raise NoSuchPathError: :return: git.Repo """ - epath = os.getenv('GIT_DIR') or path or os.getcwd() + epath = path or os.getenv('GIT_DIR') + if not epath: + epath = os.getcwd() if Git.is_cygwin(): epath = decygpath(epath) epath = _expand_path(epath or path or os.getcwd())