summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--git/exc.py4
-rw-r--r--git/repo/fun.py25
-rw-r--r--git/test/test_repo.py20
3 files changed, 39 insertions, 10 deletions
diff --git a/git/exc.py b/git/exc.py
index f5b52374..34382ecd 100644
--- a/git/exc.py
+++ b/git/exc.py
@@ -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)