Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita58a60a

Browse files
committed
tree: now behaves like a list with string indexing functionality - using a dict as cache is a problem as the tree is ordered, added blobs, trees and traverse method
repo: remove blob function as blobs are created directly or iterated - primitve types should not clutter the repo interface
1 parentff3d142 commita58a60a

File tree

6 files changed

+192
-74
lines changed

6 files changed

+192
-74
lines changed

‎CHANGES

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ Blob
4747
Tree
4848
----
4949
* former 'name' member renamed to path as it suits the actual data better
50-
50+
* added traverse method allowing to recursively traverse tree items
51+
* deleted blob method
52+
* added blobs and trees properties allowing to query the respective items in the
53+
tree
54+
* now mimics behaviour of a read-only list instead of a dict to maintain order.
5155

5256
0.1.6
5357
=====

‎lib/git/objects/tree.py

Lines changed: 136 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,57 @@
99
importbase
1010

1111
classTree(base.IndexObject):
12+
"""
13+
Tress represent a ordered list of Blobs and other Trees. Hence it can be
14+
accessed like a list.
15+
16+
Tree's will cache their contents after first retrieval to improve efficiency.
17+
18+
``Tree as a list``::
19+
20+
Access a specific blob using the
21+
tree['filename'] notation.
22+
23+
You may as well access by index
24+
blob = tree[0]
25+
26+
27+
"""
1228

1329
type="tree"
14-
__slots__="_contents"
30+
__slots__="_cache"
1531

1632
def__init__(self,repo,id,mode=None,path=None):
1733
super(Tree,self).__init__(repo,id,mode,path)
1834

1935
def_set_cache_(self,attr):
20-
ifattr=="_contents":
21-
# Read the tree contents.
22-
self._contents= {}
23-
forlineinself.repo.git.ls_tree(self.id).splitlines():
24-
obj=self.content__from_string(self.repo,line)
25-
ifobjisnotNone:
26-
self._contents[obj.path]=obj
36+
ifattr=="_cache":
37+
# Set the data when we need it
38+
self._cache=self._get_tree_cache(self.repo,self.id)
2739
else:
2840
super(Tree,self)._set_cache_(attr)
2941

30-
@staticmethod
31-
defcontent__from_string(repo,text):
42+
@classmethod
43+
def_get_tree_cache(cls,repo,treeish):
44+
"""
45+
Return
46+
list(object_instance, ...)
47+
48+
``treeish``
49+
sha or ref identifying a tree
50+
"""
51+
out=list()
52+
forlineinrepo.git.ls_tree(treeish).splitlines():
53+
obj=cls.content_from_string(repo,line)
54+
ifobjisnotNone:
55+
out.append(obj)
56+
# END if object was handled
57+
# END for each line from ls-tree
58+
returnout
59+
60+
61+
@classmethod
62+
defcontent_from_string(cls,repo,text):
3263
"""
3364
Parse a content item and create the appropriate object
3465
@@ -40,6 +71,8 @@ def content__from_string(repo, text):
4071
4172
Returns
4273
``git.Blob`` or ``git.Tree``
74+
75+
NOTE: Currently sub-modules are ignored !
4376
"""
4477
try:
4578
mode,typ,id,path=text.expandtabs(1).split(" ",3)
@@ -51,6 +84,7 @@ def content__from_string(repo, text):
5184
eliftyp=="blob":
5285
returnblob.Blob(repo,id,mode,path)
5386
eliftyp=="commit":
87+
# TODO: Return a submodule
5488
returnNone
5589
else:
5690
raise(TypeError,"Invalid type: %s"%typ)
@@ -67,36 +101,104 @@ def __div__(self, file):
67101
<git.Blob "8b1e02c0fb554eed2ce2ef737a68bb369d7527df">
68102
69103
Returns
70-
``git.Blob`` or ``git.Tree`` or ``None`` if not found
104+
``git.Blob`` or ``git.Tree``
105+
106+
Raise
107+
KeyError if given file or tree does not exist in tree
71108
"""
72-
returnself.get(file)
109+
returnself[file]
73110

74111

75112
def__repr__(self):
76113
return'<git.Tree "%s">'%self.id
114+
115+
@classmethod
116+
def_iter_recursive(cls,repo,tree,cur_depth,max_depth,predicate ):
117+
118+
forobjintree:
119+
# adjust path to be complete
120+
obj.path=os.path.join(tree.path,obj.path)
121+
ifnotpredicate(obj):
122+
continue
123+
yieldobj
124+
ifobj.type=="tree"and (max_depth<0orcur_depth+1<=max_depth ):
125+
forrecursive_objincls._iter_recursive(repo,obj,cur_depth+1,max_depth,predicate ):
126+
yieldrecursive_obj
127+
# END for each recursive object
128+
# END if we may enter recursion
129+
# END for each object
130+
131+
deftraverse(self,max_depth=-1,predicate=lambdai:True):
132+
"""
133+
Returns
134+
Iterator to traverse the tree recursively up to the given level.
135+
The iterator returns Blob and Tree objects
136+
137+
``max_depth``
138+
139+
if -1, the whole tree will be traversed
140+
if 0, only the first level will be traversed which is the same as
141+
the default non-recursive iterator
142+
143+
``predicate``
144+
145+
If predicate(item) returns True, item will be returned by iterator
146+
"""
147+
returnself._iter_recursive(self.repo,self,0,max_depth,predicate )
148+
149+
@property
150+
deftrees(self):
151+
"""
152+
Returns
153+
list(Tree, ...) list of trees directly below this tree
154+
"""
155+
return [iforiinselfifi.type=="tree" ]
156+
157+
@property
158+
defblobs(self):
159+
"""
160+
Returns
161+
list(Blob, ...) list of blobs directly below this tree
162+
"""
163+
return [iforiinselfifi.type=="blob" ]
77164

78-
# Implement the basics of the dict protocol:
79-
# directories/trees can be seen as object dicts.
80-
def__getitem__(self,key):
81-
returnself._contents[key]
82165

166+
# List protocol
167+
def__getslice__(self,i,j):
168+
returnself._cache[i:j]
169+
83170
def__iter__(self):
84-
returniter(self._contents)
85-
171+
returniter(self._cache)
172+
86173
def__len__(self):
87-
returnlen(self._contents)
88-
89-
def__contains__(self,key):
90-
returnkeyinself._contents
91-
92-
defget(self,key):
93-
returnself._contents.get(key)
94-
95-
defitems(self):
96-
returnself._contents.items()
97-
98-
defkeys(self):
99-
returnself._contents.keys()
100-
101-
defvalues(self):
102-
returnself._contents.values()
174+
returnlen(self._cache)
175+
176+
def__getitem__(self,item):
177+
ifisinstance(item,int):
178+
returnself._cache[item]
179+
180+
ifisinstance(item,basestring):
181+
# compatability
182+
forobjinself._cache:
183+
ifobj.path==item:
184+
returnobj
185+
# END for each obj
186+
raiseKeyError("Blob or Tree named %s not found"%item )
187+
# END index is basestring
188+
189+
raiseTypeError("Invalid index type: %r"%item )
190+
191+
192+
def__contains__(self,item):
193+
ifisinstance(item,base.IndexObject):
194+
returniteminself._cache
195+
196+
# compatability
197+
forobjinself._cache:
198+
ifitem==obj.path:
199+
returnTrue
200+
# END for each item
201+
returnFalse
202+
203+
def__reversed__(self):
204+
returnreversed(self._cache)

‎lib/git/repo.py

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -342,19 +342,10 @@ def tree(self, treeish=None):
342342

343343
# we should also check whether the ref has a valid commit ... but lets n
344344
# not be over-critical
345-
returnTree(self,treeish)
345+
# the root has an empty relative path and the default mode
346+
root=Tree(self,treeish,0,'')
347+
returnroot
346348

347-
defblob(self,id):
348-
"""
349-
The Blob object for the given id
350-
351-
``id``
352-
is the SHA1 id of the blob
353-
354-
Returns
355-
``git.Blob``
356-
"""
357-
returnBlob(self,id=id)
358349

359350
deflog(self,commit='master',path=None,**kwargs):
360351
"""

‎test/git/test_repo.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,16 @@ def test_tree(self, git):
9393

9494
tree=self.repo.tree(Head(self.repo,'master'))
9595

96-
assert_equal(4,len([cforcintree.values()ifisinstance(c,Blob)]))
97-
assert_equal(3,len([cforcintree.values()ifisinstance(c,Tree)]))
96+
assert_equal(4,len([cforcintreeifisinstance(c,Blob)]))
97+
assert_equal(3,len([cforcintreeifisinstance(c,Tree)]))
9898

9999
assert_true(git.called)
100100

101101
@patch_object(Git,'_call_process')
102102
deftest_blob(self,git):
103103
git.return_value=fixture('cat_file_blob')
104104

105-
blob=self.repo.blob("abc")
105+
blob=Blob(self.repo,"abc")
106106
assert_equal("Hello world",blob.data)
107107

108108
assert_true(git.called)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp