summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2010-11-15 22:12:05 +0100
committerSebastian Thiel <byronimo@gmail.com>2010-11-15 22:12:05 +0100
commitceee7d7e0d98db12067744ac3cd0ab3a49602457 (patch)
tree61325f8bcb9b5849413abcdb8adba4c9cb410a44
parent624556eae1c292a1dc283d9dca1557e28abe8ee3 (diff)
downloadgitpython-ceee7d7e0d98db12067744ac3cd0ab3a49602457.tar.gz
Added partial implementation of update, but realized that using refs in general may be contradicting if a tag is given there, as well as a commit sha of the submodule. Hence it should really be only a branch
-rw-r--r--lib/git/objects/submodule.py60
-rw-r--r--lib/git/refs.py2
-rw-r--r--test/git/test_submodule.py6
3 files changed, 65 insertions, 3 deletions
diff --git a/lib/git/objects/submodule.py b/lib/git/objects/submodule.py
index eda95115..12610abd 100644
--- a/lib/git/objects/submodule.py
+++ b/lib/git/objects/submodule.py
@@ -56,6 +56,7 @@ class Submodule(base.IndexObject, Iterable, Traversable):
def __init__(self, repo, binsha, mode=None, path=None, name = None, parent_commit=None, url=None, ref=None):
"""Initialize this instance with its attributes. We only document the ones
that differ from ``IndexObject``
+ :param repo: Our parent repository
:param binsha: binary sha referring to a commit in the remote repository, see url parameter
:param parent_commit: see set_parent_commit()
:param url: The url to the remote repository which is the submodule
@@ -105,6 +106,10 @@ class Submodule(base.IndexObject, Iterable, Traversable):
"""Compare with another submodule for inequality"""
return not (self == other)
+ def __hash__(self):
+ """Hash this instance using its logical id, not the sha"""
+ return hash(self._name)
+
@classmethod
def _config_parser(cls, repo, parent_commit, read_only):
""":return: Config Parser constrained to our submodule in read or write mode
@@ -159,6 +164,57 @@ class Submodule(base.IndexObject, Iterable, Traversable):
:param skip_init: if True, the new repository will not be cloned to its location.
:return: The newly created submodule instance"""
+ def update(self, recursive=False, init=True):
+ """Update the repository of this submodule to point to the checkout
+ we point at with the binsha of this instance.
+ :param recursive: if True, we will operate recursively and update child-
+ modules as well.
+ :param init: if True, the module repository will be cloned into place if necessary
+ :note: does nothing in bare repositories
+ :return: self"""
+ if self.repo.bare:
+ return self
+ #END pass in bare mode
+
+ try:
+ mrepo = self.module()
+ except InvalidGitRepositoryError:
+ if not init:
+ return self
+ # END early abort if init is not allowed
+ import git
+
+ # there is no git-repository yet - but delete empty paths
+ module_path = join_path_native(self.repo.working_tree_dir, self.path)
+ if os.path.isdir(module_path):
+ try:
+ os.rmdir(module_path)
+ except OSError:
+ raise OSError("Module directory at %r does already exist and is non-empty" % module_path)
+ # END handle OSError
+ # END handle directory removal
+
+ # don't check it out at first
+ mrepo = git.Repo.clone_from(self.url, self.path, n=True)
+ # ref can be a tag or a branch - we can checkout branches, but not tags
+ # tag_ref = git.TagReference(mrepo, TagReference.to_full_path(self.ref))
+ if tag_ref.is_valid():
+ #if tag_ref.commit
+ mrepo.git.checkout(tag_ref)
+ else:
+ # assume it is a branch and try it
+ mrepo.git.checkout(self.hexsha, b=self.ref)
+ #if mrepo.head.ref.name != self.ref:
+ # mrepo.head.ref = git.Head(mrepo, git.Head.to_full_path(self.ref
+ #END handle initalization
+
+ # TODO: handle ref-path
+ if mrepo.head.commit.binsha != self.binsha:
+ mrepo.git.checkout(self.binsha)
+ # END handle checkout
+
+ return self
+
def set_parent_commit(self, commit, check=True):
"""Set this instance to use the given commit whose tree is supposed to
contain the .gitmodules blob.
@@ -167,7 +223,8 @@ class Submodule(base.IndexObject, Iterable, Traversable):
validity of the submodule.
:raise ValueError: if the commit's tree didn't contain the .gitmodules blob.
:raise ValueError: if the parent commit didn't store this submodule under the
- current path"""
+ current path
+ :return: self"""
pcommit = self.repo.commit(commit)
pctree = pcommit.tree
if self.k_modules_file not in pctree:
@@ -196,6 +253,7 @@ class Submodule(base.IndexObject, Iterable, Traversable):
pass
# END try attr deletion
# END for each name to delete
+ return self
def config_writer(self):
""":return: a config writer instance allowing you to read and write the data
diff --git a/lib/git/refs.py b/lib/git/refs.py
index af7284ff..3dc73d03 100644
--- a/lib/git/refs.py
+++ b/lib/git/refs.py
@@ -489,6 +489,8 @@ class SymbolicReference(object):
@classmethod
def from_path(cls, repo, path):
"""
+ :param path: full .git-directory-relative path name to the Reference to instantiate
+ :note: use to_full_path() if you only have a partial path of a known Reference Type
:return:
Instance of type Reference, Head, or Tag
depending on the given path"""
diff --git a/test/git/test_submodule.py b/test/git/test_submodule.py
index ac179c22..f015ad7f 100644
--- a/test/git/test_submodule.py
+++ b/test/git/test_submodule.py
@@ -51,7 +51,7 @@ class TestSubmodule(TestBase):
# make the old into a new
prev_parent_commit = smold.parent_commit
- smold.set_parent_commit(self.k_subm_current)
+ assert smold.set_parent_commit(self.k_subm_current) is smold
assert smold.parent_commit != prev_parent_commit
assert smold.binsha == sm.binsha
smold.set_parent_commit(prev_parent_commit)
@@ -70,7 +70,9 @@ class TestSubmodule(TestBase):
# its not checked out in our case
self.failUnlessRaises(InvalidGitRepositoryError, sm.module)
- # lets do it - its a recursive one too
+ # lets update it - its a recursive one too
+ # update fails if the path already exists non-empty
+ # self.failUnlessRaises(
# delete the whole directory and re-initialize
# END handle bare mode