summaryrefslogtreecommitdiff
path: root/git/repo/base.py
diff options
context:
space:
mode:
Diffstat (limited to 'git/repo/base.py')
-rw-r--r--git/repo/base.py143
1 files changed, 66 insertions, 77 deletions
diff --git a/git/repo/base.py b/git/repo/base.py
index bde9b936..f3a04cf4 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -4,52 +4,16 @@
# This module is part of GitPython and is released under
# the BSD License: http://www.opensource.org/licenses/bsd-license.php
-from git.exc import (
- InvalidGitRepositoryError,
- NoSuchPathError,
- GitCommandError
-)
+from collections import namedtuple
+import logging
+import os
+import re
+import sys
+
from git.cmd import (
Git,
handle_process_output
)
-from git.refs import (
- HEAD,
- Head,
- Reference,
- TagReference,
-)
-from git.objects import (
- Submodule,
- RootModule,
- Commit
-)
-from git.util import (
- Actor,
- finalize_process
-)
-from git.index import IndexFile
-from git.config import GitConfigParser
-from git.remote import (
- Remote,
- add_progress,
- to_progress_instance
-)
-
-from git.db import GitCmdObjectDB
-
-from gitdb.util import (
- join,
- isfile,
- hex_to_bin
-)
-
-from .fun import (
- rev_parse,
- is_git_dir,
- find_submodule_git_dir,
- touch,
-)
from git.compat import (
text_type,
defenc,
@@ -58,12 +22,18 @@ from git.compat import (
range,
is_win,
)
+from git.config import GitConfigParser
+from git.db import GitCmdObjectDB
+from git.exc import InvalidGitRepositoryError, NoSuchPathError, GitCommandError
+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
+import os.path as osp
+
+from .fun import rev_parse, is_git_dir, find_submodule_git_dir, touch
-import os
-import sys
-import re
-import logging
-from collections import namedtuple
log = logging.getLogger(__name__)
@@ -79,7 +49,7 @@ __all__ = ('Repo',)
def _expand_path(p):
- return os.path.normpath(os.path.abspath(os.path.expandvars(os.path.expanduser(p))))
+ return osp.normpath(osp.abspath(osp.expandvars(osp.expanduser(p))))
class Repo(object):
@@ -129,8 +99,9 @@ class Repo(object):
repo = Repo("~/Development/git-python.git")
repo = Repo("$REPOSITORIES/Development/git-python.git")
- if `None, current-directory is used.
- The :envvar:`GIT_DIR` if set and not empty takes precendance over this parameter.
+ - In *Cygwin*, path may be a `'cygdrive/...'` prefixed path.
+ - If `None, current-directory is used.
+ - The :envvar:`GIT_DIR` if set and not empty takes precendance over this parameter.
:param odbt:
Object DataBase type - a type which is constructed by providing
the directory containing the database objects, i.e. .git/objects. It will
@@ -143,7 +114,9 @@ class Repo(object):
:raise InvalidGitRepositoryError:
:raise NoSuchPathError:
:return: git.Repo """
- epath = os.getenv('GIT_DIR')
+ epath = os.getenv('GIT_DIR') or path or os.getcwd()
+ if Git.is_cygwin():
+ epath = decygpath(epath)
epath = _expand_path(epath or path or os.getcwd())
if not os.path.exists(epath):
raise NoSuchPathError(epath)
@@ -152,7 +125,7 @@ class Repo(object):
#
curpath = epath
while curpath:
- # ABOUT os.path.NORMPATH
+ # 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.
@@ -161,15 +134,18 @@ class Repo(object):
self._working_tree_dir = os.path.dirname(self.git_dir)
break
- sm_gitpath = find_submodule_git_dir(join(curpath, '.git'))
+ sm_gitpath = find_submodule_git_dir(osp.join(curpath, '.git'))
if sm_gitpath is not None:
- self.git_dir = os.path.normpath(sm_gitpath)
+ 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, tail = os.path.split(curpath)
+ curpath, tail = osp.split(curpath)
if not tail:
break
# END while curpath
@@ -194,7 +170,7 @@ class Repo(object):
self.git = self.GitCommandWrapperType(self.working_dir)
# special handling, in special times
- args = [join(self.git_dir, 'objects')]
+ args = [osp.join(self.git_dir, 'objects')]
if issubclass(odbt, GitCmdObjectDB):
args.append(self.git)
self.odb = odbt(*args)
@@ -216,12 +192,12 @@ class Repo(object):
# Description property
def _get_description(self):
- filename = join(self.git_dir, 'description')
+ filename = osp.join(self.git_dir, 'description')
with open(filename, 'rb') as fp:
return fp.read().rstrip().decode(defenc)
def _set_description(self, descr):
- filename = join(self.git_dir, 'description')
+ filename = osp.join(self.git_dir, 'description')
with open(filename, 'wb') as fp:
fp.write((descr + '\n').encode(defenc))
@@ -385,12 +361,12 @@ class Repo(object):
if config_level == "system":
return "/etc/gitconfig"
elif config_level == "user":
- config_home = os.environ.get("XDG_CONFIG_HOME") or os.path.join(os.environ.get("HOME", '~'), ".config")
- return os.path.normpath(os.path.expanduser(join(config_home, "git", "config")))
+ config_home = os.environ.get("XDG_CONFIG_HOME") or osp.join(os.environ.get("HOME", '~'), ".config")
+ return osp.normpath(osp.expanduser(osp.join(config_home, "git", "config")))
elif config_level == "global":
- return os.path.normpath(os.path.expanduser("~/.gitconfig"))
+ return osp.normpath(osp.expanduser("~/.gitconfig"))
elif config_level == "repository":
- return os.path.normpath(join(self.git_dir, "config"))
+ return osp.normpath(osp.join(self.git_dir, "config"))
raise ValueError("Invalid configuration level: %r" % config_level)
@@ -534,12 +510,12 @@ class Repo(object):
return True
def _get_daemon_export(self):
- filename = join(self.git_dir, self.DAEMON_EXPORT_FILE)
- return os.path.exists(filename)
+ filename = osp.join(self.git_dir, self.DAEMON_EXPORT_FILE)
+ return osp.exists(filename)
def _set_daemon_export(self, value):
- filename = join(self.git_dir, self.DAEMON_EXPORT_FILE)
- fileexists = os.path.exists(filename)
+ filename = osp.join(self.git_dir, self.DAEMON_EXPORT_FILE)
+ fileexists = osp.exists(filename)
if value and not fileexists:
touch(filename)
elif not value and fileexists:
@@ -554,9 +530,9 @@ class Repo(object):
"""The list of alternates for this repo from which objects can be retrieved
:return: list of strings being pathnames of alternates"""
- alternates_path = join(self.git_dir, 'objects', 'info', 'alternates')
+ alternates_path = osp.join(self.git_dir, 'objects', 'info', 'alternates')
- if os.path.exists(alternates_path):
+ if osp.exists(alternates_path):
with open(alternates_path, 'rb') as f:
alts = f.read().decode(defenc)
return alts.strip().splitlines()
@@ -574,9 +550,9 @@ class Repo(object):
:note:
The method does not check for the existance of the paths in alts
as the caller is responsible."""
- alternates_path = join(self.git_dir, 'objects', 'info', 'alternates')
+ alternates_path = osp.join(self.git_dir, 'objects', 'info', 'alternates')
if not alts:
- if isfile(alternates_path):
+ if osp.isfile(alternates_path):
os.remove(alternates_path)
else:
with open(alternates_path, 'wb') as f:
@@ -605,7 +581,7 @@ class Repo(object):
default_args.append(path)
if index:
# diff index against HEAD
- if isfile(self.index.path) and \
+ if osp.isfile(self.index.path) and \
len(self.git.diff('--cached', *default_args)):
return True
# END index handling
@@ -865,7 +841,7 @@ class Repo(object):
:return: ``git.Repo`` (the newly created repo)"""
if path:
path = _expand_path(path)
- if mkdir and path and not os.path.exists(path):
+ if mkdir and path and not osp.exists(path):
os.makedirs(path, 0o755)
# git command automatically chdir into the directory
@@ -879,19 +855,32 @@ class Repo(object):
progress = to_progress_instance(progress)
odbt = kwargs.pop('odbt', odb_default_type)
- proc = git.clone(url, path, with_extended_output=True, as_process=True,
+
+ ## A bug win cygwin's Git, when `--bare` or `--separate-git-dir`
+ # it prepends the cwd or(?) the `url` into the `path, so::
+ # git clone --bare /cygwin/d/foo.git C:\\Work
+ # becomes::
+ # git clone --bare /cygwin/d/foo.git /cygwin/d/C:\\Work
+ #
+ clone_path = (Git.polish_url(path)
+ if Git.is_cygwin() and 'bare'in kwargs
+ else path)
+ sep_dir = kwargs.get('separate_git_dir')
+ if sep_dir:
+ kwargs['separate_git_dir'] = Git.polish_url(sep_dir)
+ proc = git.clone(Git.polish_url(url), clone_path, with_extended_output=True, as_process=True,
v=True, **add_progress(kwargs, git, progress))
if progress:
handle_process_output(proc, None, progress.new_message_handler(), finalize_process)
else:
- (stdout, stderr) = proc.communicate() # FIXME: Will block of outputs are big!
+ (stdout, stderr) = proc.communicate() # FIXME: Will block if outputs are big!
log.debug("Cmd(%s)'s unused stdout: %s", getattr(proc, 'args', ''), stdout)
finalize_process(proc, stderr=stderr)
# our git command could have a different working dir than our actual
# environment, hence we prepend its working dir if required
- if not os.path.isabs(path) and git.working_dir:
- path = join(git._working_dir, path)
+ if not osp.isabs(path) and git.working_dir:
+ path = osp.join(git._working_dir, path)
# adjust remotes - there may be operating systems which use backslashes,
# These might be given as initial paths, but when handling the config file
@@ -969,7 +958,7 @@ class Repo(object):
"""
if self.bare:
return False
- return os.path.isfile(os.path.join(self.working_tree_dir, '.git'))
+ return osp.isfile(osp.join(self.working_tree_dir, '.git'))
rev_parse = rev_parse