summaryrefslogtreecommitdiff
path: root/git/repo/base.py
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2017-09-28 15:17:25 +0200
committerGitHub <noreply@github.com>2017-09-28 15:17:25 +0200
commit58998fb2dd6a1cad5faffdc36ae536ee6b04e3d2 (patch)
tree4f5c342b1c20b23a5bc73eb74855c4bb81f2c197 /git/repo/base.py
parent251128d41cdf39a49468ed5d997cc1640339ccbc (diff)
parent2af601d5800a39ab04e9fe6cf22ef7b917ab5d67 (diff)
downloadgitpython-58998fb2dd6a1cad5faffdc36ae536ee6b04e3d2.tar.gz
Merge branch 'master' into master
Diffstat (limited to 'git/repo/base.py')
-rw-r--r--git/repo/base.py50
1 files changed, 36 insertions, 14 deletions
diff --git a/git/repo/base.py b/git/repo/base.py
index 28bb2a5d..d3bdc983 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -9,6 +9,7 @@ import logging
import os
import re
import sys
+import warnings
from git.cmd import (
Git,
@@ -29,7 +30,7 @@ from git.index import IndexFile
from git.objects import Submodule, RootModule, Commit
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
+from git.util import Actor, finalize_process, decygpath, hex_to_bin, expand_path
import os.path as osp
from .fun import rev_parse, is_git_dir, find_submodule_git_dir, touch, find_worktree_git_dir
@@ -50,10 +51,6 @@ BlameEntry = namedtuple('BlameEntry', ['commit', 'linenos', 'orig_path', 'orig_l
__all__ = ('Repo',)
-def _expand_path(p):
- return osp.normpath(osp.abspath(osp.expandvars(osp.expanduser(p))))
-
-
class Repo(object):
"""Represents a git repository and allows you to query references,
gather commit information, generate diffs, create and clone repositories query
@@ -74,6 +71,7 @@ class Repo(object):
working_dir = None
_working_tree_dir = None
git_dir = None
+ _common_dir = None
# precompiled regex
re_whitespace = re.compile(r'\s+')
@@ -90,7 +88,7 @@ class Repo(object):
# Subclasses may easily bring in their own custom types by placing a constructor or type here
GitCommandWrapperType = Git
- def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False):
+ def __init__(self, path=None, odbt=DefaultDBType, search_parent_directories=False, expand_vars=True):
"""Create a new Repo instance
:param path:
@@ -116,12 +114,18 @@ class Repo(object):
:raise InvalidGitRepositoryError:
:raise NoSuchPathError:
:return: git.Repo """
+
epath = path or os.getenv('GIT_DIR')
if not epath:
epath = os.getcwd()
if Git.is_cygwin():
epath = decygpath(epath)
- epath = _expand_path(epath or path or os.getcwd())
+
+ epath = epath or path or os.getcwd()
+ if expand_vars and ("%" in epath or "$" in epath):
+ warnings.warn("The use of environment variables in paths is deprecated" +
+ "\nfor security reasons and may be removed in the future!!")
+ epath = expand_path(epath, expand_vars)
if not os.path.exists(epath):
raise NoSuchPathError(epath)
@@ -148,7 +152,7 @@ class Repo(object):
sm_gitpath = find_worktree_git_dir(dotgit)
if sm_gitpath is not None:
- self.git_dir = _expand_path(sm_gitpath)
+ self.git_dir = expand_path(sm_gitpath, expand_vars)
self._working_tree_dir = curpath
break
@@ -169,17 +173,23 @@ class Repo(object):
# lets not assume the option exists, although it should
pass
+ try:
+ common_dir = open(osp.join(self.git_dir, 'commondir'), 'rt').readlines()[0].strip()
+ self._common_dir = osp.join(self.git_dir, common_dir)
+ except (OSError, IOError):
+ self._common_dir = None
+
# adjust the wd in case we are actually bare - we didn't know that
# in the first place
if self._bare:
self._working_tree_dir = None
# END working dir handling
- self.working_dir = self._working_tree_dir or self.git_dir
+ 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.git_dir, 'objects')]
+ args = [osp.join(self.common_dir, 'objects')]
if issubclass(odbt, GitCmdObjectDB):
args.append(self.git)
self.odb = odbt(*args)
@@ -237,6 +247,13 @@ class Repo(object):
return self._working_tree_dir
@property
+ def common_dir(self):
+ """:return: The git dir that holds everything except possibly HEAD,
+ FETCH_HEAD, ORIG_HEAD, COMMIT_EDITMSG, index, and logs/ .
+ """
+ return self._common_dir or self.git_dir
+
+ @property
def bare(self):
""":return: True if the repository is bare"""
return self._bare
@@ -574,7 +591,7 @@ class Repo(object):
:note:
The method does not check for the existence of the paths in alts
as the caller is responsible."""
- alternates_path = osp.join(self.git_dir, 'objects', 'info', 'alternates')
+ alternates_path = osp.join(self.common_dir, 'objects', 'info', 'alternates')
if not alts:
if osp.isfile(alternates_path):
os.remove(alternates_path)
@@ -844,7 +861,7 @@ class Repo(object):
return blames
@classmethod
- def init(cls, path=None, mkdir=True, odbt=DefaultDBType, **kwargs):
+ def init(cls, path=None, mkdir=True, odbt=DefaultDBType, expand_vars=True, **kwargs):
"""Initialize a git repository at the given path if specified
:param path:
@@ -862,12 +879,17 @@ class Repo(object):
the directory containing the database objects, i.e. .git/objects.
It will be used to access all object data
+ :param expand_vars:
+ if specified, environment variables will not be escaped. This
+ can lead to information disclosure, allowing attackers to
+ access the contents of environment variables
+
:parm kwargs:
keyword arguments serving as additional options to the git-init command
:return: ``git.Repo`` (the newly created repo)"""
if path:
- path = _expand_path(path)
+ path = expand_path(path, expand_vars)
if mkdir and path and not osp.exists(path):
os.makedirs(path, 0o755)
@@ -932,7 +954,7 @@ class Repo(object):
* All remaining keyword arguments are given to the git-clone command
:return: ``git.Repo`` (the newly cloned repo)"""
- return self._clone(self.git, self.git_dir, path, type(self.odb), progress, **kwargs)
+ return self._clone(self.git, self.common_dir, path, type(self.odb), progress, **kwargs)
@classmethod
def clone_from(cls, url, to_path, progress=None, env=None, **kwargs):