Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ceee7d7

Browse files
committed
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
1 parent 624556e commit ceee7d7

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

lib/git/objects/submodule.py

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class Submodule(base.IndexObject, Iterable, Traversable):
5656
def __init__(self, repo, binsha, mode=None, path=None, name = None, parent_commit=None, url=None, ref=None):
5757
"""Initialize this instance with its attributes. We only document the ones
5858
that differ from ``IndexObject``
59+
:param repo: Our parent repository
5960
:param binsha: binary sha referring to a commit in the remote repository, see url parameter
6061
:param parent_commit: see set_parent_commit()
6162
:param url: The url to the remote repository which is the submodule
@@ -105,6 +106,10 @@ def __ne__(self, other):
105106
"""Compare with another submodule for inequality"""
106107
return not (self == other)
107108

109+
def __hash__(self):
110+
"""Hash this instance using its logical id, not the sha"""
111+
return hash(self._name)
112+
108113
@classmethod
109114
def _config_parser(cls, repo, parent_commit, read_only):
110115
""":return: Config Parser constrained to our submodule in read or write mode
@@ -159,6 +164,57 @@ def add(cls, repo, path, url, skip_init=False):
159164
:param skip_init: if True, the new repository will not be cloned to its location.
160165
:return: The newly created submodule instance"""
161166

167+
def update(self, recursive=False, init=True):
168+
"""Update the repository of this submodule to point to the checkout
169+
we point at with the binsha of this instance.
170+
:param recursive: if True, we will operate recursively and update child-
171+
modules as well.
172+
:param init: if True, the module repository will be cloned into place if necessary
173+
:note: does nothing in bare repositories
174+
:return: self"""
175+
if self.repo.bare:
176+
return self
177+
#END pass in bare mode
178+
179+
try:
180+
mrepo = self.module()
181+
except InvalidGitRepositoryError:
182+
if not init:
183+
return self
184+
# END early abort if init is not allowed
185+
import git
186+
187+
# there is no git-repository yet - but delete empty paths
188+
module_path = join_path_native(self.repo.working_tree_dir, self.path)
189+
if os.path.isdir(module_path):
190+
try:
191+
os.rmdir(module_path)
192+
except OSError:
193+
raise OSError("Module directory at %r does already exist and is non-empty" % module_path)
194+
# END handle OSError
195+
# END handle directory removal
196+
197+
# don't check it out at first
198+
mrepo = git.Repo.clone_from(self.url, self.path, n=True)
199+
# ref can be a tag or a branch - we can checkout branches, but not tags
200+
# tag_ref = git.TagReference(mrepo, TagReference.to_full_path(self.ref))
201+
if tag_ref.is_valid():
202+
#if tag_ref.commit
203+
mrepo.git.checkout(tag_ref)
204+
else:
205+
# assume it is a branch and try it
206+
mrepo.git.checkout(self.hexsha, b=self.ref)
207+
#if mrepo.head.ref.name != self.ref:
208+
# mrepo.head.ref = git.Head(mrepo, git.Head.to_full_path(self.ref
209+
#END handle initalization
210+
211+
# TODO: handle ref-path
212+
if mrepo.head.commit.binsha != self.binsha:
213+
mrepo.git.checkout(self.binsha)
214+
# END handle checkout
215+
216+
return self
217+
162218
def set_parent_commit(self, commit, check=True):
163219
"""Set this instance to use the given commit whose tree is supposed to
164220
contain the .gitmodules blob.
@@ -167,7 +223,8 @@ def set_parent_commit(self, commit, check=True):
167223
validity of the submodule.
168224
:raise ValueError: if the commit's tree didn't contain the .gitmodules blob.
169225
:raise ValueError: if the parent commit didn't store this submodule under the
170-
current path"""
226+
current path
227+
:return: self"""
171228
pcommit = self.repo.commit(commit)
172229
pctree = pcommit.tree
173230
if self.k_modules_file not in pctree:
@@ -196,6 +253,7 @@ def set_parent_commit(self, commit, check=True):
196253
pass
197254
# END try attr deletion
198255
# END for each name to delete
256+
return self
199257

200258
def config_writer(self):
201259
""":return: a config writer instance allowing you to read and write the data

lib/git/refs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,8 @@ def iter_items(cls, repo, common_path = None):
489489
@classmethod
490490
def from_path(cls, repo, path):
491491
"""
492+
:param path: full .git-directory-relative path name to the Reference to instantiate
493+
:note: use to_full_path() if you only have a partial path of a known Reference Type
492494
:return:
493495
Instance of type Reference, Head, or Tag
494496
depending on the given path"""

test/git/test_submodule.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def _do_base_tests(self, rwrepo):
5151

5252
# make the old into a new
5353
prev_parent_commit = smold.parent_commit
54-
smold.set_parent_commit(self.k_subm_current)
54+
assert smold.set_parent_commit(self.k_subm_current) is smold
5555
assert smold.parent_commit != prev_parent_commit
5656
assert smold.binsha == sm.binsha
5757
smold.set_parent_commit(prev_parent_commit)
@@ -70,7 +70,9 @@ def _do_base_tests(self, rwrepo):
7070
# its not checked out in our case
7171
self.failUnlessRaises(InvalidGitRepositoryError, sm.module)
7272

73-
# lets do it - its a recursive one too
73+
# lets update it - its a recursive one too
74+
# update fails if the path already exists non-empty
75+
# self.failUnlessRaises(
7476

7577
# delete the whole directory and re-initialize
7678
# END handle bare mode

0 commit comments

Comments
 (0)