@@ -56,6 +56,7 @@ class Submodule(base.IndexObject, Iterable, Traversable):
56
56
def __init__ (self ,repo ,binsha ,mode = None ,path = None ,name = None ,parent_commit = None ,url = None ,ref = None ):
57
57
"""Initialize this instance with its attributes. We only document the ones
58
58
that differ from ``IndexObject``
59
+ :param repo: Our parent repository
59
60
:param binsha: binary sha referring to a commit in the remote repository, see url parameter
60
61
:param parent_commit: see set_parent_commit()
61
62
:param url: The url to the remote repository which is the submodule
@@ -105,6 +106,10 @@ def __ne__(self, other):
105
106
"""Compare with another submodule for inequality"""
106
107
return not (self == other )
107
108
109
+ def __hash__ (self ):
110
+ """Hash this instance using its logical id, not the sha"""
111
+ return hash (self ._name )
112
+
108
113
@classmethod
109
114
def _config_parser (cls ,repo ,parent_commit ,read_only ):
110
115
""":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):
159
164
:param skip_init: if True, the new repository will not be cloned to its location.
160
165
:return: The newly created submodule instance"""
161
166
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
+
162
218
def set_parent_commit (self ,commit ,check = True ):
163
219
"""Set this instance to use the given commit whose tree is supposed to
164
220
contain the .gitmodules blob.
@@ -167,7 +223,8 @@ def set_parent_commit(self, commit, check=True):
167
223
validity of the submodule.
168
224
:raise ValueError: if the commit's tree didn't contain the .gitmodules blob.
169
225
:raise ValueError: if the parent commit didn't store this submodule under the
170
- current path"""
226
+ current path
227
+ :return: self"""
171
228
pcommit = self .repo .commit (commit )
172
229
pctree = pcommit .tree
173
230
if self .k_modules_file not in pctree :
@@ -196,6 +253,7 @@ def set_parent_commit(self, commit, check=True):
196
253
pass
197
254
# END try attr deletion
198
255
# END for each name to delete
256
+ return self
199
257
200
258
def config_writer (self ):
201
259
""":return: a config writer instance allowing you to read and write the data