summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2010-11-16 09:30:10 +0100
committerSebastian Thiel <byronimo@gmail.com>2010-11-16 09:30:10 +0100
commitaf5abca21b56fcf641ff916bd567680888c364aa (patch)
tree72503602d20646502e287f2d33c21d68dbebd530
parentd4fd7fca515ba9b088a7c811292f76f47d16cd7b (diff)
downloadgitpython-af5abca21b56fcf641ff916bd567680888c364aa.tar.gz
Added a few utility methods and improved the test. Refs need an improvement though to allow easy configuration of branch-specific settings
-rw-r--r--lib/git/objects/submodule.py60
-rw-r--r--test/git/test_submodule.py21
2 files changed, 64 insertions, 17 deletions
diff --git a/lib/git/objects/submodule.py b/lib/git/objects/submodule.py
index 86aba49c..d58e07a9 100644
--- a/lib/git/objects/submodule.py
+++ b/lib/git/objects/submodule.py
@@ -251,6 +251,17 @@ class Submodule(base.IndexObject, Iterable, Traversable):
local_branch = git.Head(mrepo, git.Head.to_full_path(self.branch))
if not local_branch.is_valid():
mrepo.git.checkout(remote_branch, b=self.branch)
+ else:
+ # have a valid branch, but no checkout - make sure we can figure
+ # that out by marking the commit with a null_sha
+ # have to write it directly as .commit = NULLSHA tries to resolve the sha
+ ref = mrepo.head.ref
+ refpath = join_path_native(mrepo.git_dir, ref.to_full_path(ref.path))
+ refdir = os.path.dirname(refpath)
+ if not os.path.isdir(refdir):
+ os.makedirs(refdir)
+ #END handle directory
+ open(refpath, 'w').write(self.NULL_HEX_SHA)
# END initial checkout + branch creation
# make sure we are not detached
mrepo.head.ref = local_branch
@@ -259,24 +270,24 @@ class Submodule(base.IndexObject, Iterable, Traversable):
#END handle tracking branch
#END handle initalization
- # if the commit to checkout is on the current branch, merge the branch
- if mrepo.head.is_detached:
- if mrepo.head.commit.binsha != self.binsha:
+ # update the working tree
+ if mrepo.head.commit.binsha != self.binsha:
+ if mrepo.head.is_detached:
mrepo.git.checkout(self.hexsha)
- # END checkout commit
- else:
- # TODO: allow to specify a rebase, merge, or reset
- # TODO: Warn if the hexsha forces the tracking branch off the remote
- # branch - this should be prevented when setting the branch option
- mrepo.head.reset(self.hexsha, index=True, working_tree=True)
- # END handle checkout
-
- if recursive:
- for submodule in self.iter_items(self.module()):
- submodule.update(recursive, init)
- # END handle recursive update
- # END for each submodule
-
+ else:
+ # TODO: allow to specify a rebase, merge, or reset
+ # TODO: Warn if the hexsha forces the tracking branch off the remote
+ # branch - this should be prevented when setting the branch option
+ mrepo.head.reset(self.hexsha, index=True, working_tree=True)
+ # END handle checkout
+
+ if recursive:
+ for submodule in self.iter_items(self.module()):
+ submodule.update(recursive, init)
+ # END handle recursive update
+ # END for each submodule
+ # END update to new commit only if needed
+
return self
def set_parent_commit(self, commit, check=True):
@@ -354,6 +365,15 @@ class Submodule(base.IndexObject, Iterable, Traversable):
def module_path(self):
""":return: full path to the root of our module. It is relative to the filesystem root"""
return join_path_native(self.repo.working_tree_dir, self.path)
+
+ def module_exists(self):
+ """:return: True if our module exists and is a valid git repository. See module() method"""
+ try:
+ self.module()
+ return True
+ except InvalidGitRepositoryError:
+ return False
+ # END handle exception
@property
def branch(self):
@@ -391,6 +411,12 @@ class Submodule(base.IndexObject, Iterable, Traversable):
:raise IOError: If the .gitmodules file/blob could not be read"""
return self._config_parser_constrained(read_only=True)
+ def children(self):
+ """:return: IterableList(Submodule, ...) an iterable list of submodules instances
+ which are children of this submodule
+ :raise InvalidGitRepositoryError: if the submodule is not checked-out"""
+ return self._get_intermediate_items(self)
+
#} END query interface
#{ Iterable Interface
diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py
index 79413a9c..5b1cad6c 100644
--- a/test/git/test_submodule.py
+++ b/test/git/test_submodule.py
@@ -88,6 +88,10 @@ class TestSubmodule(TestBase):
else:
# its not checked out in our case
self.failUnlessRaises(InvalidGitRepositoryError, sm.module)
+ assert not sm.module_exists()
+
+ # currently there is only one submodule
+ assert len(list(rwrepo.iter_submodules())) == 1
# lets update it - its a recursive one too
newdir = os.path.join(sm.module_path(), 'dir')
@@ -98,12 +102,29 @@ class TestSubmodule(TestBase):
os.rmdir(newdir)
assert sm.update() is sm
+ assert sm.module_exists()
assert isinstance(sm.module(), git.Repo)
assert sm.module().working_tree_dir == sm.module_path()
# delete the whole directory and re-initialize
shutil.rmtree(sm.module_path())
+ sm.update(recursive=False)
+ assert len(list(rwrepo.iter_submodules())) == 2
+ assert len(sm.children()) == 1 # its not checked out yet
+ csm = sm.children()[0]
+ assert not csm.module_exists()
+
+ # adjust the path of the submodules module to point to the local destination
+ new_csm_path = to_native_path_linux(join_path_native(self.rorepo.working_tree_dir, sm.path, csm.path))
+ csm.config_writer().set_value('url', new_csm_path)
+ assert csm.url == new_csm_path
+
+
+ # update recuesively again
sm.update(recursive=True)
+
+ # this flushed in a sub-submodule
+ assert len(list(rwrepo.iter_submodules())) == 2
# END handle bare mode