diff options
author | D. Dotsenko <dotsa@hotmail.com> | 2010-10-20 22:41:52 -0700 |
---|---|---|
committer | Daniel Dotsenko <dotsa@hotmail.com> | 2010-10-20 22:41:52 -0700 |
commit | cfd2121eda5fadd18fba6819f90efb8868fad14a (patch) | |
tree | da2d2b16a0a68145a5ada2d514540b20e6f79665 /lib/git/tree.py | |
parent | 7bfca5efce8988e6070e7284bd409d1a731a3fbc (diff) | |
download | gitpython-cfd2121eda5fadd18fba6819f90efb8868fad14a.tar.gz |
Added submodule type and handling through Tree listing.
Diffstat (limited to 'lib/git/tree.py')
-rw-r--r-- | lib/git/tree.py | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/lib/git/tree.py b/lib/git/tree.py index 02266dce..45f5fdcb 100644 --- a/lib/git/tree.py +++ b/lib/git/tree.py @@ -7,14 +7,47 @@ import os from lazy import LazyMixin import blob +import submodule class Tree(LazyMixin): - def __init__(self, repo, id, mode=None, name=None): + def __init__(self, repo, id, mode=None, name=None, commit_context = None, path = ''): LazyMixin.__init__(self) self.repo = repo self.id = id self.mode = mode self.name = name + # commit_context (A string with ID of the commit) is a "crutch" that + # allows us to look up details for submodules, should we find any in + # this particular tree. + # Trees don't have a reference to parent (commit, other tree). + # They can have infinite amounts of parents. + # However, we need to know what commit got us to this particular + # tree if we want to know the URI of the submodule. + # The commit ID of the repo pointed out by submodule is here, in the tree. + # However, the only way to know what URI that submodule refers to is + # to read .gitmodules file that's in the top-most tree of SOME commit. + # Each commit can have a different version of .gitmodule, but through + # tree chain lead to the same Tree instance where the submodule is rooted. + # + # There is a short-cut. If submodule is placed in top-most Tree in a + # commit (i.e. submodule's path value is "mysubmodule") the .gitmodules + # file will be in the same exact tree. YEY! we just read that and know + # the submodule's URI. Shortcut is gone when submodule is nested in the + # commit like so: "commonfolder/otherfolder/mysubmodule" In this case, + # commit's root tree will have "Tree 'commonfolder'" which will have + # "Tree "otherfolder", which will have "Submodule 'mysubmodule'" + # By the time we get to "Tree 'otherfolder'" we don't know where to + # look for ".gitmodules". This is what commit_context is for. + # The only way you get a value here if you either set it by hand, or + # traverse the Tree chain that started with CommitInstance.tree, which + # populates the context upon Tree instantiation. + self.commit_context = commit_context + # path is the friend commit_context. since trees don't have links to + # parents, we have no clue what the "full local path" of a child + # submodule would be. Submodules are listed as "name" in trees and + # as "folder/folder/name" in .gitmodules. path helps us keep up with the + # the folder changes. + self.path = path self._contents = None def __bake__(self): @@ -26,12 +59,12 @@ class Tree(LazyMixin): # Read the tree contents. self._contents = {} for line in self.repo.git.ls_tree(self.id).splitlines(): - obj = self.content_from_string(self.repo, line) + obj = self.content_from_string(self.repo, line, commit_context = self.commit_context, path = self.path) if obj is not None: self._contents[obj.name] = obj @staticmethod - def content_from_string(repo, text): + def content_from_string(repo, text, commit_context = None, path=''): """ Parse a content item and create the appropriate object @@ -50,11 +83,13 @@ class Tree(LazyMixin): return None if typ == "tree": - return Tree(repo, id=id, mode=mode, name=name) + return Tree(repo, id=id, mode=mode, name=name, + commit_context = commit_context, path='/'.join([path,name])) elif typ == "blob": return blob.Blob(repo, id=id, mode=mode, name=name) - elif typ == "commit": - return None + elif typ == "commit" and mode == '160000': + return submodule.Submodule(repo, id=id, name=name, + commit_context = commit_context, path='/'.join([path,name])) else: raise(TypeError, "Invalid type: %s" % typ) |