aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2015-01-16 17:43:52 +0100
committerSebastian Thiel <byronimo@gmail.com>2015-01-16 17:43:52 +0100
commit503b62bd76ee742bd18a1803dac76266fa8901bc (patch)
tree4e703edaa7a63f3ab33c28dbf53af5ccced337c2
parenta9a5414300a245b6e93ea4f39fbca792c3ec753f (diff)
downloadGitPython-503b62bd76ee742bd18a1803dac76266fa8901bc.tar.gz
GitPython-503b62bd76ee742bd18a1803dac76266fa8901bc.zip
Implemented more tests and made use of .git files when adding submodules
There is some more work to do, as renames and updates still have to be adjusted accordinlgy. Relates #233
-rw-r--r--git/objects/submodule/base.py39
-rw-r--r--git/test/test_submodule.py48
2 files changed, 79 insertions, 8 deletions
diff --git a/git/objects/submodule/base.py b/git/objects/submodule/base.py
index e055cb8c..13183e29 100644
--- a/git/objects/submodule/base.py
+++ b/git/objects/submodule/base.py
@@ -127,6 +127,10 @@ class Submodule(util.IndexObject, Iterable, Traversable):
return list()
# END handle intermeditate items
+ @classmethod
+ def _need_gitfile_submodules(cls, git):
+ return git.version_info[:3] >= (1, 8, 0)
+
def __eq__(self, other):
"""Compare with another submodule"""
# we may only compare by name as this should be the ID they are hashed with
@@ -157,9 +161,7 @@ class Submodule(util.IndexObject, Iterable, Traversable):
access of the config parser"""
parent_matches_head = repo.head.commit == parent_commit
if not repo.bare and parent_matches_head:
- fp_module = cls.k_modules_file
- fp_module_path = os.path.join(repo.working_tree_dir, fp_module)
- fp_module = fp_module_path
+ fp_module = os.path.join(repo.working_tree_dir, cls.k_modules_file)
else:
try:
fp_module = cls._sio_modules(parent_commit)
@@ -198,6 +200,23 @@ class Submodule(util.IndexObject, Iterable, Traversable):
parser.set_submodule(self)
return SectionConstraint(parser, sm_section(self.name))
+ @classmethod
+ def _module_abspath(cls, parent_repo, path, name):
+ if cls._need_gitfile_submodules(parent_repo.git):
+ return os.path.join(parent_repo.git_dir, 'modules', name)
+ else:
+ return os.path.join(parent_repo.working_tree_dir, path)
+ # end
+
+ @classmethod
+ def _write_git_file(cls, working_tree_dir, module_abspath, overwrite_existing=False):
+ """Writes a .git file containing a (preferably) relative path to the actual git module repository.
+ It is an error if the module_abspath cannot be made into a relative path, relative to the working_tree_dir
+ :param working_tree_dir: directory to write the .git file into
+ :param module_abspath: absolute path to the bare repository
+ :param overwrite_existing: if True, we may rewrite existing .git files, otherwise we raise"""
+ raise NotImplementedError
+
#{ Edit Interface
@classmethod
@@ -298,7 +317,17 @@ class Submodule(util.IndexObject, Iterable, Traversable):
if not branch_is_default:
kwargs['b'] = br.name
# END setup checkout-branch
- mrepo = git.Repo.clone_from(url, os.path.join(repo.working_tree_dir, path), **kwargs)
+ module_abspath = cls._module_abspath(repo, path, name)
+ module_checkout_path = module_abspath
+ if cls._need_gitfile_submodules(repo.git):
+ kwargs['separate_git_dir'] = module_abspath
+ module_abspath_dir = os.path.dirname(module_abspath)
+ if not os.path.isdir(module_abspath_dir):
+ os.makedirs(module_abspath_dir)
+ module_checkout_path = os.path.join(repo.working_tree_dir, path)
+ # end
+
+ mrepo = git.Repo.clone_from(url, module_checkout_path, **kwargs)
# END verify url
# update configuration and index
@@ -390,7 +419,7 @@ class Submodule(util.IndexObject, Iterable, Traversable):
import git
# there is no git-repository yet - but delete empty paths
- module_path = join_path_native(self.repo.working_tree_dir, self.path)
+ module_path = self._module_abspath(self.repo, self.path, self.name)
if not dry_run and os.path.isdir(module_path):
try:
os.rmdir(module_path)
diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py
index 3e3a97d8..484e73ae 100644
--- a/git/test/test_submodule.py
+++ b/git/test/test_submodule.py
@@ -16,6 +16,7 @@ from git.objects.submodule.base import Submodule
from git.objects.submodule.root import RootModule, RootUpdateProgress
from git.util import to_native_path_linux, join_path_native
from git.compat import string_types
+from git.repo.fun import find_git_dir
from nose import SkipTest
@@ -602,11 +603,9 @@ class TestSubmodule(TestBase):
@with_rw_directory
def test_add_empty_repo(self, rwdir):
- parent_dir = os.path.join(rwdir, 'parent')
- os.mkdir(parent_dir)
empty_repo_dir = os.path.join(rwdir, 'empty-repo')
- parent = git.Repo.init(parent_dir)
+ parent = git.Repo.init(os.path.join(rwdir, 'parent'))
git.Repo.init(empty_repo_dir)
for checkout_mode in range(2):
@@ -614,3 +613,46 @@ class TestSubmodule(TestBase):
self.failUnlessRaises(ValueError, parent.create_submodule, name, name,
url=empty_repo_dir, no_checkout=checkout_mode and True or False)
# end for each checkout mode
+
+ def _submodule_url(self):
+ return os.path.join(self.rorepo.working_tree_dir, 'git/ext/gitdb/gitdb/ext/smmap')
+
+ @with_rw_directory
+ def test_git_submodules(self, rwdir):
+ parent = git.Repo.init(os.path.join(rwdir, 'parent'))
+ parent.git.submodule('add', self._submodule_url(), 'module')
+ parent.index.commit("added submodule")
+
+ assert len(parent.submodules) == 1
+ sm = parent.submodules[0]
+
+ assert sm.exists() and sm.module_exists()
+
+ # test move and rename
+ # TODO
+
+ @with_rw_directory
+ def test_git_submodule_compatibility(self, rwdir):
+ parent = git.Repo.init(os.path.join(rwdir, 'parent'))
+ empty_file = os.path.join(parent.working_tree_dir, "empty")
+ with open(empty_file, 'wb') as fp:
+ fp.close()
+ parent.index.add([empty_file])
+ parent.index.commit("initial commit - can't yet add submodules to empty parent dir")
+
+ sm_path = 'submodules/intermediate/one'
+ sm = parent.create_submodule('mymodules/myname', sm_path, url=self._submodule_url())
+ parent.index.commit("added submodule")
+
+ # As git is backwards compatible itself, it would still recognize what we do here ... unless we really
+ # muss it up. That's the only reason why the test is still here ... .
+ assert len(parent.git.submodule().splitlines()) == 1
+
+ module_repo_path = os.path.join(sm.module().working_tree_dir, '.git')
+ assert module_repo_path.startswith(os.path.join(parent.working_tree_dir, sm_path))
+ if not sm._need_gitfile_submodules(parent.git):
+ assert os.path.isdir(module_repo_path)
+ else:
+ assert os.path.isfile(module_repo_path)
+ assert find_git_dir(module_repo_path) is not None, "module pointed to by .git file must be valid"
+ # end verify submodule 'style'