3030from git .refs import HEAD , Head , Reference , TagReference
3131from git .remote import Remote , add_progress , to_progress_instance
3232from git .util import Actor , finalize_process , decygpath , hex_to_bin
33-
3433import os .path as osp
3534
36- from .fun import rev_parse , is_git_dir , find_git_dir , touch
35+ from .fun import rev_parse , is_git_dir , find_submodule_git_dir , touch
3736
3837
3938log = logging .getLogger (__name__ )
5049
5150
5251def _expand_path (p ):
53- return osp .abspath (osp .expandvars (osp .expanduser (p )))
52+ return osp .normpath ( osp . abspath (osp .expandvars (osp .expanduser (p ) )))
5453
5554
5655class Repo (object ):
@@ -69,6 +68,11 @@ class Repo(object):
6968 'git_dir' is the .git repository directory, which is always set."""
7069 DAEMON_EXPORT_FILE = 'git-daemon-export-ok'
7170
71+ git = None # Must exist, or __del__ will fail in case we raise on `__init__()`
72+ working_dir = None
73+ _working_tree_dir = None
74+ git_dir = None
75+
7276 # precompiled regex
7377 re_whitespace = re .compile (r'\s+' )
7478 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
9599 repo = Repo("~/Development/git-python.git")
96100 repo = Repo("$REPOSITORIES/Development/git-python.git")
97101
98- In *Cygwin*, path may be a `'cygdrive/...'` prefixed path.
99-
102+ - In *Cygwin*, path may be a `'cygdrive/...'` prefixed path.
103+ - If `None, current-directory is used.
104+ - The :envvar:`GIT_DIR` if set and not empty takes precendance over this parameter.
100105 :param odbt:
101106 Object DataBase type - a type which is constructed by providing
102107 the directory containing the database objects, i.e. .git/objects. It will
@@ -109,40 +114,39 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals
109114 :raise InvalidGitRepositoryError:
110115 :raise NoSuchPathError:
111116 :return: git.Repo """
117+ epath = os .getenv ('GIT_DIR' ) or path or os .getcwd ()
112118 if Git .is_cygwin ():
113- path = decygpath (path )
114-
115- epath = _expand_path (path or os .getcwd ())
116- self .git = None # should be set for __del__ not to fail in case we raise
117- if not osp .exists (epath ):
119+ epath = decygpath (epath )
120+ epath = _expand_path (epath or path or os .getcwd ())
121+ if not os .path .exists (epath ):
118122 raise NoSuchPathError (epath )
119123
120- self .working_dir = None
121- self ._working_tree_dir = None
122- self .git_dir = None
123- curpath = os .getenv ('GIT_DIR' , epath )
124-
125- # walk up the path to find the .git dir
124+ ## Walk up the path to find the `.git` dir.
125+ #
126+ curpath = epath
126127 while curpath :
127128 # ABOUT osp.NORMPATH
128129 # It's important to normalize the paths, as submodules will otherwise initialize their
129130 # repo instances with paths that depend on path-portions that will not exist after being
130131 # removed. It's just cleaner.
131132 if is_git_dir (curpath ):
132- self .git_dir = osp . normpath ( curpath )
133- self ._working_tree_dir = osp .dirname (self .git_dir )
133+ self .git_dir = curpath
134+ self ._working_tree_dir = os . path .dirname (self .git_dir )
134135 break
135136
136- gitpath = find_git_dir (osp .join (curpath , '.git' ))
137- if gitpath is not None :
138- self .git_dir = osp .normpath (gitpath )
137+ sm_gitpath = find_submodule_git_dir (osp .join (curpath , '.git' ))
138+ if sm_gitpath is not None :
139+ self .git_dir = osp .normpath (sm_gitpath )
140+ sm_gitpath = find_submodule_git_dir (osp .join (curpath , '.git' ))
141+ if sm_gitpath is not None :
142+ self .git_dir = _expand_path (sm_gitpath )
139143 self ._working_tree_dir = curpath
140144 break
141145
142146 if not search_parent_directories :
143147 break
144- curpath , dummy = osp .split (curpath )
145- if not dummy :
148+ curpath , tail = osp .split (curpath )
149+ if not tail :
146150 break
147151 # END while curpath
148152
0 commit comments