1414import tempfile
1515import os
1616import stat
17- from git .objects import Blob , Tree
17+ import git .diff as diff
18+
19+ from git .objects import Blob , Tree , Object
1820from git .utils import SHA1Writer , LazyMixin , ConcurrentWriteOperation
19- from git . diff import Diffable
21+
2022
2123class _TemporaryFileSwap (object ):
2224 """
@@ -140,7 +142,7 @@ def from_blob(cls, blob):
140142 return IndexEntry ((time , time , 0 , 0 , blob .mode , 0 , 0 , blob .size , blob .id , 0 , blob .path ))
141143
142144
143- class Index (LazyMixin ):
145+ class Index (LazyMixin , diff . Diffable ):
144146 """
145147 Implements an Index that can be manipulated using a native implementation in
146148 order to save git command function calls wherever possible.
@@ -154,7 +156,7 @@ class Index(LazyMixin):
154156 The index contains an entries dict whose keys are tuples of type IndexEntry
155157 to facilitate access.
156158 """
157- __slots__ = ( "repo" , "version" , "entries" , "_extension_data" )
159+ __slots__ = ( "repo" , "version" , "entries" , "_extension_data" , "_is_default_index" )
158160 _VERSION = 2 # latest version we support
159161 S_IFGITLINK = 0160000
160162
@@ -168,10 +170,13 @@ def __init__(self, repo, stream = None):
168170 self .repo = repo
169171 self .version = self ._VERSION
170172 self ._extension_data = ''
173+ self ._is_default_index = True
171174 if stream is not None :
175+ self ._is_default_index = False
172176 self ._read_from_stream (stream )
173177 # END read from stream immediatly
174178
179+
175180 def _set_cache_ (self , attr ):
176181 if attr == "entries" :
177182 # read the current index
@@ -187,6 +192,18 @@ def _set_cache_(self, attr):
187192 def _index_path (self ):
188193 return os .path .join (self .repo .path , "index" )
189194
195+
196+ @property
197+ def path (self ):
198+ """
199+ Returns
200+ Path to the index file we are representing or None if we are
201+ a loose index that was read from a stream.
202+ """
203+ if self ._is_default_index :
204+ return self ._index_path ()
205+ return None
206+
190207 @classmethod
191208 def _read_entry (cls , stream ):
192209 """Return: One entry of the given stream"""
@@ -535,4 +552,51 @@ def write_tree(self):
535552 # END write tree handling
536553 return Tree (self .repo , tree_sha , 0 , '' )
537554
555+
556+ def _process_diff_args (self , args ):
557+ try :
558+ args .pop (args .index (self ))
559+ except IndexError :
560+ pass
561+ # END remove self
562+ return args
563+
564+ def diff (self , other = diff .Diffable .Index , paths = None , create_patch = False , ** kwargs ):
565+ """
566+ Diff this index against the working copy or a Tree or Commit object
567+
568+ For a documentation of the parameters and return values, see
569+ Diffable.diff
570+
571+ Note
572+ Will only work with indices that represent the default git index as
573+ they have not been initialized with a stream.
574+ """
575+ if not self ._is_default_index :
576+ raise AssertionError ( "Cannot diff custom indices as they do not represent the default git index" )
577+
578+ # index against index is always empty
579+ if other is self .Index :
580+ return diff .DiffIndex ()
581+
582+ # index against anything but None is a reverse diff with the respective
583+ # item. Handle existing -R flags properly. Transform strings to the object
584+ # so that we can call diff on it
585+ if isinstance (other , basestring ):
586+ other = Object .new (self .repo , other )
587+ # END object conversion
588+
589+ if isinstance (other , Object ):
590+ # invert the existing R flag
591+ cur_val = kwargs .get ('R' , False )
592+ kwargs ['R' ] = not cur_val
593+ return other .diff (self .Index , paths , create_patch , ** kwargs )
594+ # END diff against other item handlin
595+
596+ # if other is not None here, something is wrong
597+ if other is not None :
598+ raise ValueError ( "other must be None, Diffable.Index, a Tree or Commit, was %r" % other )
599+
600+ # diff against working copy - can be handled by superclass natively
601+ return super (Index , self ).diff (other , paths , create_patch , ** kwargs )
538602
0 commit comments