1313import objects
1414import tempfile
1515import os
16+ import stat
17+ from git .objects import Blob
1618
1719class IndexEntry (tuple ):
1820 """
@@ -114,19 +116,24 @@ class Index(object):
114116 Implements an Index that can be manipulated using a native implementation in
115117 order to save git command function calls wherever possible.
116118
117- It provides custom merging facilities and to create custom commits.
119+ It provides custom merging facilities allowing to merge without actually changing
120+ your index or your working tree. This way you can perform own test-merges based
121+ on the index only without having to deal with the working copy. This is useful
122+ in case of partial working trees.
118123
119124 ``Entries``
120125 The index contains an entries dict whose keys are tuples of type IndexEntry
121126 to facilitate access.
122127 """
123- __slots__ = ( "version" , "entries" , "_extension_data" )
128+ __slots__ = ( "repo" , " version" , "entries" , "_extension_data" )
124129 _VERSION = 2 # latest version we support
130+ S_IFGITLINK = 0160000
125131
126- def __init__ (self , stream = None ):
132+ def __init__ (self , repo , stream = None ):
127133 """
128134 Initialize this Index instance, optionally from the given ``stream``
129135 """
136+ self .repo = repo
130137 self .entries = dict ()
131138 self .version = self ._VERSION
132139 self ._extension_data = ''
@@ -178,11 +185,14 @@ def _read_from_stream(self, stream):
178185 self ._extension_data = stream .read (~ 0 )
179186
180187 @classmethod
181- def from_file (cls , file_path ):
188+ def from_file (cls , repo , file_path ):
182189 """
183190 Returns
184191 Index instance as recreated from the given stream.
185-
192+
193+ ``repo``
194+ Repository the index is related to
195+
186196 ``file_pa ``
187197 File path pointing to git index file
188198
@@ -200,7 +210,7 @@ def from_file(cls, file_path):
200210 # END memory mapping
201211
202212 try :
203- return cls (stream )
213+ return cls (repo , stream )
204214 finally :
205215 fp .close ()
206216
@@ -331,7 +341,7 @@ def from_tree(cls, repo, *treeish, **kwargs):
331341 try :
332342 os .rename (cur_index , moved_index )
333343 repo .git .read_tree (* arg_list , ** kwargs )
334- index = cls .from_file (tmp_index )
344+ index = cls .from_file (repo , tmp_index )
335345 finally :
336346 # put back the original index first !
337347 if os .path .exists (moved_index ):
@@ -341,7 +351,41 @@ def from_tree(cls, repo, *treeish, **kwargs):
341351 # END index merge handling
342352
343353 return index
344-
354+
355+ @classmethod
356+ def _index_mode_to_tree_index_mode (cls , index_mode ):
357+ """Cleanup a index_mode value.
358+ This will return a index_mode that can be stored in a tree object.
359+ ``index_mode``
360+ Index_mode to clean up.
361+ """
362+ if stat .S_ISLNK (index_mode ):
363+ return stat .S_IFLNK
364+ elif stat .S_ISDIR (index_mode ):
365+ return stat .S_IFDIR
366+ elif stat .S_IFMT (index_mode ) == cls .S_IFGITLINK :
367+ return cls .S_IFGITLINK
368+ ret = stat .S_IFREG | 0644
369+ ret |= (index_mode & 0111 )
370+ return ret
371+
372+ def iter_blobs (self , predicate = lambda t : True ):
373+ """
374+ Returns
375+ Iterator yielding tuples of Blob objects and stages, tuple(stage, Blob)
376+
377+ ``predicate``
378+ Function(t) returning True if tuple(stage, Blob) should be yielded by the
379+ iterator
380+ """
381+ for entry in self .entries .itervalues ():
382+ mode = self ._index_mode_to_tree_index_mode (entry .mode )
383+ blob = Blob (self .repo , entry .sha , mode , entry .path )
384+ output = (entry .stage , blob )
385+ if predicate (output ):
386+ yield output
387+ # END for each entry
388+
345389 def write_tree (self , stream ):
346390 """
347391 Writes the
0 commit comments