diff --git a/git/repo/base.py b/git/repo/base.py index 21d129e98..0f85e3d96 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -30,10 +30,9 @@ from git.refs import HEAD, Head, Reference, TagReference from git.remote import Remote, add_progress, to_progress_instance from git.util import Actor, finalize_process, decygpath, hex_to_bin - import os.path as osp -from .fun import rev_parse, is_git_dir, find_git_dir, touch +from .fun import rev_parse, is_git_dir, find_submodule_git_dir, touch log = logging.getLogger(__name__) @@ -50,7 +49,7 @@ def _expand_path(p): - return osp.abspath(osp.expandvars(osp.expanduser(p))) + return osp.normpath(osp.abspath(osp.expandvars(osp.expanduser(p)))) class Repo(object): @@ -69,6 +68,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}$') @@ -95,8 +99,9 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals repo = Repo("~/Development/git-python.git") repo = Repo("$REPOSITORIES/Development/git-python.git") - In *Cygwin*, path may be a `'cygdrive/...'` prefixed path. - + - In *Cygwin*, path may be a `'cygdrive/...'` prefixed path. + - 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 @@ -109,40 +114,41 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals :raise InvalidGitRepositoryError: :raise NoSuchPathError: :return: git.Repo """ + epath = path or os.getenv('GIT_DIR') + if not epath: + epath = os.getcwd() if Git.is_cygwin(): - path = decygpath(path) - - epath = _expand_path(path or os.getcwd()) - self.git = None # should be set for __del__ not to fail in case we raise - if not osp.exists(epath): + epath = decygpath(epath) + 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 osp.NORMPATH # It's important to normalize the paths, as submodules will otherwise initialize their # 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 = osp.normpath(curpath) - self._working_tree_dir = osp.dirname(self.git_dir) + self.git_dir = curpath + self._working_tree_dir = os.path.dirname(self.git_dir) break - gitpath = find_git_dir(osp.join(curpath, '.git')) - if gitpath is not None: - self.git_dir = osp.normpath(gitpath) + sm_gitpath = find_submodule_git_dir(osp.join(curpath, '.git')) + if sm_gitpath is not None: + self.git_dir = osp.normpath(sm_gitpath) + sm_gitpath = find_submodule_git_dir(osp.join(curpath, '.git')) + if sm_gitpath is not None: + self.git_dir = _expand_path(sm_gitpath) self._working_tree_dir = curpath break if not search_parent_directories: break - curpath, dummy = osp.split(curpath) - if not dummy: + curpath, tail = osp.split(curpath) + if not tail: break # END while curpath diff --git a/git/repo/fun.py b/git/repo/fun.py index c5a8a52b1..39e55880f 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -16,7 +16,7 @@ from git.cmd import Git -__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') @@ -47,7 +47,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 @@ -60,12 +61,13 @@ def find_git_dir(d): else: if content.startswith('gitdir: '): path = content[8:] + if Git.is_cygwin(): ## Cygwin creates submodules prefixed with `/cygdrive/...` suffixes. path = decygpath(path) if not osp.isabs(path): path = osp.join(osp.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 fcaad04ba..0ebd9ec76 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -7,34 +7,24 @@ import git from git.cmd import Git -from git.compat import ( - string_types, - is_win, -) +from git.compat import string_types, is_win from git.exc import ( InvalidGitRepositoryError, RepositoryDirtyError ) from git.objects.submodule.base import Submodule -from git.objects.submodule.root import ( - RootModule, - RootUpdateProgress, -) +from git.objects.submodule.root import RootModule, RootUpdateProgress from git.repo.fun import ( - find_git_dir, - touch, + find_submodule_git_dir, + touch ) from git.test.lib import ( TestBase, - with_rw_repo, + with_rw_repo ) from git.test.lib import with_rw_directory -from git.util import ( - to_native_path_linux, - join_path_native, - HIDE_WINDOWS_KNOWN_ERRORS, -) - +from git.util import HIDE_WINDOWS_KNOWN_ERRORS +from git.util import to_native_path_linux, join_path_native import os.path as osp @@ -775,7 +765,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
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: