diff options
Diffstat (limited to 'git')
| -rw-r--r-- | git/refs/remote.py | 4 | ||||
| -rw-r--r-- | git/refs/symbolic.py | 44 | ||||
| -rw-r--r-- | git/remote.py | 2 | ||||
| -rw-r--r-- | git/repo/base.py | 22 | ||||
| -rw-r--r-- | git/test/test_repo.py | 2 | 
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"""  | 
