Skip to content

Commit d86e77e

Browse files
committed
tree: implemented recursive paths in __div__ and __getitem__ method, allowing the keys to contain slashes; adjusted test to check for this
1 parent 1b3fedd commit d86e77e

File tree

3 files changed

+33
-7
lines changed

3 files changed

+33
-7
lines changed

doc/tutorial.rst

+2
Original file line numberDiff line numberDiff line change
@@ -239,13 +239,15 @@ query entries by name.
239239
'dir/file'
240240
>>> blob.abspath
241241
'/Users/mtrier/Development/git-python/dir/file'
242+
>>>tree['dir/file'].sha == blob.sha
242243

243244
There is a convenience method that allows you to get a named sub-object
244245
from a tree with a syntax similar to how paths are written in an unix
245246
system.
246247

247248
>>> tree/"lib"
248249
<git.Tree "c1c7214dde86f76bc3e18806ac1f47c38b2b7a30">
250+
>>> tree/"dir/file" == blob.sha
249251

250252
You can also get a tree directly from the repository if you know its name.
251253

lib/git/objects/tree.py

+27-6
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,32 @@ def __div__(self, file):
158158
Raise
159159
KeyError if given file or tree does not exist in tree
160160
"""
161-
return self[file]
161+
msg = "Blob or Tree named %r not found"
162+
if '/' in file:
163+
tree = self
164+
item = self
165+
tokens = file.split('/')
166+
for i,token in enumerate(tokens):
167+
item = tree[token]
168+
if item.type == 'tree':
169+
tree = item
170+
else:
171+
# safety assertion - blobs are at the end of the path
172+
if i != len(tokens)-1:
173+
raise KeyError(msg % file)
174+
return item
175+
# END handle item type
176+
# END for each token of split path
177+
if item == self:
178+
raise KeyError(msg % file)
179+
return item
180+
else:
181+
for obj in self._cache:
182+
if obj.name == file:
183+
return obj
184+
# END for each obj
185+
raise KeyError( msg % file )
186+
# END handle long paths
162187

163188

164189
def __repr__(self):
@@ -205,11 +230,7 @@ def __getitem__(self,item):
205230

206231
if isinstance(item, basestring):
207232
# compatability
208-
for obj in self._cache:
209-
if obj.name == item:
210-
return obj
211-
# END for each obj
212-
raise KeyError( "Blob or Tree named %s not found" % item )
233+
return self.__div__(item)
213234
# END index is basestring
214235

215236
raise TypeError( "Invalid index type: %r" % item )

test/git/test_tree.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,10 @@ def test_traverse(self):
5454
assert os.path.isabs(item.abspath)
5555
if '/' in item.path:
5656
found_slash = True
57-
break
57+
# END check for slash
58+
59+
# slashes in paths are supported as well
60+
assert root[item.path] == item == root/item.path
5861
# END for each item
5962
assert found_slash
6063

0 commit comments

Comments
 (0)