Skip to content

Commit 4754fa1

Browse files
authored
Merge pull request gitpython-developers#537 from ankostis/exp_git_dir
FIX gitpython-developers#535: expand also GIT_DIR var on Repo-construction
2 parents caa0ea7 + 5fac8d4 commit 4754fa1

File tree

3 files changed

+42
-44
lines changed

3 files changed

+42
-44
lines changed

Diff for: git/repo/base.py

+29-23
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,9 @@
3030
from git.refs import HEAD, Head, Reference, TagReference
3131
from git.remote import Remote, add_progress, to_progress_instance
3232
from git.util import Actor, finalize_process, decygpath, hex_to_bin
33-
3433
import 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

3938
log = logging.getLogger(__name__)
@@ -50,7 +49,7 @@
5049

5150

5251
def _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

5655
class 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 it evaluates to false, :envvar:`GIT_DIR` is used, and if this also evals to false,
104+
the current-directory is used.
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,41 @@ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=Fals
109114
:raise InvalidGitRepositoryError:
110115
:raise NoSuchPathError:
111116
:return: git.Repo """
117+
epath = path or os.getenv('GIT_DIR')
118+
if not epath:
119+
epath = os.getcwd()
112120
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):
121+
epath = decygpath(epath)
122+
epath = _expand_path(epath or path or os.getcwd())
123+
if not os.path.exists(epath):
118124
raise NoSuchPathError(epath)
119125

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
126+
## Walk up the path to find the `.git` dir.
127+
#
128+
curpath = epath
126129
while curpath:
127130
# ABOUT osp.NORMPATH
128131
# It's important to normalize the paths, as submodules will otherwise initialize their
129132
# repo instances with paths that depend on path-portions that will not exist after being
130133
# removed. It's just cleaner.
131134
if is_git_dir(curpath):
132-
self.git_dir = osp.normpath(curpath)
133-
self._working_tree_dir = osp.dirname(self.git_dir)
135+
self.git_dir = curpath
136+
self._working_tree_dir = os.path.dirname(self.git_dir)
134137
break
135138

136-
gitpath = find_git_dir(osp.join(curpath, '.git'))
137-
if gitpath is not None:
138-
self.git_dir = osp.normpath(gitpath)
139+
sm_gitpath = find_submodule_git_dir(osp.join(curpath, '.git'))
140+
if sm_gitpath is not None:
141+
self.git_dir = osp.normpath(sm_gitpath)
142+
sm_gitpath = find_submodule_git_dir(osp.join(curpath, '.git'))
143+
if sm_gitpath is not None:
144+
self.git_dir = _expand_path(sm_gitpath)
139145
self._working_tree_dir = curpath
140146
break
141147

142148
if not search_parent_directories:
143149
break
144-
curpath, dummy = osp.split(curpath)
145-
if not dummy:
150+
curpath, tail = osp.split(curpath)
151+
if not tail:
146152
break
147153
# END while curpath
148154

Diff for: git/repo/fun.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from git.cmd import Git
1717

1818

19-
__all__ = ('rev_parse', 'is_git_dir', 'touch', 'find_git_dir', 'name_to_object', 'short_to_long', 'deref_tag',
19+
__all__ = ('rev_parse', 'is_git_dir', 'touch', 'find_submodule_git_dir', 'name_to_object', 'short_to_long', 'deref_tag',
2020
'to_commit')
2121

2222

@@ -47,7 +47,8 @@ def is_git_dir(d):
4747
return False
4848

4949

50-
def find_git_dir(d):
50+
def find_submodule_git_dir(d):
51+
"""Search for a submodule repo."""
5152
if is_git_dir(d):
5253
return d
5354

@@ -60,12 +61,13 @@ def find_git_dir(d):
6061
else:
6162
if content.startswith('gitdir: '):
6263
path = content[8:]
64+
6365
if Git.is_cygwin():
6466
## Cygwin creates submodules prefixed with `/cygdrive/...` suffixes.
6567
path = decygpath(path)
6668
if not osp.isabs(path):
6769
path = osp.join(osp.dirname(d), path)
68-
return find_git_dir(path)
70+
return find_submodule_git_dir(path)
6971
# end handle exception
7072
return None
7173

Diff for: git/test/test_submodule.py

+8-18
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,24 @@
77

88
import git
99
from git.cmd import Git
10-
from git.compat import (
11-
string_types,
12-
is_win,
13-
)
10+
from git.compat import string_types, is_win
1411
from git.exc import (
1512
InvalidGitRepositoryError,
1613
RepositoryDirtyError
1714
)
1815
from git.objects.submodule.base import Submodule
19-
from git.objects.submodule.root import (
20-
RootModule,
21-
RootUpdateProgress,
22-
)
16+
from git.objects.submodule.root import RootModule, RootUpdateProgress
2317
from git.repo.fun import (
24-
find_git_dir,
25-
touch,
18+
find_submodule_git_dir,
19+
touch
2620
)
2721
from git.test.lib import (
2822
TestBase,
29-
with_rw_repo,
23+
with_rw_repo
3024
)
3125
from git.test.lib import with_rw_directory
32-
from git.util import (
33-
to_native_path_linux,
34-
join_path_native,
35-
HIDE_WINDOWS_KNOWN_ERRORS,
36-
)
37-
26+
from git.util import HIDE_WINDOWS_KNOWN_ERRORS
27+
from git.util import to_native_path_linux, join_path_native
3828
import os.path as osp
3929

4030

@@ -775,7 +765,7 @@ def assert_exists(sm, value=True):
775765
else:
776766
assert osp.isfile(module_repo_path)
777767
assert sm.module().has_separate_working_tree()
778-
assert find_git_dir(module_repo_path) is not None, "module pointed to by .git file must be valid"
768+
assert find_submodule_git_dir(module_repo_path) is not None, "module pointed to by .git file must be valid"
779769
# end verify submodule 'style'
780770

781771
# test move

0 commit comments

Comments
 (0)