diff --git a/git/repo/base.py b/git/repo/base.py index f35870803..af8e0c74c 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -66,7 +66,7 @@ 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__()` + _git = None # Must exist, or __del__ will fail in case we raise on `__init__()` working_dir = None _working_tree_dir = None git_dir = None @@ -202,7 +202,6 @@ def __init__(self, path=None, odbt=GitCmdObjectDB, search_parent_directories=Fal # END working dir handling self.working_dir = self._working_tree_dir or self.common_dir - self.git = self.GitCommandWrapperType(self.working_dir) # special handling, in special times args = [osp.join(self.common_dir, 'objects')] @@ -210,6 +209,35 @@ def __init__(self, path=None, odbt=GitCmdObjectDB, search_parent_directories=Fal args.append(self.git) self.odb = odbt(*args) + def _get_git(self): + working_dir = self._working_tree_dir or self.common_dir + if self._git: + if self._git._working_dir != expand_path(working_dir): + self.close() + self._git = None + + if not self._git: + self._git = self.GitCommandWrapperType(working_dir) + return self._git + + def _del_git(self): + if self._git: + self._git.clear_cache() + self._git = None + # Tempfiles objects on Windows are holding references to + # open files until they are collected by the garbage + # collector, thus preventing deletion. + # TODO: Find these references and ensure they are closed + # and deleted synchronously rather than forcing a gc + # collection. + if is_win: + gc.collect() + gitdb.util.mman.collect() + if is_win: + gc.collect() + + git = property(fget=_get_git, fdel=_del_git) + def __enter__(self): return self @@ -223,19 +251,7 @@ def __del__(self): pass def close(self): - if self.git: - self.git.clear_cache() - # Tempfiles objects on Windows are holding references to - # open files until they are collected by the garbage - # collector, thus preventing deletion. - # TODO: Find these references and ensure they are closed - # and deleted synchronously rather than forcing a gc - # collection. - if is_win: - gc.collect() - gitdb.util.mman.collect() - if is_win: - gc.collect() + del self.git def __eq__(self, rhs): if isinstance(rhs, Repo): @@ -431,7 +447,15 @@ def _get_config_path(self, config_level): elif config_level == "global": return osp.normpath(osp.expanduser("~/.gitconfig")) elif config_level == "repository": - return osp.normpath(osp.join(self._common_dir or self.git_dir, "config")) + try: + config_path = self.git.rev_parse("config", git_path=True) + except GitCommandError: + return osp.normpath(osp.join(self._common_dir or self.git_dir, "config")) + else: + if self.git._working_dir: + return osp.normpath(osp.join(self.git._working_dir, config_path)) + else: + return config_path raise ValueError("Invalid configuration level: %r" % config_level) diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 1c06010f4..687db9906 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -366,8 +366,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): - cls.rorepo.git.clear_cache() - cls.rorepo.git = None + del cls.rorepo.git def _make_file(self, rela_path, data, repo=None): """