summaryrefslogtreecommitdiff
path: root/git
diff options
context:
space:
mode:
Diffstat (limited to 'git')
-rw-r--r--git/refs/remote.py4
-rw-r--r--git/refs/symbolic.py44
-rw-r--r--git/remote.py2
-rw-r--r--git/repo/base.py22
-rw-r--r--git/test/test_repo.py2
5 files changed, 45 insertions, 29 deletions
diff --git a/git/refs/remote.py b/git/refs/remote.py
index ef69b5db..0164e110 100644
--- a/git/refs/remote.py
+++ b/git/refs/remote.py
@@ -37,6 +37,10 @@ class RemoteReference(Head):
# and delete remainders manually
for ref in refs:
try:
+ os.remove(osp.join(repo.common_dir, ref.path))
+ except OSError:
+ pass
+ try:
os.remove(osp.join(repo.git_dir, ref.path))
except OSError:
pass
diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py
index 90ecb62c..bef6ba3c 100644
--- a/git/refs/symbolic.py
+++ b/git/refs/symbolic.py
@@ -26,6 +26,14 @@ from .log import RefLog
__all__ = ["SymbolicReference"]
+def _git_dir(repo, path):
+ """ Find the git dir that's appropriate for the path"""
+ name = "%s" % (path,)
+ if name in ['HEAD', 'ORIG_HEAD', 'FETCH_HEAD', 'index', 'logs']:
+ return repo.git_dir
+ return repo.common_dir
+
+
class SymbolicReference(object):
"""Represents a special case of a reference such that this reference is symbolic.
@@ -71,16 +79,11 @@ class SymbolicReference(object):
@property
def abspath(self):
- return join_path_native(self.repo.git_dir, self.path)
+ return join_path_native(_git_dir(self.repo, self.path), self.path)
@classmethod
def _get_packed_refs_path(cls, repo):
- try:
- commondir = open(osp.join(repo.git_dir, 'commondir'), 'rt').readlines()[0].strip()
- except (OSError, IOError):
- commondir = '.'
- repodir = osp.join(repo.git_dir, commondir)
- return osp.join(repodir, 'packed-refs')
+ return osp.join(repo.common_dir, 'packed-refs')
@classmethod
def _iter_packed_refs(cls, repo):
@@ -127,11 +130,12 @@ class SymbolicReference(object):
# END recursive dereferencing
@classmethod
- def _get_ref_info_helper(cls, repo, repodir, ref_path):
+ def _get_ref_info_helper(cls, repo, ref_path):
"""Return: (str(sha), str(target_ref_path)) if available, the sha the file at
rela_path points to, or None. target_ref_path is the reference we
point to, or None"""
tokens = None
+ repodir = _git_dir(repo, ref_path)
try:
with open(osp.join(repodir, ref_path), 'rt') as fp:
value = fp.read().rstrip()
@@ -169,16 +173,7 @@ class SymbolicReference(object):
"""Return: (str(sha), str(target_ref_path)) if available, the sha the file at
rela_path points to, or None. target_ref_path is the reference we
point to, or None"""
- try:
- return cls._get_ref_info_helper(repo, repo.git_dir, ref_path)
- except ValueError:
- try:
- commondir = open(osp.join(repo.git_dir, 'commondir'), 'rt').readlines()[0].strip()
- except (OSError, IOError):
- commondir = '.'
-
- repodir = osp.join(repo.git_dir, commondir)
- return cls._get_ref_info_helper(repo, repodir, ref_path)
+ return cls._get_ref_info_helper(repo, ref_path)
def _get_object(self):
"""
@@ -433,7 +428,7 @@ class SymbolicReference(object):
or just "myreference", hence 'refs/' is implied.
Alternatively the symbolic reference to be deleted"""
full_ref_path = cls.to_full_path(path)
- abs_path = osp.join(repo.git_dir, full_ref_path)
+ abs_path = osp.join(repo.common_dir, full_ref_path)
if osp.exists(abs_path):
os.remove(abs_path)
else:
@@ -484,8 +479,9 @@ class SymbolicReference(object):
a proper symbolic reference. Otherwise it will be resolved to the
corresponding object and a detached symbolic reference will be created
instead"""
+ git_dir = _git_dir(repo, path)
full_ref_path = cls.to_full_path(path)
- abs_ref_path = osp.join(repo.git_dir, full_ref_path)
+ abs_ref_path = osp.join(git_dir, full_ref_path)
# figure out target data
target = reference
@@ -559,8 +555,8 @@ class SymbolicReference(object):
if self.path == new_path:
return self
- new_abs_path = osp.join(self.repo.git_dir, new_path)
- cur_abs_path = osp.join(self.repo.git_dir, self.path)
+ new_abs_path = osp.join(_git_dir(self.repo, new_path), new_path)
+ cur_abs_path = osp.join(_git_dir(self.repo, self.path), self.path)
if osp.isfile(new_abs_path):
if not force:
# if they point to the same file, its not an error
@@ -594,7 +590,7 @@ class SymbolicReference(object):
# walk loose refs
# Currently we do not follow links
- for root, dirs, files in os.walk(join_path_native(repo.git_dir, common_path)):
+ for root, dirs, files in os.walk(join_path_native(repo.common_dir, common_path)):
if 'refs' not in root.split(os.sep): # skip non-refs subfolders
refs_id = [d for d in dirs if d == 'refs']
if refs_id:
@@ -605,7 +601,7 @@ class SymbolicReference(object):
if f == 'packed-refs':
continue
abs_path = to_native_path_linux(join_path(root, f))
- rela_paths.add(abs_path.replace(to_native_path_linux(repo.git_dir) + '/', ""))
+ rela_paths.add(abs_path.replace(to_native_path_linux(repo.common_dir) + '/', ""))
# END for each file in root directory
# END for each directory to walk
diff --git a/git/remote.py b/git/remote.py
index fd76e592..29c7ed92 100644
--- a/git/remote.py
+++ b/git/remote.py
@@ -652,7 +652,7 @@ class Remote(LazyMixin, Iterable):
continue
# read head information
- with open(osp.join(self.repo.git_dir, 'FETCH_HEAD'), 'rb') as fp:
+ with open(osp.join(self.repo.common_dir, 'FETCH_HEAD'), 'rb') as fp:
fetch_head_info = [l.decode(defenc) for l in fp.readlines()]
l_fil = len(fetch_info_lines)
diff --git a/git/repo/base.py b/git/repo/base.py
index 28bb2a5d..d607deee 100644
--- a/git/repo/base.py
+++ b/git/repo/base.py
@@ -74,6 +74,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+')
@@ -169,17 +170,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 +244,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 +588,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)
@@ -932,7 +946,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):
diff --git a/git/test/test_repo.py b/git/test/test_repo.py
index a6be4e66..312e67f9 100644
--- a/git/test/test_repo.py
+++ b/git/test/test_repo.py
@@ -935,6 +935,8 @@ class TestRepo(TestBase):
commit = repo.head.commit
self.assertIsInstance(commit, Object)
+ self.assertIsInstance(repo.heads['aaaaaaaa'], Head)
+
@with_rw_directory
def test_git_work_tree_env(self, rw_dir):
"""Check that we yield to GIT_WORK_TREE"""