summaryrefslogtreecommitdiff
path: root/lib/git/tree.py
diff options
context:
space:
mode:
authorD. Dotsenko <dotsa@hotmail.com>2010-10-20 22:41:52 -0700
committerDaniel Dotsenko <dotsa@hotmail.com>2010-10-20 22:41:52 -0700
commitcfd2121eda5fadd18fba6819f90efb8868fad14a (patch)
treeda2d2b16a0a68145a5ada2d514540b20e6f79665 /lib/git/tree.py
parent7bfca5efce8988e6070e7284bd409d1a731a3fbc (diff)
downloadgitpython-cfd2121eda5fadd18fba6819f90efb8868fad14a.tar.gz
Added submodule type and handling through Tree listing.
Diffstat (limited to 'lib/git/tree.py')
-rw-r--r--lib/git/tree.py47
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)