diff options
-rw-r--r-- | git/exc.py | 4 | ||||
-rw-r--r-- | git/repo/fun.py | 25 | ||||
-rw-r--r-- | git/test/test_repo.py | 20 |
3 files changed, 39 insertions, 10 deletions
@@ -14,6 +14,10 @@ class InvalidGitRepositoryError(Exception): """ Thrown if the given repository appears to have an invalid format. """ +class WorkTreeRepositoryUnsupported(InvalidGitRepositoryError): + """ Thrown to indicate we can't handle work tree repositories """ + + class NoSuchPathError(OSError): """ Thrown if a path could not be access by the system. """ diff --git a/git/repo/fun.py b/git/repo/fun.py index 049800b9..6b06663a 100644 --- a/git/repo/fun.py +++ b/git/repo/fun.py @@ -4,7 +4,7 @@ from string import digits from gitdb.exc import ( BadObject, - BadName + BadName, ) from git.refs import SymbolicReference from git.objects import Object @@ -16,6 +16,7 @@ from gitdb.util import ( hex_to_bin, bin_to_hex ) +from git.exc import WorkTreeRepositoryUnsupported from git.compat import xrange @@ -31,14 +32,20 @@ def touch(filename): def is_git_dir(d): """ This is taken from the git setup.c:is_git_directory - function.""" - if isdir(d) and \ - isdir(join(d, 'objects')) and \ - isdir(join(d, 'refs')): - headref = join(d, 'HEAD') - return isfile(headref) or \ - (os.path.islink(headref) and - os.readlink(headref).startswith('refs')) + function. + + @throws WorkTreeRepositoryUnsupported if it sees a worktree directory. It's quite hacky to do that here, + but at least clearly indicates that we don't support it. + There is the unlikely danger to throw if we see directories which just look like a worktree dir, + but are none.""" + if isdir(d): + if isdir(join(d, 'objects')) and isdir(join(d, 'refs')): + headref = join(d, 'HEAD') + return isfile(headref) or \ + (os.path.islink(headref) and + os.readlink(headref).startswith('refs')) + elif isfile(join(d, 'gitdir')) and isfile(join(d, 'commondir')) and isfile(join(d, 'gitfile')): + raise WorkTreeRepositoryUnsupported(d) return False diff --git a/git/test/test_repo.py b/git/test/test_repo.py index c95592ea..2e44f0aa 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -33,7 +33,10 @@ from git import ( ) from git.repo.fun import touch from git.util import join_path_native -from git.exc import BadObject +from git.exc import ( + BadObject, + WorkTreeRepositoryUnsupported +) from gitdb.util import bin_to_hex from git.compat import string_types from gitdb.test.lib import with_rw_directory @@ -45,6 +48,8 @@ import shutil import itertools from io import BytesIO +from nose import SkipTest + class TestRepo(TestBase): @@ -779,3 +784,16 @@ class TestRepo(TestBase): self.assertFalse(repo.is_ancestor("master", c1)) for i, j in itertools.permutations([c1, 'ffffff', ''], r=2): self.assertRaises(GitCommandError, repo.is_ancestor, i, j) + + @with_rw_directory + def test_work_tree_unsupported(self, rw_dir): + git = Git(rw_dir) + if git.version_info[:3] < (2, 5, 1): + raise SkipTest("worktree feature unsupported") + + rw_master = self.rorepo.clone(join_path_native(rw_dir, 'master_repo')) + rw_master.git.checkout('HEAD~10') + worktree_path = join_path_native(rw_dir, 'worktree_repo') + rw_master.git.worktree('add', worktree_path, 'master') + + self.failUnlessRaises(WorkTreeRepositoryUnsupported, Repo, worktree_path) |