Skip to content

FIX #535: expand also GIT_DIR var on Repo-construction #537

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 29 additions & 23 deletions git/repo/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__)
Expand All @@ -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):
Expand All @@ -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}$')
Expand All @@ -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
Expand All @@ -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

Expand Down
8 changes: 5 additions & 3 deletions git/repo/fun.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')


Expand Down Expand Up @@ -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

Expand All @@ -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

Expand Down
26 changes: 8 additions & 18 deletions git/test/test_submodule.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down Expand Up @@ -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
Expand Down